这个例子中使用ABAP RESTful Application Programming Model开发一个ODATA服务,前端使用WEBIDE创建 一个SAPUI5程序 并发布到SAP中。
功能如图
其中使用到如下功能,
- 使用define root custom entity创建一个自定义查询功能CDS;
- CDS查询时调用自定义类方法实现自由查询返回数据;
- CDS查询中插入数据;
- 实现RAP的behavior中的Actions方法,并在WEB中调用些方法(删除,领料);
- 在SAPUI5中设置最新行高亮显示,使用SAP UI5 的表达式绑定(expression binding)实现;
- SAPUI5中使用callFunction调用CDS的ACTION,此方法也可调用SEGW中创建 的方法及BOPF中定义的ACTION.
- SAPUI5中过滤器 filter 的开发和使用,在查询后判断查询是否成功
- SAPUI5中支付扫码输入查询
1.创建CDS
其中的注释一开始是打算使用SAP Fiori Elements开发的,但后期发现一些细节实现不也,所以就改用SAPUI5 freestyle开发了,所以这里的注释没用使用。在这里用类ZCL_CONSIGN_SALE_QUERY来定义查询,这里定义的两个ACTION,后下一步中实现 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
@EndUserText.label: 'WEB寄售领用' @ObjectModel.query.implementedBy: 'ABAP:ZCL_CONSIGN_SALE_QUERY' @Search.searchable: true @Metadata.allowExtensions: true @UI.lineItem: [{criticality: 'ZTSC'}] //行颜色标记 @UI.headerInfo: { typeName: '寄售信用' ,//列表报告中的应用程序标头 title: { value: 'LENUM', //- Reference to element in element list type: #STANDARD }, description: { label: '物料编号', value: 'LENUM' // Reference to element in element list } } define root custom entity ZI_CONSIGN_SALE { @UI.facet: [ { // label: '',//结果 id : 'HeaderResurt', type : #FIELDGROUP_REFERENCE ,//#FIELDGROUP_REFERENCE, purpose:#HEADER, targetQualifier : 'HeaderResurt', position:10 }, { // label: '',//单据信息 id : 'HeaderDj', type : #FIELDGROUP_REFERENCE ,//#FIELDGROUP_REFERENCE, purpose:#HEADER, targetQualifier : 'HeaderDj', position:20 } ] @UI.lineItem: [ { type: #FOR_ACTION, dataAction: 'ZDELETE_ALL', label: '删除', position: 10 }, { type: #FOR_ACTION, dataAction: 'ZCREATE_LYD', label: '创建领用', position:20 } ] key LLSQD : zewmltlsqd; @UI.identification: [{ position: 10, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 10 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 10 } ] key LLPOS : zewmposnr; ZLYDH : zewmltlsqd;//生成的领用单号 @UI.identification: [{ position: 20 } ] //细节时显示在20 @UI.lineItem:[{position: 20 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 20 } ] STAT : zlm_stat;//删除标记 LLTYP : zewmllfs; @Search.defaultSearchElement: true @UI.identification: [{ position: 15, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 15 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 15 } ] LENUM : char20; @UI.identification: [{ position: 30, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 30 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 30 } ] WERKS : werks_d; @UI.identification: [{ position: 40, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 40 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 40 } ] GR_TYPE : zgr_type; @UI.identification: [{ position: 50, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 50 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 50 } ] GR_DATE : zgr_date; @UI.identification: [{ position: 60, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 60 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 60 } ] GR_MONTH : num6; @UI.identification: [{ position: 70, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 70 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 70 } ] MATNR : matnr; @UI.identification: [{ position: 80, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 80 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 80 } ] CHARG : charg_d; ZTSC : int1;//状态颜色 @Semantics.quantity.unitOfMeasure : 'unit_net' @UI.identification: [{ position: 90, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 90 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 90 } ] NET_WEIGHT : znet_weight; @UI.identification: [{ position: 100, importance: #HIGH } ] //细节时显示在20 @UI.lineItem:[{position: 100 }]//列表时显示在第60 @UI.fieldGroup: [{ qualifier: 'HeaderDj',position: 100 } ] UNIT_NET : zunit_net; } |
CDS查询类ZCL_CONSIGN_SALE_QUERY
创建类ZCL_CONSIGN_SALE_QUERY,其中接口引入IF_RAP_QUERY_PROVIDER,并实现IF_RAP_QUERY_PROVIDER~SELECT方法,并在其中读取数据。其中字段ZTSC用来标记当前行(最新行),在SAPUI5前端为来记录最新的数据。据说,这里应该不能使用COMMIT,不过,我是查询所以应该不影响。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
METHOD IF_RAP_QUERY_PROVIDER~SELECT. DATA: LS_DATA TYPE ZI_CONSIGN_SALE, LT_DATA TYPE TABLE OF ZI_CONSIGN_SALE. DATA: L_LENUM TYPE ZLENUM."输入包装号 DATA: L_ACTION TYPE FLAG, L_CONSIGN_DELETE TYPE FLAG. DATA(LT_REQ_ELEMENTS) = IO_REQUEST->GET_REQUESTED_ELEMENTS( ). * BREAK YANGSEN. IF IO_REQUEST->IS_DATA_REQUESTED( ). DATA(LV_TOP) = IO_REQUEST->GET_PAGING( )->GET_PAGE_SIZE( ). IF LV_TOP < 0. LV_TOP = 1. ENDIF. DATA(LV_SKIP) = IO_REQUEST->GET_PAGING( )->GET_OFFSET( ). DATA(LT_SORT) = IO_REQUEST->GET_SORT_ELEMENTS( ). DATA : LV_ORDERBY TYPE STRING. LOOP AT LT_SORT INTO DATA(LS_SORT). IF LS_SORT-DESCENDING = ABAP_TRUE. LV_ORDERBY = |'{ LV_ORDERBY } { LS_SORT-ELEMENT_NAME } DESCENDING '|. ELSE. LV_ORDERBY = |'{ LV_ORDERBY } { LS_SORT-ELEMENT_NAME } ASCENDING '|. ENDIF. ENDLOOP. IF LV_ORDERBY IS INITIAL. LV_ORDERBY = 'LLPOS '. ENDIF. DATA(LV_CONDITIONS) = IO_REQUEST->GET_FILTER( )->GET_AS_SQL_STRING( ). DATA(LV_SEARCH_STRING) = IO_REQUEST->GET_SEARCH_EXPRESSION( ). L_LENUM = CL_ABAP_DYN_PRG=>ESCAPE_QUOTES( LV_SEARCH_STRING )."输入包装号 IF L_LENUM = '' . " l_LENUM = LV_CONDITIONS."从查询 条件中读取包装号 IF STRLEN( LV_CONDITIONS ) > 5. IF LV_CONDITIONS(5) = 'LENUM' . SPLIT LV_CONDITIONS AT '%' INTO DATA(V1) L_LENUM DATA(V2). ENDIF. ENDIF. ENDIF. IF L_LENUM <> '' ."表示 从ECC读取数据,并写到临时表, QUERY_LENUM_ECC( IV_LENUM = L_LENUM ). ENDIF. LV_CONDITIONS = |LLSQD = '$| && SY-UNAME && |'| ."读取所有当前用户号 SELECT FROM ZEWMTR0310 FIELDS * WHERE (LV_CONDITIONS) * ORDER BY (LV_ORDERBY) INTO CORRESPONDING FIELDS OF TABLE @LT_DATA UP TO @LV_TOP ROWS ."OFFSET lv_skip. SORT LT_DATA BY LLPOS DESCENDING. LOOP AT LT_DATA ASSIGNING FIELD-SYMBOL(<DATA>). SHIFT <DATA>-LENUM LEFT DELETING LEADING '0'. IF <DATA>-LENUM = L_LENUM."当前行 <DATA>-ZTSC = 3. ENDIF. ENDLOOP. IF IO_REQUEST->IS_TOTAL_NUMB_OF_REC_REQUESTED( ). "对象页时不需要指定记录数,当LT_REQ_ELEMENTS只有主银行时,在这里设置一下,就会调用明细类 IO_RESPONSE->SET_TOTAL_NUMBER_OF_RECORDS( LINES( LT_DATA ) ). ENDIF. IO_RESPONSE->SET_DATA( LT_DATA ). " DELETE LT_DATA WHERE NOT BUKRS = P_BUKRS. ELSE. IO_RESPONSE->SET_TOTAL_NUMBER_OF_RECORDS('0'). ENDIF. ENDMETHOD. |
1.1.类方法QUERY_LENUM_ECC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
METHOD QUERY_LENUM_ECC. DATA: LT_OPTIONS TYPE TABLE OF /BODS/RFC_DB_OPT. DATA: LT_DATA TYPE TABLE OF ZEWMTR0310, LS_DATA TYPE ZEWMTR0310. DATA: L_LLSQD TYPE ZEWMLTLSQD, L_LLPOS TYPE ZEWMPOSNR VALUE 0, L_LENUM TYPE ZLENUM10. L_LLSQD = '$' && SY-UNAME. L_LENUM = IV_LENUM. UPDATE ZEWMTR0310 SET ZTSC = 0 WHERE LLSQD = L_LLSQD. UPDATE ZEWMTR0310 SET ZTSC = 3"最新行 WHERE LLSQD = L_LLSQD AND LENUM = L_LENUM . IF SY-SUBRC = 0."包装号已存在,应该要返回消息已存在 RETURN. ENDIF. WHILE STRLEN( L_LENUM ) < 20."补0 L_LENUM = '0' && L_LENUM. ENDWHILE. LT_OPTIONS = VALUE #( ( TEXT = |LENUM = '{ L_LENUM }'| ) ). CALL FUNCTION 'ZFM_EWM_GET_ERP_DATA' EXPORTING IV_TABNAME = 'ZLMT00440' TABLES IT_OPTIONS = LT_OPTIONS ET_TAB = LT_DATA. READ TABLE LT_DATA INTO LS_DATA INDEX 1. IF SY-SUBRC <> 0."没取到值 。 RETURN. ENDIF. SHIFT LS_DATA-LENUM LEFT DELETING LEADING '0'."去除前导0 SELECT MAX( LLPOS ) INTO L_LLPOS FROM ZEWMTR0310 WHERE LLSQD = L_LLSQD. L_LLPOS = L_LLPOS + 1. LS_DATA-LLSQD = L_LLSQD. LS_DATA-LLPOS = L_LLPOS. LS_DATA-ZTSC = 3."最新行 MODIFY ZEWMTR0310 FROM LS_DATA. COMMIT WORK . DO 5 TIMES. SELECT SINGLE * INTO LS_DATA FROM ZEWMTR0310 WHERE LLSQD = L_LLSQD AND LLPOS = L_LLPOS . IF SY-SUBRC = 0. EXIT. ENDIF. WAIT UP TO 1 SECONDS. ENDDO. ENDMETHOD. |
2.创建behavior
在CDS上右键,选择NEW Behavior Defintion来创建一个behavior,在这里定义对应的ACTION,及对应的CLASS类zbp_i_consign_sale。其中定义了两上操作功能ACTION(ZDELETE_ALL,ZCREATE_LYD)在第一步的CDS中使用这两个ACTION.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
unmanaged implementation in class zbp_i_consign_sale unique; define behavior for ZI_CONSIGN_SALE //alias <alias_name> //late numbering //lock master //etag master <field_name> { delete; action ( features : instance ) ZDELETE_ALL result [1] $self; action ( features : instance ) ZCREATE_LYD result [1] $self; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
CLASS LHC_ZI_CONSIGN_SALE DEFINITION INHERITING FROM CL_ABAP_BEHAVIOR_HANDLER. PRIVATE SECTION. METHODS DELETE FOR MODIFY IMPORTING KEYS FOR DELETE ZI_CONSIGN_SALE. METHODS READ FOR READ IMPORTING KEYS FOR READ ZI_CONSIGN_SALE RESULT RESULT. METHODS ZDELETE_ALL FOR MODIFY IMPORTING KEYS FOR ACTION ZI_CONSIGN_SALE~ZDELETE_ALL. "RESULT RESULT. METHODS ZCREATE_LYD FOR MODIFY IMPORTING KEYS FOR ACTION ZI_CONSIGN_SALE~ZCREATE_LYD RESULT RESULT. METHODS GET_FEATURES FOR FEATURES IMPORTING KEYS REQUEST REQUESTED_FEATURES FOR ZI_CONSIGN_SALE RESULT RESULT. ENDCLASS. CLASS LHC_ZI_CONSIGN_SALE IMPLEMENTATION. METHOD DELETE. BREAK YANGSEN. DATA:LT_DATA TYPE TABLE OF ZEWMTR0310, LS_DATA TYPE ZEWMTR0310, LS_PARAM TYPE ZI_CONSIGN_SALE. LOOP AT KEYS INTO DATA(LS_KEYS) . DELETE FROM ZEWMTR0310 WHERE LLSQD = LS_KEYS-LLSQD AND LLPOS = LS_KEYS-LLPOS. ENDLOOP. ENDMETHOD. METHOD READ. ENDMETHOD. METHOD ZDELETE_ALL. " BREAK YANGSEN. DATA:LT_DATA TYPE TABLE OF ZEWMTR0310, LS_DATA TYPE ZEWMTR0310, LS_PARAM TYPE ZI_CONSIGN_SALE. SELECT * INTO TABLE LT_DATA FROM ZEWMTR0310 FOR ALL ENTRIES IN KEYS WHERE LLSQD = KEYS-LLSQD AND LLPOS = KEYS-LLPOS. SORT LT_DATA BY LLSQD LLPOS. LOOP AT KEYS INTO DATA(LS_KEYS) . DELETE FROM ZEWMTR0310 WHERE LLSQD = LS_KEYS-LLSQD AND LLPOS = LS_KEYS-LLPOS. IF SY-SUBRC <> 0. CLEAR:LS_DATA. READ TABLE LT_DATA INTO LS_DATA WITH KEY LLSQD = LS_KEYS-LLSQD LLPOS = LS_KEYS-LLPOS BINARY SEARCH. * APPEND INITIAL LINE TO RESULT ASSIGNING FIELD-SYMBOL(<RESULT>) . * <RESULT>-LLSQD = LS_KEYS-LLSQD. * <RESULT>-LLPOS = LS_KEYS-LLPOS. * MOVE-CORRESPONDING LS_DATA TO LS_PARAM. * LS_PARAM-STAT = '10'. * LS_PARAM-ZTSC = 1. * <RESULT>-%PARAM = LS_PARAM. APPEND VALUE #( LLSQD = LS_KEYS-LLSQD LLPOS = LS_KEYS-LLPOS %MSG = NEW ZCL_MESSAGEWRAPPER( TEXTID = ZCL_MESSAGEWRAPPER=>DELETE_ERROR SEVERITY = IF_ABAP_BEHV_MESSAGE=>SEVERITY-error ATTR1 = '111' ) %STATE_AREA = 'state_area' ) TO REPORTED-ZI_CONSIGN_SALE. APPEND VALUE #( LLSQD = LS_KEYS-LLSQD LLPOS = LS_KEYS-LLPOS ) TO FAILED-ZI_CONSIGN_SALE. ENDIF. ENDLOOP. ENDMETHOD. METHOD ZCREATE_LYD. BREAK YANGSEN. DATA: L_SUCC TYPE FLAG. LOOP AT KEYS INTO DATA(LS_KEYS) . * APPEND VALUE #( * LLSQD = LS_KEYS-LLSQD * LLPOS = LS_KEYS-LLPOS * %MSG = NEW ZCL_MESSAGEWRAPPER( * TEXTID = ZCL_MESSAGEWRAPPER=>CREATE_LY_SUCC * SEVERITY = IF_ABAP_BEHV_MESSAGE=>SEVERITY-success ** MESSAGE_VARIABLE = '111' * ) * %STATE_AREA = 'state_area' * ) * TO REPORTED-ZI_CONSIGN_SALE. * APPEND VALUE #( * LLSQD = LS_KEYS-LLSQD * LLPOS = LS_KEYS-LLPOS ) * TO MAPPED-ZI_CONSIGN_SALE. * L_SUCC = 'X'. ENDLOOP. READ ENTITIES OF ZI_CONSIGN_SALE IN LOCAL MODE ENTITY ZI_CONSIGN_SALE ALL FIELDS WITH CORRESPONDING #( KEYS ) RESULT DATA(LT_DATA). *1.创建领用单, L_SUCC = 'X'. *2。失败报错。 IF L_SUCC <> 'X'. RETURN. ENDIF. *3。成功删除表内容 IF L_SUCC = 'X'. APPEND VALUE #( * LLSQD = LS_KEYS-LLSQD * LLPOS = LS_KEYS-LLPOS %TKY = LS_KEYS-%TKY %MSG = NEW ZCL_MESSAGEWRAPPER( TEXTID = ZCL_MESSAGEWRAPPER=>CREATE_LY_SUCC SEVERITY = IF_ABAP_BEHV_MESSAGE=>SEVERITY-SUCCESS ATTR1 = '111' ) %STATE_AREA = 'VALIDATE_CUSTOMER' ) TO REPORTED-ZI_CONSIGN_SALE. * APPEND VALUE #( * LLSQD = LS_KEYS-LLSQD * LLPOS = LS_KEYS-LLPOS ) * TO FAILED-ZI_CONSIGN_SALE. * DELETE FROM ZEWMTR0310 WHERE LLSQD = LS_KEYS-LLSQD. ENDIF. ENDMETHOD. METHOD GET_FEATURES. ENDMETHOD. ENDCLASS. CLASS LSC_ZI_CONSIGN_SALE DEFINITION INHERITING FROM CL_ABAP_BEHAVIOR_SAVER. PROTECTED SECTION. METHODS CHECK_BEFORE_SAVE REDEFINITION. METHODS FINALIZE REDEFINITION. METHODS SAVE REDEFINITION. ENDCLASS. CLASS LSC_ZI_CONSIGN_SALE IMPLEMENTATION. METHOD CHECK_BEFORE_SAVE. ENDMETHOD. METHOD FINALIZE. ENDMETHOD. METHOD SAVE. ENDMETHOD. ENDCLASS. |
3.创建define service
在package上左右新建立
1 2 3 4 |
@EndUserText.label: '寄售信用服务' define service Zconsign_sale_u { expose ZI_CONSIGN_SALE as sale; } |
4.创建Service Binding
选择上一步中的Define service,右键建立 一个OData V2 – UI的服务绑定ZCONSIGN_SALE_UI_V2,并发布。
5.SAP Fiori Elements开发完成
到这里我们就可以在上一步图中点击 OPEN Preview for Fiori Elements App,来浏览FIORI APP了,但些细节不满意,比如输入一个号查询后查询不到数据不能提示,查询后不能删除查询(后期点击删除功能会再次使用这里的数据再查询,结果就不对了)。所以后面改用SAPUI5 freestyle来自定义开发。
6.SAPUI5前端开发
我使用的是WEBIDE,使用模板SAP Fiori Master-Detail Applaction 选择前面服务生成 的ODATA(ZCONSIGN_SALE_UI_V2),来创建一个新的APP,然后修改MASTER的XML,JS文件,
Master.view.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:ndc="sap.ndc" controllerName="sap.consign.sale.view.Master" displayBlock="true"> <Page id="master1Page" title="{i18n>master1Title}"> <subHeader> <Bar id="master1SearchBar"> <contentMiddle> <SearchField id="master1SearchField" showRefreshButton="{device>/isNoTouch}" placeholder="{i18n>master1SearchPlaceholder}" search="onSearch" tooltip="{i18n>master1SearchTooltip}" width="100%"/> <ndc:BarcodeScannerButton id="sampleBarcodeScannerButton" scanSuccess="onScanSuccess" scanFail="onScanError" inputLiveUpdate="onScanLiveupdate" dialogTitle="Barcode Scanner Button Sample" class="sampleBarcodeScannerButtonWithZebraEB"/> </contentMiddle> </Bar> </subHeader> <content> <List id="master1List" width="auto" items="{/sale}" noDataText="{listView>/noDataText}" growing="true" growingScrollToLoad="true" busyIndicatorDelay="{masterView>/delay}" rememberSelections="false" mode="MultiSelect"> <items> <ObjectListItem id="_IDGenObjectListItem1" intro="{WERKS}-{MATNR}" title="{LENUM}" number="{NET_WEIGHT}" numberUnit="{UNIT_NET}" highlight="{= ${ZTSC} === 3 ? 'Success' : 'None' }" numberState="{= ${NET_WEIGHT} < 1000 ? 'Error' : 'None' }" > </ObjectListItem> </items> </List> </content> <footer> <Toolbar> <content> <Button text="删除" width="130px" id="ZDELETE" type="Reject" press="onZDELETE" icon="sap-icon://delete"/> <sap.ui.core:ComponentContainer xmlns:sap.ui.core="sap.ui.core" width="100%" id="__container0"/> <Button text="领料" width="130px" id="__button1" type="Accept" press="onZCREATE_LYD" icon="sap-icon://accept"/> </content> </Toolbar> </footer> <headerContent> <Button width="40px" id="__button0" icon="sap-icon://multiselect-all" press="onMultiSelectPress"/> </headerContent> </Page> </mvc:View> |
Master.controller.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
sap.ui.core.mvc.Controller.extend("sap.consign.sale.view.Master", { onInit: function() { this.oInitialLoadFinishedDeferred = jQuery.Deferred(); var oEventBus = this.getEventBus(); this.GallSelected = ""; this.getView().byId("master1List").attachEventOnce("updateFinished", function() { this.oInitialLoadFinishedDeferred.resolve(); oEventBus.publish("Master", "InitialLoadFinished", { oListItem: this.getView().byId("master1List").getItems()[0] }); this.getRouter().detachRoutePatternMatched(this.onRouteMatched, this); }, this); //On phone devices, there is nothing to select from the list. There is no need to attach events. if (sap.ui.Device.system.phone) { return; } }, onRouteMatched: function(oEvent) { var sName = oEvent.getParameter("name"); if (sName !== "main") { return; } //Load the welcome view in desktop this.getRouter().myNavToWithoutHash({ currentView: this.getView(), targetViewName: "sap.consign.sale.view.Welcome", targetViewType: "XML" }); }, waitForInitialListLoading: function(fnToExecute) { jQuery.when(this.oInitialLoadFinishedDeferred).then(jQuery.proxy(fnToExecute, this)); }, onNotFound: function() { this.getView().byId("master1List").removeSelections(); }, onSearch: function() { // Add search filter var L_SUCC = ''; var filters = []; var searchString = this.getView().byId("master1SearchField").getValue(); // if (searchString && searchString.length > 0) { filters = [new sap.ui.model.Filter("LENUM", sap.ui.model.FilterOperator.Contains, searchString)]; // } // Update list binding this.getView().byId("master1List").getBinding("items").filter(filters); if(searchString === ""){return;} //判断是否有取到输入的包装号,新输入的在这取不到。 this.getView().getModel().read("/sale", { success:function(oResultData, oResponse){ for(var I in oResultData.results){ var L_LENUM = oResultData.results[I].LENUM; if( L_LENUM === searchString ){ L_SUCC = "X"; break; } } if(L_SUCC !== "X"){ sap.m.MessageToast.show( "输入的包装号不存在"); } }, filters:filters }); /* var _omodel = this.getView().getModel(); var odata = _omodel.oData; for( var item in odata){ var L_LENUM = odata.valueOf()[item].LENUM; if( L_LENUM == searchString ){ L_SUCC = "X"; } }; if(L_SUCC !== "X"){ sap.m.MessageToast.show( "输入的包装号不存在"); }; */ //系统查询完全后,会记录最后一次查询 的条件,当ACTION时,会使用些条件再次执行查询 ,所以为在这里用空条件再查询一次 //或者考虑在查询时设置REQUEST的查询参数为空(ABAP没找到参数) this.getView().byId("master1SearchField").setValue(""); filters = [new sap.ui.model.Filter("LENUM", sap.ui.model.FilterOperator.Contains, "")]; this.getView().byId("master1List").getBinding("items").filter(filters); }, onSelect: function(oEvent) { // Get the list item either from the listItem parameter or from the event's // source itself (will depend on the device-dependent mode) var oList = this.getView().byId("master1List"); this.showDetail(oEvent.getParameter("listItem") || oEvent.getSource()); oList.removeSelections(); }, showDetail: function(oItem) { // If we're on a phone device, include nav in history }, getEventBus: function() { return sap.ui.getCore().getEventBus(); }, getRouter: function() { return sap.ui.core.UIComponent.getRouterFor(this); }, onExit: function(oEvent) { }, onMultiSelectPress: function(oEvent) { var _olist = this.byId("master1List"); var bSelected = this.GallSelected; if (bSelected) { _olist.removeSelections(); //MessageToast.show("MultiSelect Pressed"); this.GallSelected = ""; } else { _olist.selectAll(); this.GallSelected = "X"; // MessageToast.show("MultiSelect Unpressed"); } }, onRefresh: function () { this.getView().byId("master1List").getBinding("items").refresh(); }, onZDELETE:function(){ // var that = this; var _omodel = this.getView().getModel(); var odata = []; var respodata = []; var _olist = this.byId("master1List"); var items = _olist.getSelectedItems(); if(items.length < 1){ sap.m.MessageToast.show( "请选择要删除的行"); return; } // 在这里组装出需要删除的数据。 for (var i = 0; i < items.length; i++) { var item = items[i]; var context = item.getBindingContext(); var obj = context.getProperty(null, context); // odata[i].LLSQD = obj.LLSQD; // odata[i].LLPOS = obj.LLPOS; _omodel.callFunction("/ZDELETE_ALL",{ "method": "POST", urlParameters: {"LLSQD": obj.LLSQD, "LLPOS": obj.LLPOS}, // function import parameters success: function(oData, response) { // sap.m.MessageToast.show("删除成功"); that._fnDelProessSucc(oData); }, // callback function for success error: function(oError){ that._fnDelProessError(oError); } }); // callback function for error } }, onZCREATE_LYD:function(){ // var that = this; var _omodel = this.getView().getModel(); var odata = []; var respodata = []; var _olist = this.byId("master1List"); var items = _olist.getItems(); if(items.length < 1){ sap.m.MessageToast.show( "没有需要创建的行"); return; } // 在这里组装出需要删除的数据。 var i = 1; var item = items[0]; var context = item.getBindingContext(); var obj = context.getProperty(null, context); // odata[i].LLSQD = obj.LLSQD; // odata[i].LLPOS = obj.LLPOS; _omodel.callFunction("/ZCREATE_LYD",{ "method": "POST", urlParameters: {"LLSQD": obj.LLSQD, "LLPOS": obj.LLPOS}, // function import parameters success: function(oData, response) { // sap.m.MessageToast.show("删除成功"); that._fnCreProessSucc(oData); }, // callback function for success error: function(oError){ that._fnCreProessError(oError); } }); // callback function for error }, _fnDelProessSucc: function(oData) { var oModel = this.getView().getModel(); // this.getView().getModel()._refresh(); sap.m.MessageToast.show( "删除成功:"); this.onSearch(); }, _fnDelProessError: function(oError) { // this.getModel("appView").setProperty("/busy", false); sap.m.MessageToast.error(oError); }, _fnCreProessSucc: function(oData) { var oModel = this.getView().getModel(); // this.getView().getModel()._refresh(); sap.m.MessageToast.show( "领料成功:"); this.onSearch(); }, fnCreProessError: function(oError) { // this.getModel("appView").setProperty("/busy", false); sap.m.MessageToast.MessageBox.error(oError); }, onScanSuccess: function(oEvent) { var oScanSearch = this.getView().byId("master1SearchField"); if (oEvent.getParameter("cancelled")) { sap.m.MessageToast.show("Scan cancelled", { duration:1000 }); oScanSearch.setValue("Scan cancelled"); return; } else { if (oEvent.getParameter("text")) { oScanSearch.setValue(oEvent.getParameter("text")); } else { oScanSearch.setValue("Scan NULL"); return; } } this.onSearch(); oScanSearch.setValue(""); var ScannerButton = this.getView().byId("sampleBarcodeScannerButton"); //ScannerButton.click(); }, onScanError: function(oEvent) { sap.m.MessageToast.show("Scan failed: " + oEvent, { duration:1000 }); } }); |
7.SAPUI5说明
- 在XML文件中ObjectListItem的高亮属性highlight,使用表达式绑定(expression binding)实现,代码 :”{= ${ZTSC} === 3 ? ‘Success’ : ‘None’ }”, 表示 当ODATA当前VIEW的ZTSC字段值为3时,高亮为成功(Success ,绿色),否则无色。理多的例子代码 可参看这里。
- 使用扫码对象BarcodeScannerButton实现扫条码输入,更多关于扫码的信息参考 这里,扫码成功后,我本打算让JS自动打开摄像头再次进行扫码的,这样就让手机一直处理扫码状态了。但没实现。
- 在onSearch事件中,在FILTER后调用Model().read来验证Filter后的数据是否取到数据查询条件数据,取不到时报消息;
- 经测试发现系统Filter完全后,SAP后端会记录最后一次查询 的条件,当ACTION(删除,领用功能)后,SAP(后端)会使用些条件再次执行查询并返回数据(我觉得这应该算是SAP的BUG,这也是为什么我不用SAP Fiori Elements开发此功能 的主要原因) ,而这我功能要求每次查询会把满足条件的数据保存至表,所以在执行Filter完成后,把查询条件置空,并再执行一下空查询。
- 删除、领用分别调用SAP ABAP端的RAP中创建的两个ACTIONS,在JS中使用omodel.callFunction方法调用,并判断的成功失败分别处理消息。