使用代码创建BRF ruleset

Created by Jerry Wang, last modified on Oct 02, 2014

该代码实现的功能:

  1. 为existing function创建一个空的ruleset
  2. 创建一条rule以及两个rule variable Customer Discount和promotion discount rule的规则是: 如果promotion的折扣 大于customer,则使用promotion的折扣进行price计算,否则使用customer的折扣进行计算。
  3. 创建两个formular分别进行基于customer和promotion折扣的price计算
REPORT zcreate_ruleset.
DEFINE write_errors.
  IF &1 IS NOT INITIAL.
  LOOP AT &1 ASSIGNING <ls_message>.
  WRITE: <ls_message>-text.
  ENDLOOP.
  RETURN.
  ENDIF.
END-OF-DEFINITION.
DATA:   lv_app_id      TYPE if_fdt_types=>id,
        lv_func_id     TYPE if_fdt_types=>id,
        lv_cust_ele_id TYPE if_fdt_types=>id,
        lv_item_ele_id TYPE if_fdt_types=>id,
        lv_fina_ele_id TYPE if_fdt_types=>id,
        lv_shel_ele_id TYPE if_fdt_types=>id.
INITIALIZATION.
  lv_app_id = 'FA163E8EAB031EE48B847A9EF751D5F0'.
  lv_func_id = 'FA163E8EAB031EE48B847ADC6A96D5F0'.
  lv_cust_ele_id = 'FA163E8EAB031EE48B847ADC6A96F5F0'.
  lv_item_ele_id = 'FA163E8EAB031EE48B847ADC6A9715F0'.
  lv_fina_ele_id = 'FA163E8EAB031EE48B847ADC6A9775F0'.
  lv_shel_ele_id = 'FA163E8EAB031EE48B847ADC6A9755F0'.
START-OF-SELECTION.
  DATA: lo_ruleset     TYPE REF TO if_fdt_ruleset,
        lo_factory     TYPE REF TO if_fdt_factory,
        lts_rule       TYPE if_fdt_ruleset=>ts_rule,
        lts_variable   TYPE if_fdt_ruleset=>ts_variable,
        lt_message     TYPE if_fdt_types=>t_message,
        lv_boolean     TYPE abap_bool,
        lts_expression TYPE if_fdt_ruleset=>ts_init_expr.
  FIELD-SYMBOLS: <ls_message> TYPE if_fdt_types=>s_message.
  lo_factory = cl_fdt_factory=>if_fdt_factory~get_instance(
  iv_application_id = lv_app_id ).
  lo_ruleset ?= lo_factory->get_ruleset( ).
  lo_ruleset->if_fdt_transaction~enqueue( ).
  lo_ruleset->set_ruleset_switch( iv_switch = if_fdt_ruleset=>gc_switch_on ).
  lo_ruleset->if_fdt_admin_data~set_name( 'price_calculation_rules' ).
  lo_ruleset->if_fdt_admin_data~set_texts( iv_short_text = 'price calc. rules'
                            iv_text = 'price calculation rules' ).
  lo_ruleset->set_function_restriction(
   iv_function_id = lv_func_id ).
* WE NEED TO CREATE RULESET VARIABLES AND
* ASSIGNED TO lts_variable
* Ruleset variables extend the function context,
* but within the scope of the ruleset only. they are also based on data objects.
  DATA: lo_element      TYPE REF TO if_fdt_element,
        ls_variable     TYPE if_fdt_ruleset=>s_variable,
        lv_pro_discount TYPE if_fdt_types=>id,
        lv_cus_discount TYPE if_fdt_types=>id.
  lo_element ?= lo_factory->get_data_object( iv_data_object_type =
  if_fdt_constants=>gc_data_object_type_element ).
  lo_element->if_fdt_transaction~enqueue( ).
  lo_element->if_fdt_admin_data~set_name( 'customer_discount' ).
  lo_element->if_fdt_admin_data~set_texts( iv_short_text = 'Customer Discount' ).
