Advanced shipment processing

Sometimes it is necessary to use the full functionality of Carrier Connect. For this requirement you can use the class /AEB/CL_PA_PB_CARRIER_BF. This class allows to directly address the Carrier Connect functions completely. For a detailed documentation of the API and its fields check this link: https://transport-freight-management.docs.developers.aeb.com/docs/getting-started-with-carrier-connect.

To support you building up the required data structures, there are some complementary features :

TaskClass
Determination of the org unitFreight order: /AE1/CL_PA_PB_FRO_OU_RULE_BC
Delivery: /AEB/CL_PA_PB_DLV_OU_RULE_BC
Shipment: /AEB/CL_PA_PB_SHP_OU_RULE_BC
Determination of connection parms/AEB/CL_PA_PB_ENGN_PRM_BC
Collecting data for a shipment
This function provides the basic data based on the settings in the configuration. It runs also through the "AFTER_STD_FILLING"-method of the according BAdI for each object.
Freight order: /AE1/CL_PA_PB_FRO_SHP_COLL_BC
Delivery: /AEB/CL_PA_PB_DLV_SHP_COLL_BC
Shipment: /AEB/CL_PA_PB_SHP_SHP_COLL_BC
Determination of the shipment referenceFreight order: /AE1/CL_PA_PB_FRO_SHP_REF_BC
Delivery: /AEB/CL_PA_PB_DLV_SHP_REF_BC
Shipment: /AEB/CL_PA_PB_SHP_SHP_REF_BC
Determination of the workstation ID/AEB/CL_PA_PB_WSTA_ID_BC

In the following program you will see a reference implementation that combines those functions. The task is to implement the same as in the "First Shipment - part, but now using the functions above. First step is to determine an organizational unit.

REPORT zaeb_create_first_shipment.

PARAMETERS: vbeln TYPE likp-vbeln.

DATA:
  likp             TYPE likp,
  lipss            TYPE STANDARD TABLE OF lips,
  vbpas            TYPE STANDARD TABLE OF vbpa,
  vekps            TYPE STANDARD TABLE OF vekp,
  org_unit_rule_bc TYPE REF TO /aeb/cl_pa_pb_dlv_ou_rule_bc,
  org_unit         TYPE string.

SELECT SINGLE * FROM likp INTO likp WHERE vbeln = vbeln.
SELECT * FROM lips INTO TABLE lipss WHERE vbeln = vbeln.
SELECT * FROM vbpa INTO TABLE vbpas WHERE vbeln = vbeln.
SELECT * FROM vekp INTO TABLE vekps WHERE vpobjkey = vbeln.


org_unit_rule_bc = /aeb/cl_pa_pb_dlv_ou_rule_bc=>new_for(
		im_likp = likp 
    im_lipss = lipss ).
    
org_unit = org_unit_rule_bc->get_org_unit( ).

WRITE: 'OrgUnit: ' , org_unit.
WRITE /.

Running the report will show the organizational unit. The next step is to determine the connection parameter linked to this organizational unit:

REPORT zaeb_create_first_shipment.

PARAMETERS: vbeln TYPE likp-vbeln.

DATA:
  likp             TYPE likp,
  lipss            TYPE STANDARD TABLE OF lips,
  vbpas            TYPE STANDARD TABLE OF vbpa,
  vekps            TYPE STANDARD TABLE OF vekp,
  org_unit_rule_bc TYPE REF TO /aeb/cl_pa_pb_dlv_ou_rule_bc,
  org_unit         TYPE /aeb/01_char20,
  engn_prm_bc      TYPE REF TO /aeb/cl_pa_pb_engn_prm_bc,
  engn_prm_mo      TYPE REF TO /aeb/if_pa_pb_engn_prm_mo.

SELECT SINGLE * FROM likp INTO likp WHERE vbeln = vbeln.
SELECT * FROM lips INTO TABLE lipss WHERE vbeln = vbeln.
SELECT * FROM vbpa INTO TABLE vbpas WHERE vbeln = vbeln.
SELECT * FROM vekp INTO TABLE vekps WHERE vpobjkey = vbeln AND xyz -> select the right HUs here using further criteria...


org_unit_rule_bc = /aeb/cl_pa_pb_dlv_ou_rule_bc=>new_for( im_likp = likp im_lipss = lipss ).
org_unit = org_unit_rule_bc->get_org_unit( ).

WRITE: 'OrgUnit: ' , org_unit.
WRITE /.

