1.自定義業(yè)務(wù)對(duì)象創(chuàng)建與發(fā)布OData服務(wù)
保存前節(jié)點(diǎn)替換代碼
* Before Save Validation for Node ID SALESTOPURCHASE
*
* Importing Parameter : association (Navigation to Parent/Child/Associated Node Instances)
* SALESTOPURCHASE (Current Node Data)
* Exporting Parameter : valid (abap_true or abap_false)
* message (Message Text String)
* attribute (Attribute Name)
**數(shù)據(jù)檢查*****數(shù)據(jù)檢查******數(shù)據(jù)檢查*******數(shù)據(jù)檢查*****
IF salestopurchase-belnr IS NOT INITIAL.
DATA(belnr) = salestopurchase-belnr.
DATA(len) = 10 - strlen( belnr ).
DO len TIMES.
belnr = |0| & |{ belnr }|.
ENDDO.
CLEAR len.
ENDIF.
SELECT SINGLE COUNT(*) FROM i_salesorder WHERE salesorder EQ @belnr .
IF sy-subrc NE 0.
message = | 銷售訂單號(hào)不存在 |.
RETURN.
ENDIF.
SELECT SINGLE COUNT(*) FROM i_companycode WHERE companycode EQ @salestopurchase-bukrs .
IF sy-subrc NE 0.
message = | 公司代碼不存在 |.
RETURN.
ENDIF.
SELECT SINGLE COUNT(*) FROM i_plant WHERE plant EQ @salestopurchase-werks .
IF sy-subrc NE 0.
message = | 工廠不存在 |.
RETURN.
ENDIF.
DATA(lifnr) = salestopurchase-lifnr.
len = 10 - strlen( lifnr ).
DO len TIMES.
lifnr = |0| & |{ lifnr }|.
ENDDO.
CLEAR len.
SELECT SINGLE COUNT(*)
FROM i_supplierpurchasingorg
WHERE supplier EQ @lifnr
AND purchasingorganization EQ @salestopurchase-vkorg.
*AND purchasinggroup EQ @salestopurchase-ekorg.
IF sy-subrc NE 0.
message = | 供應(yīng)商無(wú)此采購(gòu)組織視圖 |.
RETURN.
ENDIF.
SELECT SINGLE COUNT(*) FROM i_product WHERE product EQ @salestopurchase-matnr.
IF sy-subrc NE 0.
message = | 物料不存在 |.
RETURN.
ENDIF.
IF salestopurchase-matnr+0(1) NE 'S'.
message = | 只允許使用服務(wù)型物料 |.
RETURN.
ENDIF.
IF salestopurchase-wrbtr_v IS INITIAL.
message = | 金額不允許為0 |.
RETURN.
ENDIF.
IF salestopurchase-wrbtr_c NE 'CNY'.
message = | 單位必須為CNY |.
RETURN.
ENDIF.
SELECT SINGLE COUNT(*) FROM i_taxcode WHERE taxcode EQ @salestopurchase-mwskz.
IF sy-subrc NE 0.
message = | 稅碼不存在 |.
RETURN.
ENDIF.
**數(shù)據(jù)檢查*****數(shù)據(jù)檢查******數(shù)據(jù)檢查*******數(shù)據(jù)檢查*****
valid = abap_true.
創(chuàng)建采購(gòu)訂單標(biāo)簽替換代碼
* Action ACTION001 for Node ID SALESTOPURCHASE
*
* Importing Parameter : association (Navigation to Parent/Child/Associated Node Instances)
* write (API for creating and updating Custom Business Object Node Instances)
* Changing Parameter : SALESTOPURCHASE (Current Node Data)
* Exporting Parameter : message (Message with Severity S(uccess), W(arning), E(rror))
*message = VALUE #(
* severity = co_severity-success
* text = 'Action ACTION001 executed'
*).
SELECT SINGLE COUNT(*)
FROM i_purchaseorderapi01
WHERE purchaseorder EQ @salestopurchase-ebeln
AND purchasingdocumentdeletioncode NE @abap_true.
IF sy-subrc EQ 0.
message = VALUE #( severity = co_severity-error text = '不允許重復(fù)生成采購(gòu)訂單' ).RETURN.
ENDIF.
DATA: lv_available TYPE abap_bool.
cl_ble_http_client=>is_service_available(
EXPORTING
communication_scenario = 'YY1_INT_HTTP'
outbound_service = 'YY1_INT_HTTP_REST'
RECEIVING
available = lv_available ).
IF lv_available NE abap_true.
message = VALUE #( severity = co_severity-error text = '通信安排錯(cuò)誤' ).RETURN.
ENDIF.
DATA(lo_client) = cl_ble_http_client=>create(
communication_scenario = 'YY1_INT_HTTP'
outbound_service = 'YY1_INT_HTTP_REST' ).
*********獲取token***********************************
DATA lv_u1 TYPE string VALUE '/API_PURCHASEORDER_PROCESS_SRV/A_PurchaseOrder'.
DATA:lv_u2 TYPE string VALUE '?$top=1'.
DATA: lt_headerparam TYPE tihttpnvp,
ls_header TYPE LINE OF tihttpnvp.
ls_header-name = 'Accept'.
ls_header-value = 'application/json'.
APPEND ls_header TO lt_headerparam.
ls_header-name = 'x-csrf-token'.
ls_header-value = 'fetch'.
APPEND ls_header TO lt_headerparam.
lv_u2 = lv_u1 && lv_u2.
DATA(request) = cl_ble_http_request=>create( )->set_method( 'GET' )->set_resource_extension( lv_u2 )->set_header_parameters( parameters = lt_headerparam ).
CLEAR:lt_headerparam,ls_header.
TRY .
DATA(response) = lo_client->send( request ).
DATA(lv_token) = response->get_header_parameter( name = 'x-csrf-token' ).
CATCH cx_ble_http_exception INTO DATA(lx).
message = VALUE #( severity = co_severity-error text = lx->get_text( ) ).
RETURN.
ENDTRY.
*****構(gòu)造JSON POST創(chuàng)建訂單******************************************
DATA:lv_post_body TYPE string,
lv_post_head TYPE string,
lv_post_item TYPE string.
DATA:
lv_field1 TYPE string VALUE '"CompanyCode": ',
lv_field2 TYPE string VALUE '"PurchaseOrderType": "NB"',
lv_field3 TYPE string VALUE '"Supplier": ',
lv_field4 TYPE string VALUE '"PurchasingOrganization": ',
lv_field5 TYPE string VALUE '"PurchasingGroup": ',
lv_field6 TYPE string VALUE '"DocumentCurrency":"CNY" ',
lv_field7 TYPE string VALUE '"PurchaseOrderDate": ',
lv_field8 TYPE string VALUE '"PurchaseOrderItem": ',
lv_field9 TYPE string VALUE '"Plant": ',
lv_field10 TYPE string VALUE '"NetPriceAmount": ',
lv_field11 TYPE string VALUE '"OrderQuantity": "1"',
lv_field12 TYPE string VALUE '"PurchaseOrderItemCategory": "0"',
lv_field13 TYPE string VALUE '"AccountAssignmentCategory": "Z"',
lv_field14 TYPE string VALUE '"Material": ',
lv_field15 TYPE string VALUE '"AccountAssignmentNumber":"1" ',
lv_field16 TYPE string VALUE '"CostCenter": ',
lv_field17 TYPE string VALUE '"SalesOrder": ',
lv_field18 TYPE string VALUE '"SalesOrderItem": ',
lv_field19 TYPE string VALUE '"PurchasingDocumentItem": ',
lv_field20 TYPE string VALUE '"ScheduleLine":"1" ',
lv_field21 TYPE string VALUE '"ScheduleLineDeliveryDate": ',
lv_field22 TYPE string VALUE '"TaxCode":'.
DATA:lv_node1 TYPE string VALUE '"to_PurchaseOrderItem": ',
lv_node2 TYPE string VALUE '"to_AccountAssignment": ',
lv_node3 TYPE string VALUE '"to_ScheduleLine": ',
lv_node4 TYPE string VALUE '{ "results":[{'.
**********獲取銷售訂單行項(xiàng)目數(shù)據(jù)******************************
DATA(len) = 10 - strlen( salestopurchase-belnr ).
DO len TIMES.
salestopurchase-belnr = |0| & |{ salestopurchase-belnr }|.
ENDDO.
SELECT *
INTO TABLE @DATA(lt_order)
FROM i_salesdocumentitem
WHERE salesdocument EQ @salestopurchase-belnr.
SHIFT salestopurchase-belnr LEFT DELETING LEADING '0'.
DATA:ls_order TYPE i_salesdocumentitem.
DATA lv_netamount TYPE i_salesdocumentitem-netamount. "total amount
DATA lv_wrbtr_sum TYPE i_salesdocumentitem-netamount.
DATA lv_wrbtr TYPE i_salesdocumentitem-netamount.
LOOP AT lt_order INTO ls_order.
lv_netamount = lv_netamount + ls_order-netamount.
ENDLOOP.
**********時(shí)間戳處理****************************************
DATA:my_timestamp TYPE timestamp,
lv_date TYPE c LENGTH 8,
lv_time TYPE c LENGTH 6,
lv_timestamp TYPE string,
timestamp1 TYPE timestamp VALUE '19700101000000',
timestamp2 TYPE timestamp.
GET TIME STAMP FIELD my_timestamp.
lv_timestamp = | { my_timestamp TIMESTAMP = ISO TIMEZONE = 'UTC+8' } |.
CONDENSE lv_timestamp NO-GAPS.
lv_date = lv_timestamp+0(4) && lv_timestamp+5(2) && lv_timestamp+8(2).
lv_time = lv_timestamp+11(2) && lv_timestamp+14(2) && lv_timestamp+17(2).
timestamp2 = lv_date && lv_time.
DATA(seconds) = cl_abap_timestamp_util=>get_instance( )->tstmp_seconds_between(
EXPORTING iv_timestamp0 = timestamp1 iv_timestamp1 = timestamp2 ) * 1000 - 28800000.
DATA(sjc) = |/Date({ seconds })/|.
lv_post_body = |{ lv_field1 }"{ salestopurchase-bukrs }",| &
|{ lv_field2 },| &
|{ lv_field3 }"{ salestopurchase-lifnr }",| &
|{ lv_field4 }"{ salestopurchase-vkorg }",| &
|{ lv_field5 }"{ salestopurchase-ekorg }",| &
|{ lv_field6 },| &
|{ lv_field7 }"{ sjc }",| &
|{ lv_node1 }{ lv_node4 }| .
DATA(lv_line) = lines( lt_order ).
LOOP AT lt_order INTO ls_order.
SHIFT ls_order-salesdocumentitem LEFT DELETING LEADING '0'.
IF sy-tabix NE '1' .
lv_post_item = |\{|.
ENDIF.
IF sy-tabix EQ lv_line.
lv_wrbtr = salestopurchase-wrbtr_v - lv_wrbtr_sum.
lv_post_item = lv_post_item &&
|{ lv_field8 }"{ ls_order-salesdocumentitem }",| &
|{ lv_field9 }"{ salestopurchase-werks }",| &
|{ lv_field10 }"{ lv_wrbtr }",| &
|{ lv_field22 }"{ salestopurchase-mwskz }",| &
|{ lv_field11 },| &
|{ lv_field12 },| &
|{ lv_field13 },| &
|{ lv_field14 }"{ salestopurchase-matnr }",| &
|{ lv_node2 }{ lv_node4 }| &
|{ lv_field15 },| &
|{ lv_field8 }"{ ls_order-salesdocumentitem }",| &
|{ lv_field16 }"{ salestopurchase-kostl }",| &
|{ lv_field17 }"{ ls_order-salesdocument }",| &
|{ lv_field18 }"{ ls_order-salesdocumentitem }"| &
|\}]\},| &
|{ lv_node3 }{ lv_node4 }| &
|{ lv_field19 }"{ ls_order-salesdocumentitem }",| &
|{ lv_field20 },| &
|{ lv_field21 }"{ sjc }"| &
|\}]\}\}]\}|.
ELSE.
lv_wrbtr = ls_order-netamount / lv_netamount * salestopurchase-wrbtr_v.
lv_wrbtr_sum = lv_wrbtr + lv_wrbtr_sum.
lv_post_item = lv_post_item &&
|{ lv_field8 }"{ ls_order-salesdocumentitem }",| &
|{ lv_field9 }"{ salestopurchase-werks }",| &
|{ lv_field10 }"{ lv_wrbtr }",| &
|{ lv_field22 }"{ salestopurchase-mwskz }",| &
|{ lv_field11 },| &
|{ lv_field12 },| &
|{ lv_field13 },| &
|{ lv_field14 }"{ salestopurchase-matnr }",| &
|{ lv_node2 }{ lv_node4 }| &
|{ lv_field15 },| &
|{ lv_field8 }"{ ls_order-salesdocumentitem }",| &
|{ lv_field16 }"{ salestopurchase-kostl }",| &
|{ lv_field17 }"{ ls_order-salesdocument }",| &
|{ lv_field18 }"{ ls_order-salesdocumentitem }"| &
|\}]\},| &
|{ lv_node3 }{ lv_node4 }| &
|{ lv_field19 }"{ ls_order-salesdocumentitem }",| &
|{ lv_field20 },| &
|{ lv_field21 }"{ sjc }"| &
|\}]\}\},|.
ENDIF.
lv_post_body = lv_post_body && lv_post_item.
CLEAR:lv_wrbtr,lv_post_item.
ENDLOOP.
lv_post_body = '{' && lv_post_body && '}'.
ls_header-name = 'Content-type'.
ls_header-value = 'application/json'.
APPEND ls_header TO lt_headerparam.
ls_header-name = 'x-csrf-token'.
ls_header-value = lv_token.
APPEND ls_header TO lt_headerparam.
DATA(requestpost) = cl_ble_http_request=>create( )->set_method( 'POST' )->set_resource_extension( lv_u1 )->set_header_parameters(
parameters = lt_headerparam )->set_body( data = lv_post_body ).
TRY .
DATA(responsepost) = lo_client->send( requestpost ).
DATA(str) = responsepost->get_body( ).
SPLIT str AT 'PurchaseOrder>' INTO lv_u1 lv_u2.
SPLIT lv_u2 AT '<' INTO salestopurchase-ebeln lv_u1.
CATCH cx_ble_http_exception INTO DATA(lx2).
message = VALUE #( severity = co_severity-error text = lx2->get_text( ) ).
RETURN.
ENDTRY.
2.使用Postman更新數(shù)據(jù)
首先在已發(fā)布的OData服務(wù)網(wǎng)址后拼接 \$metadata 獲取元數(shù)據(jù),我們發(fā)現(xiàn) FunctionImport 節(jié)點(diǎn)后 Name = YY1_SALESTOPURCHASESap_upsert,這就是我們需要調(diào)用的方法霸琴。
SAP在發(fā)布自定義業(yè)務(wù)對(duì)象時(shí)會(huì)自動(dòng)生成Sap_upsert,此功能導(dǎo)入將檢查語(yǔ)義鍵值是否已存在椒振,如果存在,則更新相應(yīng)的數(shù)據(jù)梧乘。如果不存在澎迎,則使用相應(yīng)數(shù)據(jù)創(chuàng)建新的業(yè)務(wù)對(duì)象實(shí)例。
請(qǐng)注意以下內(nèi)容:
區(qū)分大小寫:該鏈接區(qū)分大小寫选调,意味著字段名稱必須與自定義業(yè)務(wù)對(duì)象元數(shù)據(jù)中的字段名稱相對(duì)應(yīng)夹供。否則,post 請(qǐng)求會(huì)返回錯(cuò)誤学歧。
列出所有字段:列出根節(jié)點(diǎn)中包含的所有字段罩引。否則,post 請(qǐng)求會(huì)返回錯(cuò)誤枝笨。排序不分先后。
如果在自定義業(yè)務(wù)對(duì)象中定義了日期類型字段揭蜒,則它必須與相應(yīng)的 OData 字段類型相對(duì)應(yīng)横浑。
&Date=datetime'2019-01-01T01:00:00''
POST請(qǐng)求URL
https://my300XXX-api.saps4hanacloud.cn/sap/opu/odata/sap/YY1_SALESTOPURCHASE_CDS/YY1_SALESTOPURCHASESap_upsert?BELNR='110'&EBELN=''&BUKRS='D010'&WERKS='D010'&VKORG='D010'&EKORG='DK1'&LIFNR='1000000'&MATNR='S010030010001'&KOSTL='D010X002'&WRBTR_V=2000&MWSKZ='J1'&WRBTR_C='CNY'
注意TOKEN的獲取,必須獲取https://my300XXX-api.saps4hanacloud.cn/*****前綴的TOKEN
成功
失敗
關(guān)于OData服務(wù)調(diào)用創(chuàng)建采購(gòu)訂單按鈕的可行性還在研究中
以上