* SET type for customer_discount: NUMBER
  lo_element->set_element_type( if_fdt_constants=>gc_element_type_number ).
  lo_element->set_element_type_attributes(
      iv_length        = 3
      iv_decimals      = 2
      iv_only_positive = abap_true ).
  ls_variable-position = 1.
  ls_variable-data_object_id = lo_element->mv_id.
  INSERT ls_variable INTO TABLE lts_variable.
  lv_cus_discount = lo_element->mv_id.
* CREATE RULE VARIABLE promotion_discount
  lo_element ?= lo_factory->get_data_object(
  iv_data_object_type = if_fdt_constants=>gc_data_object_type_element ).
  lo_element->if_fdt_transaction~enqueue( ).
  lo_element->if_fdt_admin_data~set_name( 'promotion_discount' ).
  lo_element->if_fdt_admin_data~set_texts(
       iv_short_text = 'promotion discount' ).
  lo_element->set_element_type( if_fdt_constants=>gc_element_type_number ).
  lo_element->set_element_type_attributes(
        iv_length        = 3
        iv_decimals      = 2
        iv_only_positive = abap_true ).
  ls_variable-position = 2.
  ls_variable-data_object_id = lo_element->mv_id.
  INSERT ls_variable INTO TABLE lts_variable.
  lv_pro_discount = lo_element->mv_id.
* THESE TWO VARIABLES COULD ONLY BE USED WITHIN RULESET
  lo_ruleset->set_ruleset_variables( lts_variable ).
* CREATE DECISION TABLE
  DATA: lo_decision_table TYPE REF TO if_fdt_decision_table,
        lts_column        TYPE if_fdt_decision_table=>ts_column,
        lts_table_data    TYPE if_fdt_decision_table=>ts_table_data,
        ls_expression     TYPE if_fdt_ruleset=>s_init_expr.
  lo_decision_table ?= lo_factory->get_expression( iv_expression_type_id =
  if_fdt_constants=>gc_exty_decision_table ).
  lo_decision_table->if_fdt_transaction~enqueue( ).
  lo_decision_table->if_fdt_admin_data~set_name( 'calc_customer_discount' ).
  lo_decision_table->if_fdt_admin_data~set_texts(
   iv_short_text = 'calc. cust. discount'
   iv_text       = 'calculate customer discount' ).
* Code for table definition <<<lts_column>>> to be inserted here
  DATA: ls_column TYPE if_fdt_decision_table=>s_column.
  ls_column-col_no = 1. "customer
  ls_column-object_id = lv_cust_ele_id.
  ls_column-is_result = abap_false.
  INSERT ls_column INTO TABLE lts_column.
  ls_column-col_no = 2. "item
  ls_column-object_id = lv_item_ele_id.
  INSERT ls_column INTO TABLE lts_column.
  ls_column-col_no = 3. "customer discount
  ls_column-object_id = lv_cus_discount.
  ls_column-is_result = abap_true.
  INSERT ls_column INTO TABLE lts_column.
  lo_decision_table->set_columns( lts_column ).
* SET RESULT DATA OBJECT OF DECISION TABLE TO RULE VARIABLE WE JUST CREATE
  lo_decision_table->if_fdt_expression~set_result_data_object(
    lv_cus_discount ).