engn_prm_bc = /aeb/cl_pa_pb_engn_prm_bc=>get_instance( ).
engn_prm_mo = engn_prm_bc->get_engn_prm_do_for( org_unit ).

WRITE: 'Destination: ' , engn_prm_mo->get_destination( ).
WRITE: 'Engine client: ' , engn_prm_mo->get_engine_client( ).s

If you run the report again the destination and client for Carrier Connect will be shown. Now we need the data for the shipment.

REPORT zaeb_create_first_shipment.

PARAMETERS: vbeln TYPE likp-vbeln.

DATA:
  likp             TYPE likp,
  lipss            TYPE STANDARD TABLE OF lips,
  vbpas            TYPE STANDARD TABLE OF vbpa,
  vekps            TYPE STANDARD TABLE OF vekp,
  org_unit_rule_bc TYPE REF TO /aeb/cl_pa_pb_dlv_ou_rule_bc,
  org_unit         TYPE /aeb/01_char20,
  engn_prm_bc      TYPE REF TO /aeb/cl_pa_pb_engn_prm_bc,
  engn_prm_mo      TYPE REF TO /aeb/if_pa_pb_engn_prm_mo,
  collector_bc     TYPE REF TO /aeb/cl_pa_pb_dlv_shp_coll_bc,
  shipment         TYPE /aeb/pa_pb_dl_shp_req_do.

SELECT SINGLE * FROM likp INTO likp WHERE vbeln = vbeln.
SELECT * FROM lips INTO TABLE lipss WHERE vbeln = vbeln.
SELECT * FROM vbpa INTO TABLE vbpas WHERE vbeln = vbeln.
SELECT * FROM vekp INTO TABLE vekps WHERE vpobjkey = vbeln AND xyz -> select the right HUs here using further criteria...


org_unit_rule_bc = /aeb/cl_pa_pb_dlv_ou_rule_bc=>new_for( im_likp = likp im_lipss = lipss ).
org_unit = org_unit_rule_bc->get_org_unit( ).

WRITE: 'OrgUnit: ' , org_unit.
WRITE /.

engn_prm_bc = /aeb/cl_pa_pb_engn_prm_bc=>get_instance( ).
engn_prm_mo = engn_prm_bc->get_engn_prm_do_for( org_unit ).

WRITE: 'Destination: ' , engn_prm_mo->get_destination( ).
WRITE /.
WRITE: 'Engine client: ' , engn_prm_mo->get_engine_client( ).
WRITE /.

collector_bc = /aeb/cl_pa_pb_dlv_shp_coll_bc=>new_for( im_likp = likp
                                                       im_lipss = lipss
                                                       im_vbpas = vbpas
                                                       im_vekps = vekps ).

shipment = collector_bc->create_shipment( org_unit ).

write shipment-referencenumber1.
WRITE /.

With this logic you have collected data of the delivery, e.g. the reference number. What you need as well for printing the label is a workstation ID. Just add the following code lines to the program.

DATA: workstation_id TYPE string.
workstation_id = /aeb/cl_pa_pb_wsta_id_bc=>new( )->get_workstation_id( ).
write: workstation_id.
write /.

Now you have everything to create your first shipment. You have to combine the data you collected with the class /AEB/CL_PA_PB_CARRIER_BF. Add the following code to your report.

DATA:
  request                   TYPE REF TO /aeb/cl_pa_pb_cr_shp_req_do,
  result_language_iso_codes TYPE /aeb/01_char2s,
  result                    TYPE REF TO /aeb/cl_pa_pb_cr_shp_res_do,
  exc                       TYPE REF TO /aeb/cx_01_pb_bf_inv_sc,
  msg                       TYPE REF TO /aeb/cl_01_pb_res_msg_do,
  text                      TYPE REF TO /aeb/cl_01_pb_til_do,
  creation_parms            TYPE REF TO /aeb/cl_pa_pb_cr_prm_do,
  process_parms             TYPE REF TO /aeb/cl_pa_pb_shp_prp_do,
  output_mode               TYPE REF TO /aeb/cl_pa_pb_doc_outm_do,
  prepare_scope             TYPE REF TO /aeb/cl_pa_pb_doc_scope_do,
  process_mode              TYPE /aeb/pa_pb_dl_pmode_do,
  output_scope              TYPE REF TO /aeb/cl_pa_pb_doc_scope_do,
  carrier_bf                TYPE REF TO /aeb/cl_pa_pb_carrier_bf.

