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

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

image.png

image.png

image.png

image.png

image.png

保存前節(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ù)

image.png

首先在已發(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

成功


image.png

失敗


image.png

關(guān)于OData服務(wù)調(diào)用創(chuàng)建采購(gòu)訂單按鈕的可行性還在研究中

以上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末屉更,一起剝皮案震驚了整個(gè)濱河市徙融,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瑰谜,老刑警劉巖欺冀,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異萨脑,居然都是意外死亡隐轩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門渤早,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)职车,“玉大人,你說(shuō)我怎么就攤上這事°擦椋” “怎么了扛芽?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)积瞒。 經(jīng)常有香客問(wèn)我川尖,道長(zhǎng),這世上最難降的妖魔是什么茫孔? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任空厌,我火速辦了婚禮,結(jié)果婚禮上银酬,老公的妹妹穿的比我還像新娘嘲更。我一直安慰自己,他們只是感情好揩瞪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布赋朦。 她就那樣靜靜地躺著,像睡著了一般李破。 火紅的嫁衣襯著肌膚如雪宠哄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天嗤攻,我揣著相機(jī)與錄音毛嫉,去河邊找鬼。 笑死妇菱,一個(gè)胖子當(dāng)著我的面吹牛承粤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闯团,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辛臊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了房交?” 一聲冷哼從身側(cè)響起彻舰,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎候味,沒(méi)想到半個(gè)月后刃唤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡白群,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年尚胞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片川抡。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辐真,死狀恐怖须尚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情侍咱,我是刑警寧澤耐床,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站楔脯,受9級(jí)特大地震影響撩轰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜昧廷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一堪嫂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧木柬,春花似錦皆串、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至速挑,卻和暖如春谤牡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姥宝。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工翅萤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腊满。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓套么,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親糜烹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子违诗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354