REPORT zip_transport.
SELECTION-SCREEN BEGIN OF BLOCK bl01 WITH FRAME TITLE TEXT-t01.
PARAMETERS p_trkorr LIKE e070-trkorr OBLIGATORY.
PARAMETERS p_ttext TYPE as4text.
SELECTION-SCREEN END OF BLOCK bl01.
SELECTION-SCREEN BEGIN OF BLOCK bl02 WITH FRAME TITLE TEXT-t02.
PARAMETERS p_sapdir TYPE string LOWER CASE OBLIGATORY DEFAULT '/usr/sap/trans/'.
PARAMETERS p_lcldir TYPE string LOWER CASE OBLIGATORY DEFAULT 'C:\temp\'.
SELECTION-SCREEN END OF BLOCK bl02.
START-OF-SELECTION.
" Check if Transport is released
DATA ls_request TYPE trwbo_request.
CALL FUNCTION 'TR_READ_REQUEST'
EXPORTING
iv_read_e070 = 'X'
iv_read_e07t = 'X'
iv_trkorr = p_trkorr
CHANGING
cs_request = ls_request
EXCEPTIONS
error_occured = 1
no_authorization = 2
OTHERS = 3.
IF ls_request-h-trstatus <> 'R'.
MESSAGE 'Transport not yet released' TYPE 'E'.
ENDIF.
" Read released Transport
DATA lv_xcontent_k TYPE xstring.
DATA lv_xcontent_r TYPE xstring.
DATA(lo_zipper) = NEW cl_abap_zip( ).
DATA(lv_transdir_k) = |{ p_sapdir }cofiles/K{ p_trkorr+4 }.{ p_trkorr(3) }|.
DATA(lv_transdir_r) = |{ p_sapdir }data/R{ p_trkorr+4 }.{ p_trkorr(3) }|.
TRY.
" K
OPEN DATASET lv_transdir_k FOR INPUT IN BINARY MODE.
READ DATASET lv_transdir_k INTO lv_xcontent_k.
CLOSE DATASET lv_transdir_k.
" R
OPEN DATASET lv_transdir_r FOR INPUT IN BINARY MODE.
READ DATASET lv_transdir_r INTO lv_xcontent_r.
CLOSE DATASET lv_transdir_r.
" Add to ZIP
lo_zipper->add( name = |K{ p_trkorr+4 }.{ p_trkorr(3) }|
content = lv_xcontent_k ).
lo_zipper->add( name = |R{ p_trkorr+4 }.{ p_trkorr(3) }|
content = lv_xcontent_r ).
" Download ZIP
DATA(lv_xzip) = lo_zipper->save( ).
DATA lt_data TYPE TABLE OF tbl1024.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xzip
TABLES
binary_tab = lt_data.
" Set zip filename
DATA(lv_zip_name) = COND #( WHEN p_ttext IS INITIAL THEN |{ p_lcldir }{ ls_request-h-as4text }_{ p_trkorr }.zip|
ELSE |{ p_lcldir }{ p_ttext }_{ p_trkorr }.zip| ).
cl_gui_frontend_services=>gui_download( EXPORTING filename = lv_zip_name
filetype = 'BIN'
CHANGING data_tab = lt_data ).
CATCH cx_root INTO DATA(e_text).
MESSAGE e_text->get_text( ) TYPE 'E'.
ENDTRY.
MESSAGE |{ p_trkorr } zip created and downloaded to { p_lcldir }| TYPE 'S'.
Tag: SAP
[CAP] Generate multitenancy ready bookshop sample
cds init bookshop --add multitenancy,samples,mta,approuter
CAP docs about adding multitenancy: https://cap.cloud.sap/docs/guides/multitenancy/#enable-multitenancy
CAP docs about deploying: https://cap.cloud.sap/docs/guides/deployment/as-saas
[CAP] Download MTA deployment logs after deployment
With this simple command, you can download the MTA deployment logs of your recent deployment. Instead of manually having to use cf dmol -i <operation id>
, just save the command (replace appId with your Id) as a shell script, make it executable (chmod +x) and run the script after your deployment. It stores the recent logs into the folder logs.
dmol
is short for download-mta-op-logs
cf download-mta-op-logs --mta <appId> --last 1 -d logs
To just have a quick look at the recent logs, use
cf logs <appId>-srv --recent
[CAP] Check if User exists in SuccessFactors
To check if a record exists, you can simply use the HEAD query.
“HEAD is almost identical to GET, but without the response body.” (https://www.w3schools.com/tags/ref_httpmethods.asp)
Unfortunately, there is no shortcut in CAP for a HEAD
query, so simply use send
with method HEAD
.
sfsfSrv = await cds.connect.to('sfsf')
try {
await sfsfSrv.send('HEAD', `/User('${userId}')`)
return true // status 200
} catch (err) {
return false // status 404
}
[CAP] Get ID for newly created entry in a table defined with aspect cuid
https://cap.cloud.sap/docs/cds/common#aspect-cuid
const result = await INSERT(payload).into(table)
const newEntries = [...result]
console.log("New ID: " + newEntries[0].ID)
[ABAP] Sum column using reduce with where condition
SELECT * FROM sflight INTO TABLE @DATA(lt_sflight).
DATA(a319_paymant_sum) = REDUCE #( INIT sum = 0
FOR flight IN lt_sflight WHERE ( planetype = 'A319' )
NEXT sum = sum + flight-paymentsum ).
[ABAP] Finding maximum value of specific column in itab
DATA(maximum) = REDUCE #( INIT max = VALUE myType( )
FOR line IN myTable
NEXT max = COND #( WHEN line-myColumn > max THEN line-myColumn
ELSE max ) ).
[ABAP] OData – GET_STREAM implementation to return a PDF
METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.
* This method get's called when a media file is queried with $value. A binary stream will be returned.
TRY.
DATA(file_id) = VALUE zfile_id( it_key_tab[ name = 'file_id' ]-value ).
CATCH cx_sy_itab_line_not_found.
RETURN. " leave here when no file_id provided
ENDTRY.
DATA(ls_file) = get_file( file_id ) " read your file you want to return (if it's not yet a binary stream, convert it)
DATA(ls_stream) = VALUE ty_s_media_resource( value = ls_file-value
mime_type = ls_file-mimetype ). " in my case it's 'application/pdf'
" necessary to display the filename instead of $value in the viewer title
TRY.
" create pdf object
DATA(lo_fp) = cl_fp=>get_reference( ).
DATA(lo_pdfobj) = lo_fp->create_pdf_object( connection = 'ADC' ).
lo_pdfobj->set_document( pdfdata = ls_stream-value ).
" set title
lo_pdfobj->set_metadata( VALUE #( title = ls_file-filename ) ).
lo_pdfobj->execute( ).
" get pdf with title
lo_pdfobj->get_document( IMPORTING pdfdata = ls_stream-value ).
CATCH cx_fp_runtime_internal
cx_fp_runtime_system
cx_fp_runtime_usage INTO DATA(lo_fpex).
ENDTRY.
copy_data_to_ref( EXPORTING is_data = ls_stream
CHANGING cr_data = er_stream ).
" necessary for the pdf to be opened inline instead of a download (also sets the filename when downloaded)
/iwbep/if_mgw_conv_srv_runtime~set_header( VALUE #( name = 'content-disposition'
value = |inline; filename={ ls_file-filename }| ) ).
ENDMETHOD
Quick way to open a PDFViewer in your UI5 App:
const pdfViewer = new PDFViewer()
pdfViewer.setSource("/sap/opu/odata/ZMY_SEVICE" + my_path + "/$value") // my_path could be something like this "/PdfSet('file_id')"
pdfViewer.setTitle("My PDFViewer Title") // title of the popup, not the viewer
pdfViewer.open()
[ABAP] Create DATA-URL from xstring
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs
DATA lv_filetype TYPE char4.
DATA lv_content TYPE xstring.
" get your data, for example a jpg
" lv_filetype = 'jpg'
" lv_content = ....
DATA(mimetype) = /iwwrk/cl_mgw_workflow_rt_util=>get_mime_type_from_extension( lv_filetype ).
DATA(base64) = /iwwrk/cl_mgw_workflow_rt_util=>base64_encode( lv_content ).
DATA(lv_data_url) = |data:{ mimetype };base64,{ base64 }|.
[ABAP] OData – Filtering, Sorting, Paging
" Filter, Sort, Paging
/iwbep/cl_mgw_data_util=>filtering( EXPORTING it_select_options = it_filter_select_options
CHANGING ct_data = et_entityset ).
/iwbep/cl_mgw_data_util=>orderby( EXPORTING it_order = it_order
CHANGING ct_data = et_entityset ).
/iwbep/cl_mgw_data_util=>paging( EXPORTING is_paging = is_paging
CHANGING ct_data = et_entityset ).