CREATE OBJECT request.
request->set_client_identcode( engn_prm_mo->get_engine_client( ) ).
request->set_client_system_id( 'SID_400' ).
request->set_shipment( shipment ).
request->set_username( sy-uname ).
APPEND 'DE' TO result_language_iso_codes.
APPEND 'EN' TO result_language_iso_codes.
request->set_result_language_iso_codes( result_language_iso_codes ).

CREATE OBJECT creation_parms.
creation_parms->set_creation_mode( 'ALWAYS' ).
request->set_creation_parms( creation_parms ).

CREATE OBJECT process_parms.
process_parms->set_do_completion( 'X' ).
process_parms->set_workstation_id( workstation_id ).

CREATE OBJECT output_mode.
output_mode->set_mode( 'NONE' ).
process_parms->set_document_output_mode( output_mode ).

process_mode-mode = 'EXTENDED'.
process_parms->set_process_mode( process_mode ).

CREATE OBJECT prepare_scope.
prepare_scope->set_scope( 'ALL' ).
process_parms->set_document_prepare_scope( prepare_scope ).

CREATE OBJECT output_scope.
output_scope->set_scope( 'ALL' ).
process_parms->set_document_output_scope( output_scope ).

request->set_process_parms(  process_parms ).

TRY.
    carrier_bf = /aeb/cl_pa_pb_carrier_bf=>new_for( im_engn_prm = engn_prm_mo
                                                    im_org_unit = org_unit ).

    result = carrier_bf->create_shipment( request ).
    IF result->get_has_errors( ) = 'X'.
      LOOP AT result->get_messages( ) INTO msg.
        LOOP AT msg->get_message_texts( ) INTO text.
          WRITE text->get_text( ).
          WRITE /.
        ENDLOOP.
      ENDLOOP.
    ELSE.
      WRITE result->get_shipment_number( ).
    ENDIF.
  CATCH /aeb/cx_01_pb_bf_inv_sc INTO exc.
    WRITE exc->/aeb/if_01_cx_message~get_msg_as_str( ).
ENDTRY.

Run the report. Now you should see the shipment number on your screen.

The communication is synchronous, so you'll receive certain data in the response of the call (result), which you can use for further processing. But you can also trigger another call to read the data of the shipment:

REPORT zaeb_get_first_shipment.

PARAMETERS: vbeln TYPE likp-vbeln.

DATA:
  likp             TYPE likp,
  lipss            TYPE STANDARD TABLE OF lips,
  org_unit_rule_bc TYPE REF TO /aeb/cl_pa_pb_dlv_ou_rule_bc,
  org_unit         TYPE /aeb/01_char20,
  engn_prm_bc      TYPE REF TO /aeb/cl_pa_pb_engn_prm_bc,
  engn_prm_mo      TYPE REF TO /aeb/if_pa_pb_engn_prm_mo,
  shp_ref_bc       TYPE REF TO /aeb/cl_pa_pb_dlv_shp_ref_bc,
  shipment_ref     TYPE /aeb/pa_pb_dl_shp_ref_do,
  carrier_bf       TYPE REF TO /aeb/cl_pa_pb_carrier_bf.

SELECT SINGLE * FROM likp INTO likp WHERE vbeln = vbeln.
SELECT * FROM lips INTO TABLE lipss WHERE vbeln = vbeln.

org_unit_rule_bc = /aeb/cl_pa_pb_dlv_ou_rule_bc=>new_for( im_likp = likp im_lipss = lipss ).
org_unit = org_unit_rule_bc->get_org_unit( ).

engn_prm_bc = /aeb/cl_pa_pb_engn_prm_bc=>get_instance( ).
engn_prm_mo = engn_prm_bc->get_engn_prm_do_for( org_unit ).

shp_ref_bc = /aeb/cl_pa_pb_dlv_shp_ref_bc=>new_for( likp ).
shipment_ref = shp_ref_bc->get_shp_ref_do( ).

DATA:
  request                   TYPE REF TO /aeb/cl_pa_pb_get_shp_req_do,
  result_language_iso_codes TYPE /aeb/01_char2s,
  result                    TYPE REF TO /aeb/cl_pa_pb_get_shp_res_do,
  exc                       TYPE REF TO /aeb/cx_01_pb_bf_inv_sc,
  msg                       TYPE REF TO /aeb/cl_01_pb_res_msg_do,
  text                      TYPE REF TO /aeb/cl_01_pb_til_do,
  shp_refs                  TYPE /aeb/pa_pb_dl_shp_ref_dos,
  shipment                  TYPE /aeb/pa_pb_dl_shp_res_do.

