Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
maheshpalavalli
Active Contributor
 

Introduction


Many of us already know about the famous GOS functionality available for GUI. We must have used it many standard applications for adding attachments in GUI. It is not only available for standard applications but also available for custom GUI based applications with minimal coding. So what if this kind of functionality is available for Fiori based apps? yes it is provided via the the attachment service.

How I used to handle attachments


Most of us had one or other issue related to Attachments in UI5 and ABAP and would have tried many different ways to save and read attachments. I tried the below two ways till now.

  1. Using Upload collection control - Without posting the data immediately after uploading a file and saving it locally in a json model and push all the attachments via the deep structure once the user clicks on save.   It has many disadvantages, e.g., large data has to be sent in a single request in case of multiple added attachments, which will make ur save slow. (very bad way)

  2. Using Upload collection control - Posting the data to the backend immediately after uploading a file and saving in a temporary table in SAP and the temp attachments in the temporary table will be having an unique ID and when user clicks on save in the Fiori app, I will read the attachments from the temp table based on the unique key and save it to GOS and delete that temp data. (most of the times I do this). This is very fast and best approach and this is kind of inspired from the standard attachment service that I saw in S4HANA.


You can see that the second approach is very clean and light weight right?

and the attachment service provides reuseable ui5 component and some API's for us to handle this in a very easy way and this will hardly take around 15 lines of code to make it work end-to-end. Let's see it in action.

Architecture


Taken for SAP help, link


DEMO


Let's first see the demo of attachment service and how it works in the below video and later move to the development part.


Implementation


Let's do this in multiple steps.

1. Custom BO GUI GOS Implementation


This steps is to validate if the GOS attachments in the GUI and the attachments added via the attachment service in the Fiori Element app are the same.

In this step, let's create a dummy report where we can enter the "Carrier ID" ( Flight tables) and in the result page, we should see the GOS toolbar, where can add/view the attachments.

So I created a new Business Object (SWO1, obviously this works for existing Business Objects as well) ZCAR2020, which has only one key field "carrid" from scarr table.

then I create a report, which takes only one input parameter "carrid" and will link the it and above created business object to the GOS toolbar.

check the code below: ref. taken from naimesh.patel blog
PARAMETERS:
carrier TYPE scarr-carrid.

START-OF-SELECTION.

" Set the GOS
NEW cl_gos_manager( is_object = VALUE #( objtype = 'ZCAR2020' objkey = carrier )
ip_no_commit = abap_false ).

WRITE: 'GOS test for carrier'.

Very simple code there. Output will be:



After F8



Now clicking on the above highlighted button will show the GOS menu and clicking on the attachments will show the attachments popup.



 

So now we saw how simple it is to add GOS toolbar, which will take care of the attachments for us. This is how it will work typically for other standard apps as well. So let's use the same BO and integrate it in the attachment service.

2. List Report template app (Fiori Elements) Implementation


Now I will create a list report app for the carrier table, which is a draft enabled application. I created the draft enabled CDS view an BO based on the below blog reference.

https://blogs.sap.com/2019/01/09/abap-programming-model-for-sap-fiori-draft-based-for-non-guid-keys-...

Not posting the code as it is a basic draft enabled CDS view with basic annotations.

Final List report application generated from the above CDS views.


3. Integrating Attachment service with the above generated List Report app


Add the dependencies for the attachment service library ("sap.se.mi.plm.lib.attachmentservice")
"dependencies": {
"minUI5Version": "1.38.34",
"libs": { //-----> This one
"sap.se.mi.plm.lib.attachmentservice": {}
},
"components": {}
},

Now the idea is to show the attachment component as section in the object page. So we need to add a section in the object page, but it will be a reuse component via the embeddedComponents approach. For more information check the UI5 documentation.

Code to add the reuse attachment component as a section in the object page.
"pages": {
"ObjectPage|ZC_CarrierBO": {
"entitySet": "ZC_CarrierBO",
"component": {
"name": "sap.suite.ui.generic.template.ObjectPage"
},
"embeddedComponents": { ----> Begins here
"simple::Attachments": {
"id": "simple::Attachments",
"componentName": "sap.se.mi.plm.lib.attachmentservice.attachment.components.stcomponent",
"title": "{{Attachments}}",
"settings": {
"mode": "{= ${ui>/editable}?'C':'D'}",
"objectType": "ZCAR2020",
"objectKey": "{parts:[{path:'carrid'},{path:'DraftUUID'}],formatter:'attachmentServiceTest.model.formatter.returnAttachmentKey'}"
}
}
}
}
}

So in the above code, we can see that we are including the embedded components inside the object page and the component name of the attachment service and settings.

The settings are from the attachment service and not specific to reuse component (documentation link).

