Creating questionnaires for Risk Assessment

If you use the Risk Assessment module in Trade Compliance Management and want to create questionnaires automatically when checking your documents in SAP you can do this with a simple BAdI implementation.

For sales documents use BAdI /AEB/CMP_EC_ORDER_06.
For deliveries use BAdI /AEB/CMP_EC_DLV_03.
For purchase documents use BAdI /AEB/CMP_EC_PD_03.
For service orders use BAdI /AEB/CMP_EC_SO_03.

DATA:
  quest_parm    TYPE REF TO /aeb/if_cmp_pb_ec_cr_quest_do,
  template_id   TYPE REF TO /aeb/cl_01_string_nv,
  department    TYPE REF TO /aeb/cl_01_string_nv,
  email         TYPE REF TO /aeb/cl_01_string_nv,
  user          TYPE REF TO /aeb/cl_01_string_nv,
  org_unit      TYPE string,
  org_unit_nv   TYPE REF TO /AEB/CL_01_string_nv.
  
template_id = im_nullable_value_factory->string( '000025' ).
department = im_nullable_value_factory->string( 'Department' ).
email = im_nullable_value_factory->string( '[email protected]' ).
user = im_nullable_value_factory->string( 'User Name' ).
org_unit = im_context_bc->get_org_unit( ).
org_unit_nv = im_nullable_value_factory->string( org_unit ).

quest_parm = im_data_object_factory->new_cmp_pb_ec_cr_quest_do(
               im_department    = department
               im_email_address = email
               im_template_id   = template_id
               im_user_name     = user
               im_org_unit = org_unit_nv ).
im_value->set_create_questionnaire_prm( quest_parm ).
TYPE-POOLS: szadr.
DATA:
  vbpa_tab      TYPE TABLE OF vbpa,
  vbpa_line     TYPE vbpa,
  adr_sel       TYPE addr1_sel,
  adr           TYPE addr1_val,
  country_found TYPE /aeb/01_pb_boolean,
  vbak          TYPE vbak,
  ernam         TYPE ernam,
  user_address  TYPE usaddress,
  adr3_complete TYPE szadr_addr3_complete,
  addr3_line    TYPE szadr_addr3_line,
  s_department  TYPE string,
  adsmtp_line   TYPE szadr_adsmtp_line,
  s_email       TYPE string,
  user_name     TYPE string,
  quest_parm    TYPE REF TO /aeb/if_cmp_pb_ec_cr_quest_do,
  template_id   TYPE REF TO /aeb/cl_01_string_nv,
  department    TYPE REF TO /aeb/cl_01_string_nv,
  email         TYPE REF TO /aeb/cl_01_string_nv,
  user          TYPE REF TO /aeb/cl_01_string_nv.


vbpa_tab = im_context_bc->get_vbpas( ).
LOOP AT vbpa_tab INTO vbpa_line.
  IF vbpa_line-parvw = 'WE'.
  adr_sel-addrnumber = vbpa_line-adrnr.

  CALL FUNCTION 'ADDR_GET'
   EXPORTING
     address_selection = adr_sel
   IMPORTING
     address_value     = adr
   EXCEPTIONS
     parameter_error   = 1
     address_not_exist = 2
     version_not_exist = 3
     internal_error    = 4
     OTHERS            = 5.

IF adr IS INITIAL.
  CLEAR adr_sel.
  adr_sel-addrhandle = vbpa_line-adrnr.
  CALL FUNCTION 'ADDR_GET'
    EXPORTING
      address_selection = adr_sel
    IMPORTING
      address_value     = adr
    EXCEPTIONS
      parameter_error   = 1
      address_not_exist = 2
      version_not_exist = 3
      internal_error    = 4
      OTHERS            = 5.
ENDIF.


vbak = im_context_bc->get_vbak( ). "needs to be replaced for other business object data

CALL FUNCTION 'SUSR_USER_READ'
  EXPORTING
    user_name    = ernam
  IMPORTING
    user_address = user_address.

CALL FUNCTION 'ADDR_PERS_COMP_GET_COMPLETE'
  EXPORTING
    addrnumber     = user_address-addrnumber
    persnumber     = user_address-persnumber
  IMPORTING
    addr3_complete = adr3_complete.

LOOP AT adr3_complete-addr3_tab INTO addr3_line.
  IF s_department IS INITIAL
    AND addr3_line-data-department IS NOT INITIAL.
    s_department = addr3_line-data-department.
    EXIT.
  ENDIF.
ENDLOOP.

LOOP AT adr3_complete-adsmtp_tab INTO adsmtp_line.
  IF s_email IS INITIAL
    AND adsmtp_line-adsmtp-smtp_addr IS NOT INITIAL.
    s_email = adsmtp_line-adsmtp-smtp_addr.
    EXIT.
  ENDIF.
