从ABAP CDS视图调用BRF+规则?

从ABAP CDS视图调用BRF+规则?,abap,cds,Abap,Cds,首先,我使用ABAP7.50和Oracle数据库在ECC中进行开发。我有一个BRF+规则,对于给定的邮政编码,它会返回我一个特定的承包商ID 只有2个可能的承包商ID,但每个ID的邮政编码是基于范围和唯一值的一组规则 简化规则示例: IF postalCode >= 1000 and postalCode <= 2000 THEN Contractor1 ELSE postalCode = 2001 THEN Contractor2 ELSE postalCode = 2002 TH

首先,我使用ABAP7.50和Oracle数据库在ECC中进行开发。我有一个BRF+规则,对于给定的邮政编码,它会返回我一个特定的承包商ID

只有2个可能的承包商ID,但每个ID的邮政编码是基于范围和唯一值的一组规则

简化规则示例:

IF postalCode >= 1000 and postalCode <= 2000 THEN Contractor1
ELSE postalCode = 2001 THEN Contractor2
ELSE postalCode = 2002 THEN Contractor1
ELSE Contractor2
现在我有一个ABAP CD,它返回一个工作订单信息,我需要它也返回标题中的供应商ID。我可以用工单邮政编码打电话给BRF+,只使用CD获取供应商ID吗

我之所以这样做,是因为CD是作为ODATA服务直接公开的。否则,我可以使用OpenSQL查询数据库,然后填充剩余字段

编辑:我将Haojie的答案标记为正确,尽管它只能从7.51版本开始。就我所知,对于较低版本,除了在Gateway中读取CDS视图后添加逻辑或不直接从该视图创建ODATA服务之外,没有其他解决方案,但是使用ABAP添加缺少的信息。

您可以使用

您需要在工单CD上构建另一个CD视图,并创建一个新的人工字段(如VendorID)并对其进行注释

 define view my_cds_view 
    as select from WorkOrder
{
    ...
     @ObjectModel.readOnly: true
     @ObjectModel.virtualElement
     @ObjectModel.virtualElementCalculatedBy: 'cl_brf_plus_vendor_id'
    cast('' as abap.lifnr ) as VendorID       
    ...
 } 
创建一个类cl\u brf\u plus\u vendor\u id以实现if\u sadl\u exit\u calc\u element\u read

CLASS cl_brf_plus_vendor_id DEFINITION
    PUBLIC
    FINAL
    CREATE PUBLIC .

    PUBLIC SECTION.
    INTERFACES:
    if_sadl_exit_calc_element_read.

    PROTECTED SECTION.
    PRIVATE SECTION.
ENDCLASS.


CLASS cl_brf_plus_vendor_id IMPLEMENTATION.

   METHOD if_sadl_exit_calc_element_read~get_calculation_info.

   ENDMETHOD.


   METHOD if_sadl_exit_calc_element_read~calculate.

       CHECK NOT it_original_data IS INITIAL.

       DATA lt_calculated_data TYPE STANDARD TABLE OF my_cds_view WITH DEFAULT KEY.

       MOVE-CORRESPONDING it_original_data TO lt_calculated_data.

       LOOP AT lt_calculated_data ASSIGNING FIELD-SYMBOL(<ls_calculated_data>).
         **"Get the postal code and call BRF+ to 
           "have the value of artificial field VendorID.** 

       ENDLOOP.

       MOVE-CORRESPONDING lt_calculated_data TO ct_calculated_data.

    ENDMETHOD.

  ENDCLASS.

将my_CD_视图作为数据源添加到网关项目中

您可以利用CDS表函数完成任务及其功能。自7.40 SP05发布AMDP以来,它仍然可用,并且表功能可用

假设您有带订单的CDS视图,该视图由表函数zcl_CDS_ord实现

您希望通过BRF+按订单ID获取每个订单的供应商ID

为了完成表函数实现类中的任务,您应该创建单独的方法,该方法将调用BRF+并更新中间itab,并在主表函数方法中将内部表重新读取到最终的CDS视图中