CREATE OBJECT request.
request->set_client_identcode( engn_prm_mo->get_engine_client( ) ).
request->set_client_system_id( 'SID_400' ).
request->set_username( sy-uname ).
APPEND 'DE' TO result_language_iso_codes.
APPEND 'EN' TO result_language_iso_codes.
request->set_result_language_iso_codes( result_language_iso_codes ).
APPEND shipment_ref TO shp_refs.
request->set_shipment_references( shp_refs ).

TRY.
    carrier_bf = /aeb/cl_pa_pb_carrier_bf=>new_for( im_engn_prm = engn_prm_mo
                                                    im_org_unit = org_unit ).

    result = carrier_bf->get_shipments( request ).
    IF result->get_has_errors( ) = 'X'.
      LOOP AT result->get_messages( ) INTO msg.
        LOOP AT msg->get_message_texts( ) INTO text.
          WRITE text->get_text( ).
          WRITE /.
        ENDLOOP.
      ENDLOOP.
    ELSE.
      loop at result->get_shipments( ) into shipment.
        write shipment-referencenumber1.
      endloop.
    ENDIF.
  CATCH /aeb/cx_01_pb_bf_inv_sc INTO exc.
    WRITE exc->/aeb/if_01_cx_message~get_msg_as_str( ).
ENDTRY.

Run the report and the delivery number should be shown on your screen.

Now that you have created the shipment, you can go ahead and update it using the "processShipment"- method:

REPORT zaeb_process_shipment.

PARAMETERS: vbeln TYPE likp-vbeln.

DATA:
  likp                      TYPE likp,
  lipss                     TYPE STANDARD TABLE OF lips,
  org_unit_rule_bc          TYPE REF TO /aeb/cl_pa_pb_dlv_ou_rule_bc,
  org_unit                  TYPE /aeb/01_char20,
  engn_prm_bc               TYPE REF TO /aeb/cl_pa_pb_engn_prm_bc,
  engn_prm_mo               TYPE REF TO /aeb/if_pa_pb_engn_prm_mo,
  shp_ref_bc                TYPE REF TO /aeb/cl_pa_pb_dlv_shp_ref_bc,
  shipment_ref              TYPE /aeb/pa_pb_dl_shp_ref_do,
  carrier_bf                TYPE REF TO /aeb/cl_pa_pb_carrier_bf,
  request                   TYPE REF TO /aeb/cl_pa_pb_pr_shp_req_do,
  result_language_iso_codes TYPE /aeb/01_char2s,
  result                    TYPE REF TO /aeb/cl_pa_pb_pr_shp_res_do,
  exc                       TYPE REF TO /aeb/cx_01_pb_bf_inv_sc,
  msg                       TYPE REF TO /aeb/cl_01_pb_res_msg_do,
  text                      TYPE REF TO /aeb/cl_01_pb_til_do,
  process_parms             TYPE REF TO /aeb/cl_pa_pb_shp_prp_do,
  output_mode               TYPE REF TO /aeb/cl_pa_pb_doc_outm_do,
  doc_prepare_scope         TYPE REF TO /aeb/cl_pa_pb_doc_scope_do,
  output_scope              TYPE REF TO /aeb/cl_pa_pb_doc_scope_do.

SELECT SINGLE * FROM likp INTO likp WHERE vbeln = vbeln.
SELECT * FROM lips INTO TABLE lipss WHERE vbeln = vbeln.

org_unit_rule_bc = /aeb/cl_pa_pb_dlv_ou_rule_bc=>new_for( im_likp = likp im_lipss = lipss ).
org_unit = org_unit_rule_bc->get_org_unit( ).

engn_prm_bc = /aeb/cl_pa_pb_engn_prm_bc=>get_instance( ).
engn_prm_mo = engn_prm_bc->get_engn_prm_do_for( org_unit ).

shp_ref_bc = /aeb/cl_pa_pb_dlv_shp_ref_bc=>new_for( likp ).
shipment_ref = shp_ref_bc->get_shp_ref_do( ).

CREATE OBJECT request.
request->set_client_identcode( engn_prm_mo->get_engine_client( ) ).
request->set_client_system_id( 'SID_400' ).
request->set_username( sy-uname ).
APPEND 'DE' TO result_language_iso_codes.
request->set_result_language_iso_codes( result_language_iso_codes ).
request->set_shipment_reference( shipment_ref ).