ENDLOOP.

template_id = im_nullable_value_factory->string( '000001' ).
department = im_nullable_value_factory->string( s_department ).
email = im_nullable_value_factory->string( s_email ).
user_name = ernam.
user = im_nullable_value_factory->string( user_name ).

quest_parm = im_data_object_factory->new_cmp_pb_ec_cr_quest_do(
               im_department    = department
               im_email_address = email
               im_template_id   = template_id
               im_user_name     = user ).
im_value->set_create_questionnaire_prm( quest_parm ).

If you like to have a block until the questionnaire is filled out with status ok, you just have to activate the Risk Assessment Integration in the Compliance Profile in the Compliance Engine.

Ok now that we created a questionnaire we might have the requirement to add the result of the questionnaire to the export controls check. Don't be confused. At the point where you have requested to create the questionnaire you also have the possibilty to get the questionnaire data.

Ok let us implement a very common usecase. The questionnaire will tell us the enduse of the transaction. For this very simple uscase i assume that we only have one critical result what tells me the enduse of the transaction.

DATA:
    items                          TYPE /aeb/if_cmp_pb_ec_item_do=>tt_ec_item_do,
    curr_item                      TYPE REF TO /aeb/if_cmp_pb_ec_item_do,
    questionnaire_do               TYPE REF TO /aeb/if_cmp_pb_quest_do,
    curr_crit_res                  TYPE REF TO /aeb/if_cmp_pb_quest_critr_do,
    quest_parm                     TYPE REF TO /aeb/if_cmp_pb_ec_cr_quest_do,
    template_id                    TYPE REF TO /aeb/cl_01_string_nv,
    department                     TYPE REF TO /aeb/cl_01_string_nv,
    email                          TYPE REF TO /aeb/cl_01_string_nv,
    user                           TYPE REF TO /aeb/cl_01_string_nv,
    initial_string_nv              TYPE REF TO /aeb/cl_01_string_nv,
    final_usage_from_questionnaire TYPE REF TO /aeb/cl_01_char_255_nv,  
    org_unit                       TYPE string,
    org_unit_nv                    TYPE REF TO /AEB/CL_01_string_nv,
    tmp_char255                    TYPE /aeb/01_char255.

  template_id = im_nullable_value_factory->string( '000008' ).
  department = im_nullable_value_factory->string( 'Sales Department' ).
  email = im_nullable_value_factory->string( '[email protected]' ).
  user = im_nullable_value_factory->string( 'User Name' ).
  org_unit = im_context_bc->get_org_unit( ).
  org_unit_nv = im_nullable_value_factory->string( org_unit ).

  quest_parm = im_data_object_factory->new_cmp_pb_ec_cr_quest_do(
                 im_department    = department
                 im_email_address = email
                 im_template_id   = template_id
                 im_org_unit      = org_unit_nv
                 im_user_name     = user ).
  im_value->set_create_questionnaire_prm( quest_parm ).

  IF NOT im_questionnaire_bc IS INITIAL.  "this is an optional paramter, not every context allows to getQuestionaire
    questionnaire_do = im_questionnaire_bc->get_questionnaire_for( im_questionnaire_template_id = template_id->v
                                                                   im_reference_id_host = im_value->get_transaction_ref_id( )->v ).

    READ TABLE questionnaire_do->get_critical_results( ) INTO curr_crit_res INDEX 1.
    IF curr_crit_res IS NOT INITIAL.
      tmp_char255 = curr_crit_res->get_identcode( ).
      final_usage_from_questionnaire = im_nullable_value_factory->char_255( tmp_char255 ).
      items = im_value->get_items( ).
      LOOP AT items INTO curr_item.
        curr_item->set_final_usages( final_usage_from_questionnaire ).
      ENDLOOP.
    ENDIF.
  ENDIF.

The first thing we have to do is to check if the parameter "im_questionnaire_bc" ist initial. Because this parameter is not passed in every context. If it is there you are in context of an export control check. The next step is to get the questionnaire with the method getQuestionnaireFor. You have to pass the parameter for the templateId and the referenceIdHost. Then you have the questionnaire. For our usecase we can now get the final usage from the critical results of the questionnaire. Then you have the set the final usage for each item. The method getQuestionnaire could raise an exception if an error occured when reading the data. It is not necessary to catch this exception it will be handled outside.

Well if you do not like to use this way to pass the data of the questionnaire to the export control checks, you also have the possibility to save the data locally in your ERP System, when the questionnaire update event will be synchronized. Or If you just like to get the data of the questionnaire without any context.


What's Next

Like to read data of Questionnaire without a context?
Or like to handle an update event of a questionnaire?