*  ls_expression-position = 1.
*  ls_expression-id = lo_decision_table->mv_id.
*  ls_expression-change_mode =
*  if_fdt_ruleset=>gc_change_mode_update.
*  INSERT ls_expression INTO TABLE lts_expression.
* Code for table content <<<lts_table_data>>> to be inserted here
  DATA: ls_range      TYPE if_fdt_range=>s_range,
        ls_table_data TYPE if_fdt_decision_table=>s_table_data.
  FIELD-SYMBOLS <lv_number> TYPE if_fdt_types=>element_number.
  ls_range-position = 1.
  ls_range-sign = if_fdt_range=>gc_sign_include.
  ls_range-option = if_fdt_range=>gc_option_equal.
  ls_table_data-col_no = 1. "start of row 1
  ls_table_data-row_no = 1.
  GET REFERENCE OF 'sap' INTO ls_range-r_low_value.
  INSERT ls_range INTO TABLE ls_table_data-ts_range.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW1, COLUMN2
  CLEAR ls_table_data-ts_range.
  ls_table_data-col_no = 2.
  ls_table_data-row_no = 1.
  GET REFERENCE OF 'ballpen' INTO ls_range-r_low_value.
  INSERT ls_range INTO TABLE ls_table_data-ts_range.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW1, COLUMN3
  CLEAR ls_table_data-ts_range.
  ls_table_data-col_no = 3.
  ls_table_data-row_no = 1.
  CREATE DATA ls_table_data-r_value TYPE if_fdt_types=>element_number.
  ASSIGN ls_table_data-r_value->* TO <lv_number>.
  <lv_number> = '0.15'.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW2, COLUMN1
  CLEAR ls_table_data-r_value.
  ls_table_data-col_no = 1. "start of row 2
  ls_table_data-row_no = 2.
  GET REFERENCE OF 'sap' INTO ls_range-r_low_value.
  INSERT ls_range INTO TABLE ls_table_data-ts_range.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW2, COLUMN2
  CLEAR ls_table_data-ts_range.
  ls_table_data-col_no = 2.
  ls_table_data-row_no = 2.
  GET REFERENCE OF 'pencil' INTO ls_range-r_low_value.
  INSERT ls_range INTO TABLE ls_table_data-ts_range.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW2, COLUMN3
  CLEAR ls_table_data-ts_range.
  ls_table_data-col_no = 3.
  ls_table_data-row_no = 2.
  CREATE DATA ls_table_data-r_value TYPE if_fdt_types=>element_number.
  ASSIGN ls_table_data-r_value->* TO <lv_number>.
  <lv_number> = '0.12'.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW3, COLUMN3????????????????
  CLEAR ls_table_data-r_value.
  ls_table_data-col_no = 3. "start of row 3
  ls_table_data-row_no = 3.
  CREATE DATA ls_table_data-r_value TYPE if_fdt_types=>element_number.
  ASSIGN ls_table_data-r_value->* TO <lv_number>.
  <lv_number> = '0'.
  INSERT ls_table_data INTO TABLE lts_table_data.
  lo_decision_table->set_table_data( lts_table_data ).
  ls_expression-position = 1.
  ls_expression-id = lo_decision_table->mv_id.
  ls_expression-change_mode = if_fdt_ruleset=>gc_change_mode_update.
  INSERT ls_expression INTO TABLE lts_expression.
* Create second decision table for promotion
  lo_decision_table ?= lo_factory->get_expression( iv_expression_type_id =
       if_fdt_constants=>gc_exty_decision_table ).
  lo_decision_table->if_fdt_transaction~enqueue( ).
  lo_decision_table->if_fdt_admin_data~set_name( 'calc_promotion_discount' ).
  lo_decision_table->if_fdt_admin_data~set_texts(
      iv_short_text = 'calc. pro. discount'
      iv_text       = 'calculate promotion discount' ).
* set column for promotion decision table
  CLEAR: lts_column.
  ls_column-col_no = 1. "customer
  ls_column-object_id = lv_cust_ele_id.
  ls_column-is_result = abap_false.
  INSERT ls_column INTO TABLE lts_column.
  ls_column-col_no = 2. "item
  ls_column-object_id = lv_item_ele_id.
  INSERT ls_column INTO TABLE lts_column.
  ls_column-col_no = 3. "customer discount
  ls_column-object_id = lv_pro_discount.
  ls_column-is_result = abap_true.
  INSERT ls_column INTO TABLE lts_column.
  lo_decision_table->set_columns( lts_column ).
  lo_decision_table->if_fdt_expression~set_result_data_object(
  lv_pro_discount ). "promotion discount