AMDP类的可能实现:

CLASS zcl_cds_ord DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    TYPES: BEGIN OF ty_orders,
             mandt     TYPE mandt,
             ebeln     TYPE ebeln,
             bstyp     TYPE ebstyp,
             vendor_id TYPE lifnr,
           END OF ty_orders,
           tty_orders TYPE STANDARD TABLE OF ty_orders.

    INTERFACES if_amdp_marker_hdb.
    CLASS-METHODS get_vendor FOR TABLE FUNCTION zcds_ord_func.
    METHODS call_brf CHANGING it_orders TYPE tty_orders.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_cds_ord IMPLEMENTATION.
  METHOD get_vendor BY DATABASE FUNCTION
          FOR HDB
          LANGUAGE SQLSCRIPT
          OPTIONS READ-ONLY.

    itab_orders = SELECT mandt,
                         ebeln,
                         bstyp,
                         '' AS vendor_id
                  FROM ekko;

    CALL call_brf CHANGING itab_orders.

    RETURN SELECT mandt, ebeln, bstyp, vendor_id
    FROM :itab_orders.
  ENDMETHOD.

  METHOD call_brf.
    DATA: lo_fuction    TYPE REF TO if_fdt_function.

* Get BRFplus function
    lo_fuction ?= cl_fdt_factory=>if_fdt_factory~get_instance( )->get_function( '50E549C2C40B1ED6A69FCB34B9365358' ).

* Set the BRFplus function context ( input variables )
    DATA(lo_context) = lo_fuction->get_process_context( ).

    LOOP AT it_orders ASSIGNING FIELD-SYMBOL(<fs_order>).
      lo_context->set_value( : iv_name  = 'ORDER_ID' ia_value = <fs_order>-ebeln   ) .
* Process the BRFplus function
      lo_fuction->process( EXPORTING io_context =  lo_context
                           IMPORTING eo_result  =  DATA(lo_result) ).

* Retrieve the BRFplus function result
      lo_result->get_value( IMPORTING ea_value =  <fs_order>-vendor_id ).
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

请注意,在CDS实现方法if\U amdp\U marker\U hdb接口中,您只能使用语句,但在其他方法中,您可以使用ABAP。

我认为上面答案中给出的以下代码片段不起作用。 您不能在AMDP方法内调用ABAP方法并调用。。。在这种情况下,更改甚至不是语法的一部分,它看起来像是SQLscript和ABAP的混合体

  METHOD get_vendor BY DATABASE FUNCTION
          FOR HDB
          LANGUAGE SQLSCRIPT
          OPTIONS READ-ONLY.

    itab_orders = SELECT mandt,
                         ebeln,
                         bstyp,
                         '' AS vendor_id
                  FROM ekko;

    CALL call_brf CHANGING itab_orders.

    RETURN SELECT mandt, ebeln, bstyp, vendor_id
    FROM :itab_orders.
  ENDMETHOD.

你好,Haojie,这看起来是正确的答案,但不幸的是,这项功能只能从7.51开始使用,而我现在使用的是7.50。我找不到发布变更,说明引入了什么版本,但我只找到了7.51及以上版本的文档。无论如何,注释和IF_SADL_EXIT_CALC_ELEMENT_READ接口在我的系统中都不存在。据我所知,它是在CD中调用ABAP的唯一地方。另一种方法是在Gateway GET_ENTITY_SET方法中实现逻辑。好的,谢谢。我在最初的问题中对版本进行了评论,将您的答案标记为正确
  METHOD get_vendor BY DATABASE FUNCTION
          FOR HDB
          LANGUAGE SQLSCRIPT
          OPTIONS READ-ONLY.

    itab_orders = SELECT mandt,
                         ebeln,
                         bstyp,
                         '' AS vendor_id
                  FROM ekko;

    CALL call_brf CHANGING itab_orders.

    RETURN SELECT mandt, ebeln, bstyp, vendor_id
    FROM :itab_orders.
  ENDMETHOD.