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: 
Introduction:

Many times while working with Transactional List Report Apps developed using SAP Fiori Elements we might have requirements to get dynamic input from the end user , like providing a popup where user makes selection and then we need to take actions accordingly.

In order to develop transactional App SAP provided us 2 programming model which are as follows.

  1. ABAP Programming model for Fiori ( Developed using Business Object Processing Framework-BOPF)

  2. RestFul Application Programming Model(RAP)


In this blog we will see how to invoke API Actions using ABAP Programming model for Fiori

Scenario:

Let us consider an e.g., of Sales Order processing, where the end user after entering Item details needs an option to select additional Charges.

The additional charges could be combination of one or more of the below charges.

  1. Freight Charges

  2. Miscellaneous charges

  3. Other Charges


So below screen shot shows that the user can enter Additional Charges from the popup by pressing the Additional charges Button and in the backend, we need to add these charges to the Total of gross amount for the item selected and the value should be reflected in the front-end Fiori App.




In order to achieve this, we will follow below steps as mentioned in Flowchart.


So let us see each step.

Implementation Steps:

Step 1: Creating  Sales Order Header and Item Database table

We create Custom Sales header Table ZSOH, where we use SoKey which is 16-digit GUID and primary Key for table. The same will be used to generate Draft key in Draft Table.
@EndUserText.label : 'Sales Order Header'
@AbapCatalog.enhancementCategory : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table zsoh {
@AbapCatalog.foreignKey.screenCheck : false
key client : mandt not null
with foreign key [0..*,1] t000
where mandt = zsoh.client;
key sokey : snwd_node_key not null;
soid : snwd_so_id;
bpid : snwd_partner_id;
include /bobf/s_lib_admin_data;

}

Next we create Item table ZSOI where we use SOITMKEY as 16 digit GUID and we include fields to get product id  , Gross Amount , Currency and Additional Charges as shown below.
@EndUserText.label : 'SO Item Table'
@AbapCatalog.enhancementCategory : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table zsoi {
@AbapCatalog.foreignKey.screenCheck : false
key client : mandt not null
with foreign key [0..*,1] t000
where mandt = zsoi.client;
key soitmkey : snwd_node_key not null;
@AbapCatalog.foreignKey.screenCheck : false
sokey : snwd_node_key
with foreign key [0..*,1] zsoh
where sokey = zsoi.sokey;
soitm : snwd_so_item_pos;
product : snwd_product_id;
@Semantics.amount.currencyCode : 'zsoi.currencycode'
grossamount : snwd_ttl_gross_amount;
currencycode : snwd_curr_code;
quantity : int4;
@Semantics.amount.currencyCode : 'zsoi.currencycode'
addcharge : snwd_ttl_gross_amount;
include /bobf/s_lib_admin_data;

}

Step 2: Create Interface View for Header and Item Tables , also generate the BOPF object  and Draft table using @ObjectModel Annotation.

We Create ZI_SOH interface view to generate BOPF object and we also mark the Create, Update and Delete Enabled as true. We define ZSOH_DRAFT as Draft Table. Below is the code for the same
@AbapCatalog.sqlViewName: 'ZISOH'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Interface view for BO with Draft'
@ObjectModel: {
createEnabled: true,
updateEnabled: true,
deleteEnabled: true,
draftEnabled: true,
modelCategory:#BUSINESS_OBJECT ,
semanticKey: ['Soid'],
compositionRoot: true,
transactionalProcessingEnabled: true,
writeDraftPersistence: 'ZSOH_DRAFT',
writeActivePersistence: 'ZSOH',
entityChangeStateId: 'Lchg_Date_Time'
}
define view ZI_SOH as select from ZSOH as soh
association [1..*] to ZI_SOI as _itm on $projection.Sokey = _itm.Sokey
association [0..1] to SEPM_I_BusinessPartner as _bpa on $projection.Bpid = _bpa.BusinessPartner
{
@ObjectModel.readOnly: true
key soh.sokey as Sokey,
@Search.defaultSearchElement: true
soh.soid as Soid,
@ObjectModel.foreignKey.association: '_bpa'
soh.bpid as Bpid,
@Semantics.systemDateTime.createdAt: true
soh.crea_date_time as Crea_Date_Time,
@Semantics.user.createdBy: true
soh.crea_uname as Crea_Uname,
@Semantics.systemDateTime.lastChangedAt: true
soh.lchg_date_time as Lchg_Date_Time,
@Semantics.user.lastChangedBy: true
soh.lchg_uname as Lchg_Uname,
@ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
_itm
}

