These are my notes on the steps needed to create the data model and publish it as oData service.
#
Layer
Nomenclature
Description
1
Database Table
ZTABLE
Place your raw data first
2
Data Definition (Interface View)
ZI_
Relation between different tables (e.g. currency or text table)
3
Projection View (Consumption View)
ZC_
Configure the UI depending on your scenario. Use different projection views for different usages of the same interface view and the same physical table.
4
Service Definition
ZSD_
Expose the projection view (and underlying associations like currency, country…) as service
5
Service Binding
ZSB_
How to we want to make the service available? Defines the binding type (OData V2 / OData V4) Activate it with the “Activate” Button within the editor window. Select the Entity and hit “Preview…” to see whtat we defined in our projection view.
If you’ve done this, you are able to view the data in a generated Fiori Elements app. But if you also want to create, edit, delete data, you’ll have to add some behavior functionality.
6
Behavior Definition on Data Definition
ZI_
Created on top of the Data Definition. Will get the same name es the Data Definition. Implementation Type: Managed Defines the operations create, delete, edit.
7
Behavior Implementation on Definition View
ZBP_I_
The code for the behavior… For the travel app tutorial, some logic for a generated unique key and field validation. The class inherits from cl_abap_behavior_handler.
8
Behavior Definition on Projection View
ZC_
Created on top of the Projection View. Will get the same name es the Projection View. Defines the operations create, delete, edit.
Recently I got the demand to enhance the leave request approvel workflow with some mail steps. These mails should also include the attachments, which can be uploaded in the “Leave Request” Fiori App.
To achive this, I used the exit functionality in the mail step.
There you have to provide a class name. The class has to implement the following interface:
IF_SWF_IFS_WORKITEM_EXIT
You will get a method you can implement.
This Method has two parameters, the “Event Name” and the “Workitem Context”.
With the event, you are able to control, in which situations your exit should be fired. In my case, I just need my code run when the workitem is created (event “CREATED”). You’ll find all usable events in domain SWW_EVTTYP.
To get and pass back the attachment to the mail step, a few things need to be done. First, get the curent workitem container and check, if there is already any attachment. If not, read the request id from the leave request. With this request id, you are able to find the attachment you need. I’ve already written a method for that, you’ll find below. Then convert the xstring to a solix table, create the attachment document with function module “SO_DOCUMENT_INSERT_API1” and “SWO_CREATE” and finally pass it to the container.
METHOD if_swf_ifs_workitem_exit~event_raised.
DATA: lv_container TYPE REF TO if_swf_ifs_parameter_container,
lv_attach TYPE TABLE OF obj_record,
lv_folder_id TYPE soodk,
wa_document_info TYPE sofolenti1,
lv_data TYPE sodocchgi1,
lv_objtype TYPE swo_objtyp,
lv_objkey TYPE swo_typeid,
lv_return TYPE swotreturn,
lv_sofm TYPE swo_objhnd,
lv_objject TYPE obj_record,
tb_obj TYPE TABLE OF obj_record,
it_solix_tab1 TYPE solix_tab,
req_id TYPE tim_req_id,
lv_doc_type TYPE so_obj_tp.
CHECK im_event_name = 'CREATED'.
* Fetch Container
lv_container = im_workitem_context->get_wi_container( ).
* Read attachment to confirm that there is no duplication
TRY.
lv_container->get(
EXPORTING
name = '_ATTACH_OBJECTS'
IMPORTING
value = lv_attach ).
CATCH: cx_swf_cnt_elem_not_found,
cx_swf_cnt_elem_type_conflict,
cx_swf_cnt_unit_type_conflict,
cx_swf_cnt_container.
ENDTRY.
CHECK lv_attach IS INITIAL.
CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
EXPORTING
owner = sy-uname
region = 'B'
IMPORTING
folder_id = lv_folder_id.
* Get Request ID
lv_container->get(
EXPORTING
name = 'RequestId'
IMPORTING
value = req_id ).
* Get XSTRING of attachment
zcl_xxx=>get_req_attachment(
EXPORTING
iv_req_id = req_id
IMPORTING
ev_xstring = DATA(xstring)
es_attachment = DATA(ls_attachment) ).
CHECK xstring IS NOT INITIAL.
* Get document type
SELECT SINGLE doc_type FROM toadd INTO @lv_doc_type
WHERE mimetype EQ @ls_attachment-file_type.
IF sy-subrc NE 0.
lv_doc_type = 'PDF'. "If doc_type not found, at least try with pdf.
ENDIF.
* Create and set document
it_solix_tab1 = cl_document_bcs=>xstring_to_solix( xstring ).
* Creating First attachment
lv_data-obj_name = ls_attachment-file_name.
lv_data-obj_descr = ls_attachment-file_name.
lv_data-obj_langu = sy-langu.
lv_data-sensitivty = 'P'.
* lv_data-doc_size = ls_attachment-file_size.
CALL FUNCTION 'SO_DOCUMENT_INSERT_API1'
EXPORTING
folder_id = lv_folder_id
document_data = lv_data
document_type = lv_doc_type
IMPORTING
document_info = wa_document_info
TABLES
contents_hex = it_solix_tab1
EXCEPTIONS
folder_not_exist = 1
document_type_not_exist = 2
operation_no_authorization = 3
parameter_error = 4
x_error = 5
enqueue_error = 6
OTHERS = 7.
* Populate object type and object key for create an instance
lv_objtype = 'SOFM'.
lv_objkey = wa_document_info-doc_id.
CALL FUNCTION 'SWO_CREATE'
EXPORTING
objtype = lv_objtype
objkey = lv_objkey
IMPORTING
object = lv_sofm
return = lv_return
EXCEPTIONS
no_remote_objects = 1
OTHERS = 2.
* Prepare for attaching the object to container
lv_objject-header = 'OBJH'.
lv_objject-type = 'SWO'.
lv_objject-handle = lv_sofm.
APPEND lv_objject TO tb_obj.
*—can be used for other workitems
lv_container->set(
EXPORTING
name = '_ATTACH_OBJECTS'
value = tb_obj[] ).
*–this will add the attachment to email
lv_container->set(
EXPORTING
name = 'ATTACHMENTS'
value = tb_obj[] ).
* Commit the changes
im_workitem_context->do_commit_work( ).
ENDMETHOD.
The following function modules are needed to read the leave request attachment: