Change user status using method HF_SET_STATUS

*"----------------------------------------------------------------------
*"Methoden Signatur:
*"  Importing
*"    IV_HEADER_GUID TYPE CRMT_OBJECT_GUID
*"    IV_STATUS TYPE J_ESTAT
*"    IV_RESET TYPE OAX
*"----------------------------------------------------------------------
METHOD change_transaction_status.

*Simulate execution of PPF action method HF_SET_STATUS.
*This solution was inspired by report CRM_SOCM_SERVICE_REPORT and action method HF_SET_STATUS.

  DATA:
    lr_methodcall  TYPE REF TO if_ex_exec_methodcall_ppf,
    lr_object      TYPE REF TO object,
    lr_appl_object TYPE REF TO cl_doc_crm_order,
    lr_partner     TYPE REF TO cl_partner_ppf,
    lv_log_handle  TYPE balloghndl,
    lr_container   TYPE REF TO if_swj_ppf_container,
    lv_status      TYPE ppfdtstat.

*Create PPF instance
  CALL METHOD cl_exithandler=>get_instance
    EXPORTING
      exit_name                     = 'EXEC_METHODCALL_PPF'
      null_instance_accepted        = cl_socm_integration=>true
    CHANGING
      instance                      = lr_methodcall
    EXCEPTIONS
      no_reference                  = 1
      no_interface_reference        = 2
      no_exit_interface             = 3
      class_not_implement_interface = 4
      single_exit_multiply_active   = 5
      cast_error                    = 6
      exit_not_existing             = 7
      data_incons_in_exit_managem   = 8
      OTHERS                        = 9.

*Unexpected error...
  IF sy-subrc <> 0 OR lr_methodcall IS NOT BOUND.
    MESSAGE ID sy-msgid TYPE 'X' NUMBER sy-msgno
               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

*Get application object.
  CALL FUNCTION 'CRM_ACTION_GET_APPL_OBJECT'
    EXPORTING
      iv_ref_guid    = iv_header_guid
      iv_ref_kind    = 'A'
    IMPORTING
      ev_appl_object = lr_object.

*Unexpected error...
  IF lr_object IS NOT BOUND.
    MESSAGE ID sy-msgid TYPE 'X' NUMBER sy-msgno
               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

  lr_appl_object ?= lr_object.

*We have and need no partner.
  CLEAR:
    lr_partner.

*Create log handle.
  CALL METHOD cl_log_ppf=>create_log
*  EXPORTING
*    ip_object    = 'PPF'
*    ip_subobject = 'PROCESSING'
*    ip_ext_no    =
    RECEIVING
      ep_handle    = lv_log_handle.

*Create and build up PPF Container
  CREATE OBJECT lr_container TYPE cl_swj_ppf_container.

*Unexpected error...
  IF lr_container IS NOT BOUND.
    MESSAGE x151(00).
  ENDIF.

  CALL METHOD lr_container->set_value
    EXPORTING
      element_name = 'USER_STATUS'
      data         = iv_status.

  CALL METHOD lr_container->set_value
    EXPORTING
      element_name = 'RESET_STATUS'
      data         = iv_reset.

*Lock Change Transaction if not already done.
  CALL FUNCTION 'CRM_ORDER_ENQUEUE'
    EXPORTING
      iv_guid           = iv_header_guid
    EXCEPTIONS
      foreign_lock      = 1
      system_failure    = 2
      distributed_lock  = 3
      no_change_allowed = 4
      transferring      = 5
      OTHERS            = 6.

*Expected & unexpected error...
  CASE sy-subrc.
    WHEN 0.
    WHEN 1. RAISE document_locked.
    WHEN 4. RAISE no_change_allowed.
    WHEN OTHERS. MESSAGE ID sy-msgid TYPE 'X' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDCASE.

*Change Status...
  TRY.
      CALL METHOD lr_methodcall->execute
        EXPORTING
          flt_val            = 'HF_SET_STATUS'
          io_appl_object     = lr_appl_object
          io_partner         = lr_partner
          ip_application_log = lv_log_handle
          ip_preview         = space
          ii_container       = lr_container
          ip_action          = '' "'RESET_BY_CHECK' "'SET_STATUS_BY_PROGRAM'
        RECEIVING
          rp_status          = lv_status.
    CATCH cx_socm_condition_violated.
      MESSAGE x151(00).
  ENDTRY.

*Free objects.
  CALL METHOD cl_log_ppf=>refresh_log
    EXPORTING
      ip_handle = lv_log_handle.

  FREE:
    lr_container,
    lr_partner,
    lr_appl_object,
    lr_methodcall.

*Status was not changed.
*We don't know why. Maybe authority maybe check condition. Maybe bigfoot. ...
  IF lv_status <> 1.
    RAISE no_change_allowed.
  ENDIF.

ENDMETHOD.