S4 Hana Cloud-自定義業(yè)務對象創(chuàng)建發(fā)布與OData更新數(shù)據(jù)

1.自定義業(yè)務對象創(chuàng)建與發(fā)布OData服務

image.png

image.png

image.png

image.png

image.png

保存前節(jié)點替換代碼

* 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 = | 銷售訂單號不存在 |.
  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 = | 供應商無此采購組織視圖 |.
  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 = | 只允許使用服務型物料 |.
  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)建采購訂單標簽替換代碼

* 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 = '不允許重復生成采購訂單' ).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 = '通信安排錯誤' ).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.


*****構造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":[{'.

**********獲取銷售訂單行項目數(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.

**********時間戳處理****************************************
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ù)

image.png

首先在已發(fā)布的OData服務網(wǎng)址后拼接 \$metadata 獲取元數(shù)據(jù),我們發(fā)現(xiàn) FunctionImport 節(jié)點后 Name = YY1_SALESTOPURCHASESap_upsert,這就是我們需要調用的方法。
SAP在發(fā)布自定義業(yè)務對象時會自動生成Sap_upsert,此功能導入將檢查語義鍵值是否已存在,如果存在,則更新相應的數(shù)據(jù)。如果不存在,則使用相應數(shù)據(jù)創(chuàng)建新的業(yè)務對象實例。
請注意以下內容:
區(qū)分大小寫:該鏈接區(qū)分大小寫,意味著字段名稱必須與自定義業(yè)務對象元數(shù)據(jù)中的字段名稱相對應。否則,post 請求會返回錯誤。
列出所有字段:列出根節(jié)點中包含的所有字段。否則,post 請求會返回錯誤。排序不分先后。
如果在自定義業(yè)務對象中定義了日期類型字段,則它必須與相應的 OData 字段類型相對應。
&Date=datetime'2019-01-01T01:00:00''

POST請求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

成功


image.png

失敗


image.png

關于OData服務調用創(chuàng)建采購訂單按鈕的可行性還在研究中

以上

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容