mode => Tells whether it is create mode or display mode and we are using the binding there with the model - "UI" model which is part of the List report template and it has values "C" for create mode and "D" for display mode, this will be interpreted by attachment service to show/hide the + icon for adding attachments.

This is a common setting and we can copy paste this in all apps

objectType => This is the business object, can be standard or custom

objectKey => Here we will pass the key, in our case, it will be the "carrid". BUT in case if it is the create scenario, there will be no key field and the key will be the "Draft ID". So we are using the formatter to create the key dynamically.

 

Formatter Code=> which is used to create the key
sap.ui.define([], function () {
"use strict";
var formatter = {};
formatter.returnAttachmentKey = function (Carrid, DraftUUID) {
var objectKey = "";
if (Carrid !== undefined && Carrid !== null && Carrid !== "") {
objectKey = Carrid;
} else if (DraftUUID !== undefined && DraftUUID !== null && DraftUUID !== "") {
objectKey = DraftUUID.replace(/[^a-zA-Z0-9]/g, "");
}
return objectKey;
};
return formatter;

}, /* bExport= */ true);

In the component.j, just mention the dependencies:
metadata: {
"manifest": "json",
dependencies: {
libs: ["sap.m",
"sap.se.mi.plm.lib.attachmentservice"
],
components: [
"sap.se.mi.plm.lib.attachmentservice.attachment.components.stcomponent"
]
}
}

Last one step, but only for the testing in the WEBIDE, we need to update the neo-app.json file. (add at the end)
"headerWhiteList": [

"objecttype",

"objectkey",

"MarkForDeletion",

"documentType",

"documentNumber",

"documentVersion",

"documentPart",

"semanticobjecttype"

]

 

Now, what left is for us to test.

4. Testing the Display scenario




Check the above demo video for more details.

We can see a new section for "Attachments" added there, which is displaying the attachments reuse component. It is also fetching the attachments that I added in the GOS gui application 🙂 Pretty cool right, just with minimal changes.

5. Configuring the Edit & Save Scenario.


Technically for Create/Edit also this will work but the attachments will not be saved to GOS and are in some temporary table. So we need to call the attachments api's save method to save the attachments to GOS in the draft class.
  METHOD /bobf/if_frw_draft~copy_draft_to_active_entity.
DATA:
carrier_root TYPE zticarrierbo_tpl.
io_read->retrieve(
EXPORTING
iv_node = zif_i_carrierbo_tpl_c=>sc_node-zi_carrierbo_tpl " Node Name
it_key = it_draft_key " Key Table
IMPORTING
et_data = carrier_root " Data Return Structure
).

DATA objectkey TYPE objky.
DATA temp_objectkey TYPE objky.
DATA(attachment_api) = cl_odata_cv_attachment_api=>get_instance( ).
IF carrier_root[ 1 ]-carrid IS NOT INITIAL.
TRY.
objectkey = carrier_root[ 1 ]-carrid.
temp_objectkey = carrier_root[ 1 ]-key.
CALL METHOD attachment_api->if_odata_cv_attachment_api~save
EXPORTING
iv_objecttype = 'ZCAR2020'
iv_objectkey = objectkey
iv_objecttype_long = 'ZCAR2020'
iv_temp_objectkey = temp_objectkey
iv_no_commit = abap_true
IMPORTING
ev_success = DATA(ok)
et_messages = DATA(messages).


DATA(key_util) = /bobf/cl_lib_legacy_key=>get_instance( zif_i_carrierbo_tpl_c=>sc_bo_key ).

DATA(bobf_key) = key_util->convert_legacy_to_bopf_key(
iv_node_key = zif_i_carrierbo_tpl_c=>sc_node-zi_carrierbo_tpl
is_legacy_key = objectkey ).

APPEND VALUE #( draft = it_draft_key[ 1 ]-key active = bobf_key ) TO et_key_link.


CATCH cx_odata_cv_base_exception INTO DATA(lo_excp).
ENDTRY.
ENDIF.
ENDMETHOD.

 

That's it folks, It is as simple as using the GOS toolbar in your custom GUI app. All the functionality is provided by SAP themselves in the form of component reusability.

and Thanks to all the devs who made this beautiful reusable application at SAP!!

 

Code reference taken from Suppliers Fiori App.

References:


Attachment service help:

https://help.sap.com/viewer/4c3d1c6b3d744f84aab4c273f979f430/1909.000/en-US/b821e557b83a1070e1000000...

Already a blog is available on this, but with limited and old information and also it was a lengthy process.

https://blogs.sap.com/2016/03/23/s4-hana-how-to-consume-attachment-reuse-ui-component-via-smart-temp...

Standard Documentation for Reuse Components:

https://ui5.sap.com/#/topic/d869d7ab3caa48b2a20dc20dfa248380

 
47 Comments
Labels in this area