In this blog, I will show you how to create a CRM Service Order Fiori application within just a couple of minutes. You don’t need to write even one line of JavaScript code to get this responsive application.
Main function of this Fiori application
(1) There is a list which shows overview of Service orders in CRM system. You can search by Service Order and order description in search field.
(2) By clicking the setting icon, you can make more table columns visible in the table:
Example: Additional two columns are exposed.
Example: Sort by Posting date in ascending order
Example: Group by Order Status:
(3) Select any table row, you can navigate to Service Order detail page:
You can click corresponding tab to reach each detail page area:
Keep in mind, you DO NOT NEED to write any JavaScript code to make the above functionalities work. Please note that service order change and save are not supported in this application yet.
【Update on 2016-04-10】: Update function is available now. Please refer to this blog for detail: Enable CRM Service Order application with edit functionality.
Prerequisite of this solution
(1) SAP Web IDE 1.17 (includes OData Annotation Modeler as an available plug-in) (2) SAP Netweaver 7.5 SP01 (3) You need to have some basic knowledge on CDS view. Here is the documentation of CDS view in SAP help (4) You need to have some basic knowledge on UI5 Smart template. This is documentation in SAP help: Developing Apps with Smart Templates
Implementation steps
The overall development process would be:
(1) Most of the effort could be the CDS view implementation. Those views are responsible to return necessary data to UI frontend.
(2) The corresponding OData service is automatically generated when you activated your CDS view.
(3) Then you can use WebIDE Smart template generation wizard to generate the Fiori application on top of the automatically generated OData service.
The following entities must be created in ABAP development studio.
You can just paste the source code of each entity into ABAP development studio and activate them one by one.
Z_C_Status_Text
For example, create a new CDS view in ABAP development studio and paste the following source code,
@AbapCatalog.sqlViewName: 'zstatustext'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'system status code and description'
define view Z_C_Status_Text as select from tj02 inner join tj02t as _tj02t on
tj02.istat = _tj02t.istat and _tj02t.spras = 'E'
{
key tj02.istat,
_tj02t.txt04,
_tj02t.txt30
}
then click activate button:
Z_I_Prod_Status
@AbapCatalog.sqlViewName: 'zprdstatus'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'product guid and status code'
define view Z_I_Prod_Status as select from crmd_product_i
inner join crm_jest as _status on crmd_product_i.guid = _status.objnr
inner join Z_C_Status_Text as _text on _status.stat = _text.istat
{
key crmd_product_i.guid,
_status.stat,
_text.txt04,
_text.txt30
}
where _status.inact = '' and _status.stat like 'I%' and _status.stat <> 'I1030';
Z_I_Item_Detail
@AbapCatalog.sqlViewName: 'zitemdetail'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'item detail'
define view Z_I_Item_Detail as select from crmd_orderadm_i
inner join crmd_schedlin as _schedule
on crmd_orderadm_i.guid = _schedule.item_guid
inner join crmd_product_i as _prod on crmd_orderadm_i.guid = _prod.guid
inner join Z_I_Prod_Status as _prd_status
on crmd_orderadm_i.guid = _prd_status.guid
{
key crmd_orderadm_i.guid,
key crmd_orderadm_i.header,
@UI.lineItem : [{position:10, label : 'Item Number'}]
crmd_orderadm_i.number_int,
@UI.lineItem : [{position:20, label : 'Product Name'}]
crmd_orderadm_i.description,
@UI.lineItem : [{position:30, label : 'Quantity'}]
_schedule.quantity,
@UI.lineItem : [{position:40, label : 'Unit'}]
_prod.process_qty_unit as unit,
_prd_status.stat,
_prd_status.txt04,
@UI.lineItem : [{position:50}]
_prd_status.txt30
}
Z_C_Order_Item
@AbapCatalog.sqlViewName: 'zorderitem'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'order item detail'
define view Z_C_Order_Item as select from crmd_orderadm_h
inner join crmc_proc_type as _type on crmd_orderadm_h.process_type =
_type.process_type and _type.object_type = 'BUS2000116'
association [0..*] to Z_I_Item_Detail as _Item
on $projection.guid = _Item.header
{
key crmd_orderadm_h.guid,
key crmd_orderadm_h.object_id,
crmd_orderadm_h.description,
crmd_orderadm_h.posting_date,
@ObjectModel.association.type: #TO_COMPOSITION_CHILD
_Item
}
Zorder_Sys_Status
@AbapCatalog.sqlViewName: 'zsystatus'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'system status'
define view Zorder_Sys_Status as select from crmd_orderadm_h
inner join crm_jest as _crm_jest on crmd_orderadm_h.guid = _crm_jest.objnr
inner join Z_C_Status_Text as _status_text on _crm_jest.stat = _status_text.istat
{
key crmd_orderadm_h.guid,
key _crm_jest.stat,
_status_text.txt04,
_status_text.txt30
}
/*where _crm_jest.inact = '' and _crm_jest.stat like 'I%' and _crm_jest.stat <> 'I1030' // has error
and _crm_jest.stat <> 'I1026'; // do not transfer*/
where _crm_jest.inact = '' and ( _crm_jest.stat = 'I1003' or
_crm_jest.stat = 'I1003' or _crm_jest.stat = 'I1005' )
/*I1002 open
I1003 in process
I1005 complete*/
Z_c_partner
@AbapCatalog.sqlViewName: 'zcpartner'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'partner detail'
define view Z_c_partner as select from crmd_orderadm_h
inner join crmd_link as _link on crmd_orderadm_h.guid = _link.guid_hi and _link.objtype_hi = '05'
and _link.objtype_set = '07'
inner join ztf_bp_detail( clnt: '001') as _bp on _link.guid_set = _bp.partset_guid
{
key crmd_orderadm_h.guid,
--_link.objtype_hi as header_type,
--_link.objtype_set as item_type,
_bp.bp_guid,
_bp.partner_no,
_bp.name,
case _bp.title
when '0001' then 'Ms.'
when '0002' then 'Mr.'
when '0003' then 'Company'
when '0004' then 'Mr and Mrs'
else 'Unknown'
end as title
}
ztf_BP_DETAIL
@ClientDependent: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
define table function ztf_BP_DETAIL
with parameters @Environment.systemField: #CLIENT
clnt:abap.clnt
returns { client:s_mandt;
partner_guid:BU_PARTNER_GUID;
partset_guid:CRMT_OBJECT_GUID;
partner_no: CRMT_PARTNER_NO;
bp_guid: BU_PARTNER_GUID;
title:AD_TITLE;
name: BU_NAME1TX;
}
implemented by method
zcl_amdp_bp_detail=>crmd_partner_but000;
zcl_amdp_bp_detail
CLASS zcl_amdp_bp_detail DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
CLASS-METHODS crmd_partner_but000 FOR TABLE FUNCTION ztf_bp_Detail.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_amdp_bp_detail IMPLEMENTATION.
METHOD crmd_partner_but000
BY DATABASE FUNCTION FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING crmd_partner but000.
RETURN SELECT sc.client as client,
sc.partner_guid as partner_guid,
sc.guid as partset_guid,
sc.partner_no as partner_no,
sp.partner_guid as bp_guid,
sp.title as title,
sp.name1_text as name
FROM crmd_partner AS sc
INNER JOIN but000 AS sp ON sc.client = sp.client AND
sc.partner_no = sp.partner_guid
WHERE sc.client = :clnt AND
sc.partner_fct = '00000001'
ORDER BY sc.client;
ENDMETHOD.
ENDCLASS.
For CDS table function and AMDP implementation, please read this blog My CDS view self study tutorial – Part 6 consume table function in CDS view for more detail.
Z_i_Order_View
@AbapCatalog.sqlViewName: 'ziorder'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'order consumption view'
define view Z_i_Order_View as select from Z_C_Order_Item
inner join Zorder_Sys_Status as _sys_status
on Z_C_Order_Item.guid = _sys_status.guid
inner join Z_c_partner as _partner
on Z_C_Order_Item.guid = _partner.guid
{
key Z_C_Order_Item.guid as order_guid,
Z_C_Order_Item.object_id,
Z_C_Order_Item.description,
Z_C_Order_Item.posting_date,
_partner.name,
_partner.partner_no,
_partner.title,
_sys_status.stat,
_sys_status.txt04,
_sys_status.txt30,
@ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
Z_C_Order_Item._Item
}
Z_C_Service_Order_View
@AbapCatalog.sqlViewName: 'zcorderview'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'service order consumption view'
@Search.searchable: true
@OData.publish: true
@ObjectModel: {
type: #CONSUMPTION,
compositionRoot,
createEnabled,
deleteEnabled,
updateEnabled
}
@UI.headerInfo:{
typeName: 'Service Order',
typeNamePlural: 'Service Orders',
title: { value: 'object_id' },
description: { value: 'description' }
}
define view Z_C_Service_Order_View as select from Z_i_Order_View {
key Z_i_Order_View.order_guid as order_guid,
@UI.lineItem : [{position:10, label : 'Service Order ID'}]
// @UI.identification: [ { position: 10 } ]
@UI.selectionField: [ { position: 20, label : 'Service Order ID' } ]
Z_i_Order_View.object_id,
@UI.lineItem : [{position:20, label : 'Description'}]
//@UI.identification: [ { position: 20 } ]
@Search:{ defaultSearchElement: true, ranking: #HIGH, fuzzinessThreshold: 0.8 }
//@UI.selectionField: { position: 4, element: '_ProductCategory.MainProductCategory' }
@UI.selectionField: [ { position: 10, label : 'Description' } ]
Z_i_Order_View.description,
Z_i_Order_View.partner_no,
Z_i_Order_View.title,
@UI.identification: [ { position: 20 } ]
Z_i_Order_View.posting_date,
@UI.lineItem : [{position:30, label : 'Account'}]
@UI.identification: [ { position: 30, label : 'Account' } ]
Z_i_Order_View.name,
Z_i_Order_View.stat,
Z_i_Order_View.txt04,
@UI.lineItem : [{position:40}]
@UI.identification: [ { position: 40 } ]
Z_i_Order_View.txt30,
@ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
Z_i_Order_View._Item
}
Once you have activated all the CDS view entities, follow the steps described in this blog Step by Step to create CDS view through SmartTemplate + WebIDE, and you will get the working Service order application immediately.
Further reading
If you have a look at the automatically generated project in WebIDE, you will find that now there is no application specific view or controllers. Only Component.js exists with a few dummy code below. The UI5 runtime takes over everything for you to make the application work.
It means your trouble shooting will become more struggled in case you meet with isuse, since now the whole scenarios works as a black box for you. As a result it is of great importance for developers to understand what occurs under the hood.
CDS view self study
The following posts are written by me during my self-study on CDS view:
- Part1 – how to test odata service generated by CDS view
- Part2 – what objects are automatically generate after you activate one CDS view
- Part3 – how is view source in Eclipse converted to ABAP view in the backend
- Part4 – how does annotation @OData.publish work
- Part5 – how to create CDS view which supports navigation in OData service
- Part6 – consume table function in CDS view
- Part7 – unveil the secret of @ObjectModel.readOnly
- Part8 – my summary of different approaches for annotation declaration and generation
- Part9 – cube view and query view
- Part10 – How does CDS view key user extensibility work in S4/HANA
- Part11 – CDS view test double framework
- Part12 – CDS view source code count tool
- Part13 – CDS view authorization
- Part14 – CDS view performance analysis using PlanViz in HANA studio
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
相关推荐
### SAP Fiori APP 应用快速实施解决办法 #### 一、引言 SAP Fiori 是一种全新的用户界面设计原则和技术框架,旨在为用户提供直观、简洁和一致的体验。本文档将详细介绍如何通过手动配置步骤或使用预定义任务列表...
### SAP Fiori 快速指南知识点详述 #### 一、SAP Fiori 简介 SAP Fiori 是一款由 SAP 开发的新用户体验(UX),旨在为用户提供直观、简洁的操作界面。它包含了300多个基于角色的应用程序,覆盖了人力资源、制造、...
在企业信息化管理领域,SAP S/4HANA是一款先进的企业资源规划系统,它结合了现代化的用户体验设计,也就是Fiori,为用户提供简洁、直观的交互界面。本篇文章将详细探讨SAP S/4HANA Fiori的配置过程以及简单的权限...
SAP fiori的简易开发过程指南,从开发者角度出发,分后面ODATA开发环境和前端SAP UI5环境搭建,以及发布进行了讲解
SAP Fiori配置手册 本配置手册旨在指导用户完成SAP Fiori的设置和配置,从而...本手册涵盖了SAP Fiori的配置和设置,从创建管理员账号和测试账号到激活SAP Fiori Launchpad,旨在帮助用户快速和正确地配置SAP Fiori。
SAP Fiori 快速启动板使用指南 SAP Fiori 快速启动板是 SAP Fiori 应用的外壳,为应用提供导航、个性化、嵌入支持和应用程序配置等服务。它是 SAP Fiori 应用在移动和桌面设备上的入口点。 快速启动板的组成部分 ...
SAP Fiori 应用程序超过300个,每个都经过精心设计,以确保用户能够快速、轻松地完成工作,无论他们是在桌面、智能手机还是平板电脑上使用。 SAP Fiori 的设计灵感来源于意大利语中的“花”,象征着它的多样性与...
- SAP Fiori 2.0 引入了一个强大的工具,允许系统管理员轻松定制主题和样式。这有助于保持企业品牌的一致性,并提高用户体验。 #### 对开发者重要的变化 ##### 1. **SAP Fiori 2.0 标题栏** - **启用自动 SAP ...
UI5-FIORI 是一个功能强大且灵活的开发环境,旨在帮助开发者快速搭建和测试 Fiori 应用程序。通过本文档,开发者可以快速了解 UI5-FIORI 的安装和配置、基本设置、Gateway 测试和 UI5 开发等内容,并快速开始 Fiori ...
### SAP Fiori Launchpad配置指南 #### 一、引言 SAP Fiori Launchpad作为移动和...SAP Fiori Launchpad及其配置工具Launchpad Designer为用户提供了一个强大而灵活的应用程序入口,极大地提高了工作效率和用户体验。
Session 1: Introduction to SAPUI5 / FIORI (40 mins) ▫ Basic MVC concept: Model, View, Controller ▫ UI5 Control libraries • Session 2: Introduction to SAP Web IDE (20 mins) • Hands on 1: Build your...
SAP Fiori 是 SAP 软件和应用程序的新用户体验(UX)。 它提供了一组应用程序,用于常规业务功能,如工作批准,金融应用程序,计算应用程序和各种自助服务应用程序。
8. **SAP HANA Cloud Platform (HCP)**:HCP提供了一个云环境,支持Fiori应用的快速部署和扩展。了解如何在HCP上设置和管理服务,可以加速应用的上线和更新。 9. **SAP Fiori 应用生命周期管理 (ALM)**:包括版本...
SAP Fiori 是 SAP 软件和应用程序的新用户体验(UX),提供了一组应用程序,用于常规业务功能,如工作批准,金融应用程序,计算应用程序和各种自助服务应用程序。SAP Fiori 提供 300 多个基于角色的应用程序,如人力...
SAP Fiori是一种创新的用户界面(UI)设计和交付...综上所述,SAP Fiori是企业IT领域的一个重要里程碑,它通过重新定义用户界面,使得企业应用程序变得更加用户友好,无论是在功能上还是在用户体验上都实现了质的飞跃。
SEGW是SAP中的一个工具,全称为Service Enablement Workbench,它是SAP NetWeaver的一部分。SEGW工具的用途是为现有SAP系统中的BAPI(Business Application Programming Interface,业务应用编程接口)或者RFC...
SAP Fiori 是 SAP 软件和应用程序的新用户体验(UX),提供了一组应用程序,用于常规业务功能,如工作批准,金融应用程序,计算应用程序和各种自助服务应用程序。SAP Fiori 提供了 300 多个基于角色的应用程序,如...
内容概要:该文件详细介绍了用于支持SAP Fiori应用开发的ABAP编程模型的关键要素及其应用场景。这涵盖了如何利用核心数据服务(CDS)定义丰富的语义模型以及OData协议的应用方法。主要内容包括如何将不同组件集成到...
SAP Fiori Launchpad是SAP Fiori用户界面的启动平台,它为最终用户提供一个个性化、角色基础的入口,可以访问各种SAPUI5应用。Fiori Launchpad可以基于SAP Netweaver、SCP等环境部署。 7. SAPUI5版本 SAPUI5的版本...