Similarly we create Item Interface view as shown below and use ZSOI_DRAFT as draft table
@AbapCatalog.sqlViewName: 'ZISOI'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Sales Item BO Draft'
@ObjectModel: {
createEnabled: true,
updateEnabled: true,
deleteEnabled: true,
semanticKey: ['Sokey','Soitm'],
writeDraftPersistence: 'ZSOI_DRAFT',
writeActivePersistence: 'ZSOI'
}
define view ZI_SOI as select from zsoi as soi
association [1..1] to ZI_SOH as _soh on $projection.Sokey = _soh.Sokey
association [0..1] to SEPM_I_Product_E as _pd on $projection.Product = _pd.Product
association [0..1] to SEPM_I_Currency as _curr on $projection.Currencycode = _curr.Currency
{
key soi.soitmkey as Soitmkey,
soi.sokey as Sokey,
@ObjectModel.readOnly: true
soi.soitm as Soitm,
@ObjectModel.foreignKey.association: '_pd'
soi.product as Product,
@ObjectModel.readOnly: true
@Semantics.amount.currencyCode: 'Currencycode'
soi.grossamount as Grossamount,
@ObjectModel.foreignKey.association: '_curr'
@Semantics.currencyCode: true
soi.currencycode as Currencycode,
soi.quantity as Quantity,
@Semantics.amount.currencyCode: 'Currencycode'
@ObjectModel.readOnly: true
soi.addcharge as AddCharge,
@ObjectModel.association.type: [#TO_COMPOSITION_PARENT,#TO_COMPOSITION_ROOT]
_soh,
_pd,
_curr

}

We get the BOPF generated below is the screen shot for the same with Parent Child Relationship.


Step 3: Create Consumption View, in which we use UI annotations to create Fiori Elements App.

We Create 2 Consumption CDS view ZC_SOH and ZC_SOI and use UI annotations so that it will create all the required controls in fiori elements app.
@AbapCatalog.sqlViewName: 'ZCSOH'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Consumption SO Hdr BO Draft'
@ObjectModel: {
createEnabled: true,
updateEnabled: true,
deleteEnabled: true,
draftEnabled: true,

semanticKey: ['Soid'],
compositionRoot: true,
transactionalProcessingDelegated: true
}
@UI.headerInfo: {
typeName: 'Sales Order',
typeNamePlural: 'Sales Orders',
title: {
type: #STANDARD,
value: 'Bpid'
},
description: {
type: #STANDARD,
value: 'Soid'
}
}
@VDM.viewType: #CONSUMPTION
@OData.publish: true
define view ZC_SOH as select from ZI_SOH
association [0..*] to ZC_SOI as _itm on $projection.Sokey = _itm.Sokey
association [0..1] to SEPM_I_BusinessPartner as _bpa on $projection.Bpid = _bpa.BusinessPartner
{
@UI.facet: [
{
id: 'Hdr',
purpose: #HEADER,
position: 10,
type: #FIELDGROUP_REFERENCE,
targetQualifier: 'HdrInfo'
},
{
id: 'SoHdr',
purpose: #STANDARD,
position: 10,
label: 'Header Details',
type: #IDENTIFICATION_REFERENCE
},
{
id: 'SoItm',
purpose: #STANDARD,
position: 20,
label: 'Item Details',
type: #LINEITEM_REFERENCE,
targetElement: '_itm'
}]
@UI.hidden: true
key Sokey,
@UI: {
lineItem: [ { position: 10, label: 'Sales Order ID', importance: #HIGH } ],
selectionField: [ { position: 10 } ],
identification:[ { position: 10 } ]
}
@UI.fieldGroup: [{ qualifier: 'HdrInfo' , position: 10 }]
@ObjectModel.readOnly: true
Soid,
@UI: {
lineItem: [ { position: 20, label: 'Customer', importance: #HIGH } ],
identification: [{ position: 20 }]
}
Bpid,
Crea_Date_Time,
Crea_Uname,
Lchg_Date_Time,
Lchg_Uname,
/* Associations */
@ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
_itm,
_bpa
}

@AbapCatalog.sqlViewName: 'ZCSOI'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'consumption view for BOD SOI'
@ObjectModel:
{
createEnabled: true,
updateEnabled: true,
deleteEnabled: true,
semanticKey: ['Sokey', 'Soitm']
}
@UI: {
headerInfo: {
typeName: 'Sales Order Item',
typeNamePlural: 'Sales Order Items',
title: { type: #STANDARD, value: '_soh.Bpid' },
description:{ type: #STANDARD, value: '_soh.Soid' }
}
}

define view ZC_SOI as select from ZI_SOI as soi
association [1..1] to ZC_SOH as _soh
on $projection.Sokey = _soh.Sokey
association [0..1] to SEPM_I_Product_E as _pd
on $projection.Product = _pd.Product
association [0..1] to SEPM_I_Currency as _curr
on $projection.Currencycode = _curr.Currency
{
@UI.facet: [{
id: 'Item',
purpose: #STANDARD,
position: 10,
label: 'Item Details',
type: #IDENTIFICATION_REFERENCE
},
{
id: 'IHdr',
purpose: #HEADER,
position: 10,
type: #FIELDGROUP_REFERENCE,
targetQualifier: 'IHdrItm'
}]
@UI.hidden: true
key soi.Soitmkey as Soitmkey,
@UI.hidden: true
soi.Sokey as Sokey,
@UI.fieldGroup: [{ qualifier: 'IHdrItm' , position: 10 }]
@UI.lineItem: [{position: 10 , importance: #HIGH}]
@UI.identification: [{position: 10 }]
@ObjectModel.readOnly: true
soi.Soitm as Soitm,
@UI.lineItem: [{position: 20 , importance: #HIGH}]
@UI.identification: [{position: 20 , importance: #HIGH }]
@ObjectModel.foreignKey.association: '_pd'
soi.Product as Product,
@UI.lineItem: [{position: 40 ,importance: #HIGH}]
@ObjectModel.readOnly: true
@Semantics.amount.currencyCode: 'Currencycode'
soi.Grossamount as Grossamount,
@ObjectModel.foreignKey.association: '_curr'
@Semantics.currencyCode: true
soi.Currencycode as Currencycode,
@UI.lineItem: [{position: 30 , label : 'Quantity', importance: #HIGH}]
@UI.identification: [{position: 40, label : 'Quantity' }]
soi.Quantity as Quantity,
@UI.lineItem: [{position: 40, importance: #HIGH, label: 'Additional Charges' }]
@ObjectModel.readOnly: true
soi.AddCharge,
/* Associations */
_curr,
_pd,
@ObjectModel.association.type: [#TO_COMPOSITION_PARENT,#TO_COMPOSITION_ROOT]
_soh
}

Step 4: Create 2 determinations in BOPF as follows

  1. Generate the Sales order number in Sales order Header Node:


This Determination will generate Sales Order number for create Scenario. Below is the code.



Below is the code implemented to generate the SO Id number.
class ZCL_I_D_CALC_SO_ID definition
public
inheriting from /BOBF/CL_LIB_D_SUPERCL_SIMPLE
final
create public .

public section.

methods /BOBF/IF_FRW_DETERMINATION~EXECUTE
redefinition .
protected section.
private section.
ENDCLASS.



CLASS ZCL_I_D_CALC_SO_ID IMPLEMENTATION.


method /BOBF/IF_FRW_DETERMINATION~EXECUTE.
DATA: itab TYPE ZTISOH.

CALL METHOD io_read->retrieve
EXPORTING
iv_node = is_ctx-node_key
it_key = it_key
IMPORTING
et_data = itab.
LOOP AT itab REFERENCE INTO DATA(lr_tab).
IF lr_tab->soid IS INITIAL.
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = '01'
object = 'RV_BELEG'
IMPORTING
number = lr_tab->soid
EXCEPTIONS
interval_not_found = 1
number_range_not_intern = 2
object_not_found = 3
quantity_is_0 = 4
quantity_is_not_1 = 5
interval_overflow = 6
buffer_overflow = 7
OTHERS = 8.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
CALL METHOD io_modify->update
EXPORTING
iv_node = is_ctx-node_key
iv_key = lr_tab->key
is_data = lr_tab
it_changed_fields =
VALUE #( ( ZIF_I_SOH_C=>sc_node_attribute-zi_soh-soid ) )
.
* CATCH /bobf/cx_frw_contrct_violation.
ENDIF.
ENDLOOP.

endmethod.
ENDCLASS.

We now implement code to generate item number and also, we implement code to set the gross item = product price * Quantity entered by the user.



Below is the code for the same.
CLASS zcl_i_d_calc_soitm_cal_gross DEFINITION
PUBLIC
INHERITING FROM /bobf/cl_lib_d_supercl_simple
FINAL
CREATE PUBLIC .

PUBLIC SECTION.

METHODS /bobf/if_frw_determination~execute
REDEFINITION .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.



CLASS zcl_i_d_calc_soitm_cal_gross IMPLEMENTATION.


METHOD /bobf/if_frw_determination~execute.
DATA:
itab TYPE ztisoi,
itab1 TYPE ztisoh,
li_key TYPE /bobf/t_frw_key.
* We Retrive the Items of the Sales Order
CALL METHOD io_read->retrieve
EXPORTING
iv_node = is_ctx-node_key
it_key = it_key
IMPORTING
et_data = itab.

DATA(lw_itm) = VALUE #( itab[ soitm = space ] OPTIONAL ).
READ TABLE itab WITH KEY soitm = space TRANSPORTING NO FIELDS.
* Get the parent node to get the sales order number because Item does not have Sales order number
IF sy-subrc = 0.
CALL METHOD io_read->retrieve_by_association
EXPORTING
iv_node = zif_i_soh_c=>sc_node-zi_soi
it_key = it_key
iv_association = zif_i_soh_c=>sc_association-zi_soi-to_root
iv_fill_data = abap_true
IMPORTING
et_data = itab1
et_target_key = li_key .

READ TABLE itab1 INTO DATA(lw_tab1) INDEX 1.
SELECT SINGLE sokey FROM zsoh INTO @DATA(lv_sokey) WHERE soid = @lw_tab1-soid.
IF sy-subrc <> 0.
SELECT SINGLE sokey FROM ZSOH_draft INTO lv_sokey WHERE soid = lw_tab1-soid.
ENDIF.

WITH +both AS ( SELECT soitm FROM zsoi WHERE sokey = @lv_sokey
UNION ALL
SELECT soitm FROM zsoi_draft WHERE sokey = @lv_sokey )
SELECT SINGLE
FROM +both
FIELDS MAX( soitm ) AS salesorderitem
INTO @DATA(lv_max_salesorderitem).


" If there are no entries, set a start value
IF lv_max_salesorderitem IS INITIAL.
lv_max_salesorderitem = '0000000000'.
ENDIF.
ENDIF.

* Get the Item and also Gross amount
LOOP AT itab REFERENCE INTO DATA(lr_tab).
IF lr_tab->soitm IS INITIAL.
lr_tab->soitm = lv_max_salesorderitem = lv_max_salesorderitem + 10.
lr_tab->soitm = |{ lr_tab->soitm ALPHA = IN }|.
ENDIF.


if lr_tab->quantity IS NOT INITIAL AND lr_tab->product IS NOT INITIAL.
SELECT SINGLE * FROM snwd_pd INTO @Data(lw_snwd_pd) WHERE product_id = @lr_tab->product.
* We add the Add Charge + quantity * price
lr_tab->grossamount = ( lr_tab->quantity * lw_snwd_pd-price ) + lr_tab->addcharge.
lr_tab->currencycode = lw_snwd_pd-currency_code.
ENDIF.
CALL METHOD io_modify->update
EXPORTING
iv_node = is_ctx-node_key
iv_key = lr_tab->key
* iv_root_key =
is_data = lr_tab
it_changed_fields =
VALUE #( ( zif_i_soh_c=>sc_node_attribute-zi_soi-soitm )
( zif_i_soh_c=>sc_node_attribute-zi_soi-grossamount )
( zif_i_soh_c=>sc_node_attribute-zi_soi-currencycode ) ).
* CATCH /bobf/cx_frw_contrct_violation.

ENDLOOP.

ENDMETHOD.
ENDCLASS.

We now also activate the OData Service using /IWFND/MAINT_SERVICE TCODE in SAP.



Step 5: Create List Report Elements App

  1. Open VS Code and use command pallet to create Fiori Elements App

  2. View->Command Pallet ->Open Template Wizard

  3. Select Fiori Elements List Report Floor plan, select your S/4 HANA system and give the Service name and project Details.



Next We preview the app




We click Create button on item to create Items.


In the next step we will add Additional Charges Button to allow users to enter additional charges. In order to achieve the same we will be using Extension and Fiori Free Style coding.

Step 6: Using Extension to Create an Additional Charges Button

In order to get additional charges from the user we will perform below steps

  1. Use Extension to create Additional Charges Button

  2. Create a Fragment for creating Table where user will Enter Details

  3. Invoke the Fragment from the Controller.


Create Additional Charges Button we will use Guided Development tool to add Custom button.

View->Command Pallet->Open Guided Development


We give below Details in step 1 and click on Insert Snippet Button so that it creates ObjectPageExt.controller











Page Object Page
Function Name getAdditionalCharge


In Step 2 we give below Details and click on Insert Snippet , so that we get the details updated in Manifest JSON.



























Entity Set ZC_SOH
Action Position Section
Facets Annotation Term ID Item Details
Action ID idGetAddChrg
Button Text Additional Charge
Row Selection Yes

Below Code Gets generated in Manifest JSON.


We can see that ext folder is created inside that we get ObjectPageExt.controller.controller.js file as shown below. We will implement code for Invoking Pop up later. In the next step we will create fragment.


Step 7: Create Fragment which we will invoke it from the Extension Function.

  1. This fragment will have responsive table with multiselect option

  2. Two Buttons Copy and Cancel Action.

  3. We do Aggregation Binding on the table using Named JSON Model “Charge”



Below is the XML code for the fragment.
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc"
height="100%">
<Dialog id="idExtraCharges" title="Other Charges" class="sapUiNoContentPadding">
<content>
<VBox id="idChargeVbox" class="sapUiSmallMarginBeginEnd">
<Table id="idChargeTable" inset="false" items="{Charge>/ExtraChrg}" mode="MultiSelect">
<columns>
<Column width="12em">
<Text text="Charge Type"/>
</Column>
<Column minScreenWidth="Tablet" demandPopin="true">
<Text text="Amount"/>
</Column>
<Column minScreenWidth="Desktop" demandPopin="true" hAlign="End">
<Text text="Currency"/>
</Column>
</columns>
<items>
<ColumnListItem vAlign="Middle">
<cells>
<Text text="{Charge>ChargeType}"/>
<Input value="{Charge>Amount}"/>
</cells>
</ColumnListItem>
</items>
</Table>
</VBox>
</content>
<buttons>
<Button id="btncopy" text="Copy" press="onActionCopy" />
<Button id="btncancel" text="Cancel" press="onActionCancel"/>
</buttons>
</Dialog>
</core:FragmentDefinition>

Step 8: Implement Logic in Controller to Trigger Fragment as Pop up.

Next we implement the ObjectPageExt Controller.

onInit Method: In this method we define the JSON Model “Charge” which will have 2 fields Charge Type and Amount.Since we have 3 types of Charges we will define Freight Charge, Miscellaneous Charge and Other Charge.Amount would be 0 we will bind fill it from Popup Table. Below is the Code for the same


getAdditionalCharge: In this method we validate if the user is in Edit or Create mode , if not we give error or trigger Pop up. We also get the Details of the line item selected because we will need to send this details to backend to modify values.


In the Pop up we had 2 Fragment we have 2 Buttons Copy and Cancel , when the user clicks Cancel we should come out of the popup and do nothing so below is the code to trigger

Close Pop up.


When the user clicks on Copy, we need to get the details of charges entered by the user and then we need to invoke the BOPF Action from backend , we will come back to this later once we finish the next step of creating Static Action.


Step 9: Create Static BOPF Action

We will create Static Action in BOPF to get the Additional Charges modify the Additional charges amount. We will do below Steps. We create static action in the Item node in BOPF as shown below


We then define the structure for ZADD_CHRG in SAP , this will have 2 parameters Draft ID and Total Coming from Front end system.


We now implement the changes in class ZCL_I_A_SET_ADD_CHRG , because we need to update the additional charge. Below is the code , we get the parameter from the front end , then we add up the gross amount and update the BO.
class ZCL_I_A_SET_ADD_CHRG definition
public
inheriting from /BOBF/CL_LIB_A_SUPERCL_SIMPLE
final
create public .

public section.

methods /BOBF/IF_FRW_ACTION~EXECUTE
redefinition .
protected section.
private section.
ENDCLASS.



CLASS ZCL_I_A_SET_ADD_CHRG IMPLEMENTATION.


method /BOBF/IF_FRW_ACTION~EXECUTE.
DATA : ls_parameters TYPE ZADD_CHRG,
lt_key TYPE /bobf/t_frw_key,
ls_key TYPE /bobf/s_frw_key,
itab TYPE ZTISOI.

"Retrive Source data from Frontend
DATA(ls_parameters_ptr) = CAST zadd_chrg( is_parameters ).

MOVE ls_parameters_ptr->* TO ls_parameters.
ls_key-key = ls_parameters-draftuuid.
APPEND ls_key TO lt_key.

call METHOD io_read->retrieve
EXPORTING
iv_node = ZIF_I_SOH_C=>sc_node-zi_soi
it_key = lt_key
IMPORTING
et_data = itab.

loop at itab REFERENCE INTO data(lr_tab).
lr_tab->addcharge = ls_parameters-amount + lr_tab->addcharge.
lr_tab->grossamount = lr_tab->grossamount + ls_parameters-amount.

call METHOD io_modify->update
EXPORTING
iv_node = ZIF_I_SOH_C=>sc_node-zi_soi
iv_key = lr_tab->key
is_data = lr_tab
it_changed_fields =
VALUE #( ( ZIF_I_SOH_C=>sc_node_attribute-zi_soi-grossamount )
( ZIF_I_SOH_C=>sc_node_attribute-zi_soi-addcharge )
( ZIF_I_SOH_C=>sc_node_attribute-zi_soi-currencycode ) ).
ev_static_action_failed = abap_false.
ENDLOOP.


endmethod.
ENDCLASS.

It is to be noted that whenever we create Action in BOPF it creates a Function Group in OData Service as shown below in Metadata.


Step 10: Invoking the Action from Front End

We will now implement the final changes in fiori app to trigger the backend static action ZC_SOISet_add_chrg for this we will use Invoke API.

Below is the code for the same.


Below is the final code of the Controller.
sap.ui.controller("fe.so.fesaleorder.ext.controller.ObjectPageExt", {
onInit: function () {

var oJson = new sap.ui.model.json.JSONModel({
"ExtraChrg": []
});

var oExtraChrg = [];
var oCharges = {
"ChargeType": "Freight",
"Amount": 0,
};

oExtraChrg.push(JSON.parse(JSON.stringify(oCharges)));

oCharges.ChargeType = "Miscellaneous Charge";
oExtraChrg.push(JSON.parse(JSON.stringify(oCharges)));

oCharges.ChargeType = "Other Charge";
oExtraChrg.push(JSON.parse(JSON.stringify(oCharges)));
this.getOwnerComponent().setModel(oJson, "Charge");
this.getOwnerComponent().getModel("Charge").setProperty("/ExtraChrg", oExtraChrg);

},

getAdditionalCharge: function (oEvent) {
debugger;
// Below is how we get the ID of the Item table
this._oTable = this.getView().byId(oEvent.getSource().getParent().getParent().getParent().getId()).getTable();
this._oDetails = this.getView().getModel().getProperty(this._oTable.getSelectedContextPaths()[0]);
var u = oEvent.getSource().getModel("ui").getData();
if (u.editable === true || u.createMode === true) {
if (!this._DialogGenerate) {
this._DialogGenerate = sap.ui.xmlfragment("fe.so.fesaleorder.ext.fragment.extraCharge", this);
this.getView().addDependent(this._DialogGenerate);
}
this._DialogGenerate.open();
} else {
// var i = this._oResourceBundle.getText('@copyInfo');
sap.m.MessageBox.information("Changes Possible only in Create and Edit Mode");
}
},

onActionCancel: function () {
this._DialogGenerate.close();
this._DialogGenerate.destroy();
this.getView().removeDependent(this._DialogGenerate);
this._DialogGenerate = null;
},

onActionCopy: function (oEvent) {
var oPromise;
var that = this;
var oApi = this.extensionAPI;
var oParameter = {};
// Get Selected row in item table
var ochargeDet = sap.ui.getCore().byId("idChargeTable").getSelectedContextPaths();
var oTot = 0;
for (var i = 0; i < ochargeDet.length; i++) {
var oCharges = this.getOwnerComponent().getModel("Charge").getProperty(ochargeDet[i]);
oTot = parseFloat(oCharges.Amount) + oTot;
}
// ***************Implment Invoke Action after Creating Static BOPF Action*********
oParameter = {
"Draftuuid": this._oDetails.Soitmkey,
"Amount": oTot,
"Currency" : 'EUR'
};
oPromise = this.extensionAPI.invokeActions("ZC_SOH_CDS.ZC_SOH_CDS_Entities/ZC_SOISet_add_chrg", [],
oParameter);
oPromise.then(function (r) {
that.getView().getModel().refresh(true, false, "CopyRefresh");
sap.m.MessageToast.show("Charges Added Successfully to Item" + that._oDetails.Soitm);

});
oPromise.catch(function (r) {
var E = jQuery.parseJSON(r[0].error.response.responseText);
sap.m.MessageBox.error(E.error.message.value);
});

this.onActionCancel();
}

});

Let us test the application as follows.

We click on Create Sales Order


We create item



Click on Addtional Charges Button by selecting item.





Conclusion:

So the conclusion is we can implement any custom actions in Fiori Elements by Invoking Actions in BOPF. By using the Combination of BOPF , Fiori Elements and Extensions in List Report.

 

Annexure:

Please Refer to below link in order to understand ABAP Programming model for Fiori.

About ABAP Programming Model for SAP Fiori - SAP Help Portal

Please refer to below link to Understand the concept of BOPF

Navigating the BOPF: Part 1 – Getting Started | SAP Blogs

Navigating the BOPF: Part 2 – Business Object Overview | SAP Blogs

Navigating the BOPF: Part 3 – Working with the BOPF API | SAP Blogs

Navigating the BOPF: Part 4 – Advanced BOPF API Features | SAP Blogs

Navigating the BOPF: Part 5 – Enhancement Techniques | SAP Blogs

Navigating the BOPF: Part 6 – Testing & UI Integration | SAP Blogs

 

Please share your thoughts and views after trying the same.

 

Thanks!!
2 Comments
Labels in this area