CREATE OBJECT process_parms.
process_parms->set_do_completion( 'X' ).
process_parms->set_workstation_id( workstation_id ).

CREATE OBJECT output_mode.
output_mode->set_mode( 'PRINT' ).
process_parms->set_document_output_mode( output_mode ).

CREATE OBJECT doc_prepare_scope.
doc_prepare_scope->set_scope( 'REMAINING' ).
process_parms->set_document_prepare_scope( doc_prepare_scope ).

CREATE OBJECT output_scope.
output_scope->set_scope( 'REMAINING' ).
process_parms->set_document_output_scope( output_scope ).

request->set_process_parms( process_parms ).

TRY.
    carrier_bf = /aeb/cl_pa_pb_carrier_bf=>new_for( im_engn_prm = engn_prm_mo
                                                    im_org_unit = org_unit ).

    result = carrier_bf->process_shipment( request ).
    LOOP AT result->get_messages( ) INTO msg.
      LOOP AT msg->get_message_texts( ) INTO text.
        WRITE text->get_text( ).
        WRITE /.
      ENDLOOP.
    ENDLOOP.
  CATCH /aeb/cx_01_pb_bf_inv_sc INTO exc.
    WRITE exc->/aeb/if_01_cx_message~get_msg_as_str( ).
ENDTRY.

With the above report you will either see the error messages on screen or no output when the shipment was processed successfully.

Now that you know which functions you need to combine using /AEB/CL_PA_PB_CARRIER_BF you should be able to implement everything else what is possible via this API. In addition, there is a function module /AEB/PA_PB_GET_CAR_PROPS that enables you to get the master data information from Carrier Connect.

Note: The public class will not write log entries. You can use the class /AEB/CL_PA_PB_LOGGER_BC and use the response data from the call to write a log entry. You can use the result type to determine if you should write an error or a warning log entry e.g. IF result->has_error( ) = 'X'. logger->create_log_error( ). ELSEIF result->has_warning( ) ...

"Create pickup call request
DATA: lo_request         TYPE REF TO /aeb/cl_pa_pb_cr_pu_req_do,
      ls_creation_parms  TYPE /aeb/pa_pb_dl_pcp_do,
      ls_process_parms   TYPE /aeb/pa_pb_dl_ppp_do,
      lt_langs           TYPE /aeb/01_char2s,
      ls_pickup          TYPE /aeb/pa_pb_dl_prd_do,
      lt_references	     TYPE /aeb/pa_pb_dl_shp_ref_dos,
      lv_carrier         TYPE /aeb/01_char20,
      lv_vstel           TYPE vstel,
      lo_carrier_bf      TYPE REF TO /aeb/cl_pa_pb_carrier_bf,
      lo_engn_prm        TYPE REF TO /aeb/if_pa_pb_engn_prm_mo,
      lo_engn_prm_bc     TYPE REF TO /aeb/cl_pa_pb_engn_prm_bc,
      lo_zaeb_cco_helper TYPE REF TO zaeb_cco_helper,
      lv_org_unit	       TYPE /aeb/01_char20
      .

"DEFAULT VALUES!!!
"Please change to your own logic
lv_org_unit = 'AEB'.
lv_vstel = '1010'.
ls_pickup-carrieridentcode = 'UPS'.

"Determine list of LIKPs first
SELECT * FROM likp WHERE wadat = @sy-datum AND vstel = @lv_vstel INTO TABLE @DATA(lt_likps). "Change to your own logic!
LOOP AT lt_likps INTO DATA(ls_likp).
  DATA(lo_dlv_shp_ref) = /aeb/cl_pa_pb_dlv_shp_ref_bc=>new_for( im_likp = ls_likp ).
  DATA(ls_shp_ref) = lo_dlv_shp_ref->get_shp_ref_do( ).
  APPEND ls_shp_ref TO lt_references.
ENDLOOP.

IF lt_references IS INITIAL.
  RETURN.
ENDIF.

CREATE OBJECT lo_request.
lo_request->set_client_system_id( im_value = sy-sysid && '_' && sy-mandt ).
ls_creation_parms-creationmode = 'ONLY_VALID_SHIPMENTS'.
lo_request->set_creation_parms( im_value = ls_creation_parms ).
ls_process_parms-documentoutputmode-mode = 'PRINT'. "Might by different if you use the AEB print agent!
ls_process_parms-domanifest = 'X'. "Depends on your business process. This will complete your pickup.
ls_process_parms-workstationid = sy-uname.
lo_request->set_process_parms( im_value = ls_process_parms ).

APPEND 'de' TO lt_langs.
lo_request->set_result_language_iso_codes( im_value = lt_langs ).

lo_request->set_username( im_value = sy-uname ).

ls_pickup-shipments = lt_references.
ls_pickup-shippingdate = sy-datum. "Must match the shipping date of the shipping orders in Carrier Connect
ls_pickup-shippingpt-companynumber = lv_vstel.
lo_request->set_pickup( im_value = ls_pickup ).

lo_engn_prm_bc = /aeb/cl_pa_pb_engn_prm_bc=>get_instance( ).
lo_engn_prm = lo_engn_prm_bc->get_engn_prm_do_for( im_org_unit = lv_org_unit ).

lo_carrier_bf = /aeb/cl_pa_pb_carrier_bf=>new_for(
                  im_engn_prm = lo_engn_prm
                  im_org_unit = lv_org_unit
                ).

lo_request->set_client_identcode( im_value = lo_engn_prm->get_engine_client( ) ).

TRY.
    DATA(lo_pickup) = lo_carrier_bf->create_pickup( im_request = lo_request ).
  CATCH /aeb/cx_01_pb_bf_inv_sc. " Interface exception
    "Implement suitable error handling here
    RETURN.
ENDTRY.

IF lo_pickup->get_has_errors( ) = 'X'.
  "Create error message and log entry here
ELSEIF lo_pickup->get_has_warnings( ) = 'X'.
  "Create warning message and log entry
ELSE.
  "Print manifest
ENDIF.

To attach documents to a shipment in Carrier Connect, execution of a separate method is necessary:

DATA: lt_attachements TYPE /aeb/cl_pa_pb_attachment_do=>tt_attachment_do,
      lo_attachement  TYPE REF TO /aeb/cl_pa_pb_attachment_do,
      lv_data         TYPE /aeb/01_rawstring,
      ls_torrot       TYPE  /scmtms/d_torrot,
      lo_request      TYPE REF TO /aeb/cl_pa_pb_add_satt_req_do,
      lt_langs        TYPE /aeb/01_char2s,
      lv_lang         TYPE /aeb/01_char2 VALUE 'DE'
      .

"DEFAULT VALUES!!!
"Please change to your own logic

DATA(lo_connection_parms_bc) = /aeb/cl_pa_pb_engn_prm_bc=>get_instance( ).
DATA(lo_engn_prm) = lo_connection_parms_bc->get_engn_prm_do_for( im_org_unit = 'DEFAULT' ).

DATA(lo_carrier_bf) = /aeb/cl_pa_pb_carrier_bf=>new_for(
                        im_engn_prm = lo_engn_prm
                        im_org_unit = 'DEFAULT'
                      ).

DATA(lo_reference_bc) = /ae1/cl_pa_pb_fro_shp_ref_bc=>new_for( im_torrot = ls_torrot ).
DATA(lv_shp_ref) = lo_reference_bc->get_shp_ref_do( ).

CREATE OBJECT lo_attachement.
*lv_data = "Needs to be provided with the proper binary content of the document
lo_attachement->set_data( im_value = lv_data ).
lo_attachement->set_file_name( im_value = 'ABD_' && ls_torrot-tor_id && '.pdf' ).
lo_attachement->set_content_type( im_value = 'EXPORT_ACCOMPANYING_DOCUMENT' ). "COMMERCIAL_INVOICE / PRO_FORMA_INVOICE
lo_attachement->set_mime_type( im_value = 'application/pdf' ).

APPEND lo_attachement TO lt_attachements.

CREATE OBJECT lo_request.
lo_request->set_client_identcode( im_value = lo_engn_prm->get_engine_client( ) ).
lo_request->set_client_system_id( im_value = sy-sysid && '_' && sy-mandt ).
APPEND lv_lang TO lt_langs.
lo_request->set_result_language_iso_codes( im_value = lt_langs ).
lo_request->set_mode( im_value = 'ADD' ).
lo_request->set_shipment_reference( im_value = lv_shp_ref ).
lo_request->set_attachments( im_value = lt_attachements ).
lo_request->set_username( im_value = sy-uname ).

TRY.
    DATA(lo_result) = lo_carrier_bf->add_shipment_attachments( im_request_do = lo_request ).
  CATCH /aeb/cx_01_pb_bf_inv_sc. " Communication exception
    "...
ENDTRY.