* code for table content (lts_table_data) to be inserted here
  CLEAR: ls_range, lts_table_data, ls_table_data.
  ls_range-position = 1.
  ls_range-sign = if_fdt_range=>gc_sign_include.
  ls_range-option = if_fdt_range=>gc_option_equal.
  ls_table_data-col_no = 1. "start of row 1
  ls_table_data-row_no = 1.
  GET REFERENCE OF 'oracle' INTO ls_range-r_low_value.
  INSERT ls_range INTO TABLE ls_table_data-ts_range.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW1, COLUMN2
  CLEAR ls_table_data-ts_range.
  ls_table_data-col_no = 2.
  ls_table_data-row_no = 1.
  GET REFERENCE OF 'notebook' INTO ls_range-r_low_value.
  INSERT ls_range INTO TABLE ls_table_data-ts_range.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW1, COLUMN3
  CLEAR ls_table_data-ts_range.
  ls_table_data-col_no = 3.
  ls_table_data-row_no = 1.
  CREATE DATA ls_table_data-r_value TYPE if_fdt_types=>element_number.
  ASSIGN ls_table_data-r_value->* TO <lv_number>.
  <lv_number> = '0.34'.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW2, COLUMN1
  CLEAR ls_table_data-r_value.
  ls_table_data-col_no = 1. "start of row 2
  ls_table_data-row_no = 2.
  GET REFERENCE OF 'oracle' INTO ls_range-r_low_value.
  INSERT ls_range INTO TABLE ls_table_data-ts_range.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW2, COLUMN2
  CLEAR ls_table_data-ts_range.
  ls_table_data-col_no = 2.
  ls_table_data-row_no = 2.
  GET REFERENCE OF 'glue' INTO ls_range-r_low_value.
  INSERT ls_range INTO TABLE ls_table_data-ts_range.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW2, COLUMN3
  CLEAR ls_table_data-ts_range.
  ls_table_data-col_no = 3.
  ls_table_data-row_no = 2.
  CREATE DATA ls_table_data-r_value TYPE if_fdt_types=>element_number.
  ASSIGN ls_table_data-r_value->* TO <lv_number>.
  <lv_number> = '0.52'.
  INSERT ls_table_data INTO TABLE lts_table_data.
* ROW3, COLUMN3????????????????
  CLEAR ls_table_data-r_value.
  ls_table_data-col_no = 3. "start of row 3
  ls_table_data-row_no = 3.
  CREATE DATA ls_table_data-r_value TYPE if_fdt_types=>element_number.
  ASSIGN ls_table_data-r_value->* TO <lv_number>.
  <lv_number> = '0'.
  INSERT ls_table_data INTO TABLE lts_table_data.
  lo_decision_table->set_table_data( lts_table_data ).
  ls_expression-position = 2.
  ls_expression-id = lo_decision_table->mv_id.
  ls_expression-change_mode = if_fdt_ruleset=>gc_change_mode_update.
  INSERT ls_expression INTO TABLE lts_expression.
  lo_ruleset->set_ruleset_initializations( lts_expression ).
* TODO: code for rules (lts_rule) to be inserted here
  DATA: lo_rule             TYPE REF TO if_fdt_rule,
        ls_rule             TYPE if_fdt_ruleset=>s_rule,
        ls_cond_range       TYPE if_fdt_range=>s_param_range,
        ls_rule_expr        TYPE if_fdt_rule=>s_expression,
        lt_rule_expr        TYPE if_fdt_rule=>t_expression,
        lv_formula_cus_disc TYPE if_fdt_types=>id,
        lv_formula_pro_disc TYPE if_fdt_types=>id.
  lo_rule ?= lo_factory->get_expression(
  iv_expression_type_id = if_fdt_constants=>gc_exty_rule ).
  lo_rule->if_fdt_transaction~enqueue( ).
  lo_rule->if_fdt_admin_data~set_texts( iv_text = 'apply discount' ).
* promotion discount > cusomter discount
  CLEAR ls_range.
  ls_cond_range-parameter_id = lv_pro_discount.
  ls_range-position = 1.
  ls_range-sign = if_fdt_range=>gc_sign_include.
  ls_range-option = if_fdt_range=>gc_option_greater.
  ls_range-low = lv_cus_discount.
  INSERT ls_range INTO TABLE ls_cond_range-ts_range.
  lo_rule->set_condition_range( ls_cond_range ).
*TODO define formulas, insert missing code later
  DATA: lo_formula TYPE REF TO if_fdt_formula,
        lv_formula TYPE string.
  lo_formula ?= lo_factory->get_expression(
  iv_expression_type_id = if_fdt_constants=>gc_exty_formula ).
  lo_formula->if_fdt_transaction~enqueue( ).
  lo_formula->if_fdt_admin_data~set_name( 'apply_promotion_discount' ).
  lo_formula->if_fdt_admin_data~set_texts(
      iv_short_text = 'apply prom. discount'
      iv_text       = 'apply promotion discount' ).
  lo_formula->if_fdt_expression~set_result_data_object(
   lv_fina_ele_id ). "final price
* Final Price = Shelf Price / ( 1 + Promotion Discount )
*  lv_formula = ‘00505683359d02ee98fc41ef3591caa8’ &&
  lv_formula = lv_shel_ele_id &&
  ` / ( 1 + ` && lv_pro_discount && ` )`.
  lo_formula->set_formula( lv_formula ).
  lv_formula_pro_disc = lo_formula->mv_id.
* The second formula, which will calculate the customer discount
  lo_formula ?= lo_factory->get_expression(
  iv_expression_type_id = if_fdt_constants=>gc_exty_formula ).
  lo_formula->if_fdt_transaction~enqueue( ).
  lo_formula->if_fdt_admin_data~set_name( 'apply_customer_discount' ).
  lo_formula->if_fdt_admin_data~set_texts(
      iv_short_text = 'apply cust. discount'
      iv_text       = 'apply customer discount' ).
  lo_formula->if_fdt_expression~set_result_data_object(
   lv_fina_ele_id ). "final price
  lv_formula = lv_shel_ele_id &&
  ` / ( 1 + ` && lv_cus_discount && ` )`.
  lo_formula->set_formula( lv_formula ).
  lv_formula_cus_disc = lo_formula->mv_id.
  ls_rule_expr-position = 1.
  ls_rule_expr-change_mode = if_fdt_rule=>gc_change_mode_update.
  ls_rule_expr-expression = lv_formula_pro_disc.
  INSERT ls_rule_expr INTO TABLE lt_rule_expr.
  lo_rule->set_true_action_extended( it_expression = lt_rule_expr ).
  CLEAR lt_rule_expr.
  ls_rule_expr-expression = lv_formula_cus_disc.
  INSERT ls_rule_expr INTO TABLE lt_rule_expr.
  lo_rule->set_false_action_extended( it_expression = lt_rule_expr ).
  ls_rule-position = 1.
  ls_rule-rule_id = lo_rule->mv_id.
  ls_rule-switch = if_fdt_ruleset=>gc_switch_on.
  INSERT ls_rule INTO TABLE lts_rule.
  lo_ruleset->set_rules( lts_rule ).
  WRITE: / 'calling check logic...'.
*  lt_message = lo_ruleset->if_fdt_transaction~check( iv_deep = abap_true ).
*  write_errors lt_message.
  WRITE: / 'ruleset check passed, ready for activation'.
  lo_ruleset->if_fdt_transaction~activate(
     EXPORTING
        iv_deep              = abap_true
     IMPORTING
        et_message           = lt_message
        ev_activation_failed = lv_boolean ).
  write_errors lt_message.
  lo_ruleset->if_fdt_transaction~save( EXPORTING iv_deep = abap_true ).
  lo_ruleset->if_fdt_transaction~dequeue(
  EXPORTING iv_deep = abap_true ).
  WRITE: / 'Rule set created successfully'.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券