CRM and CX Blogs by Members
Find insights on SAP customer relationship management and customer experience products in blog posts from community members. Post your own perspective today!
cancel
Showing results for 
Search instead for 
Did you mean: 
rmazzali
Active Contributor

I'm often required to check an object warranty validity against the good issue date.

1. SAP ECC steps

First of all you have to create the FM that returns the good issue date for an equipment. To do so copy the standard FM "SERIAL_HISTORY" in a new one:

"ZCRM_SERIAL_HISTORY" and change it to a RFC FM and the import/export paramenters and code as follows:

   function zcrm_serial_history.
*"----------------------------------------------------------------------
*"*"Interfaccia locale:
*"  IMPORTING
*"     VALUE(EQUNR) LIKE  EQUI-EQUNR
*"  EXPORTING
*"    VALUE(W_DATUM) TYPE  SY-DATUM
*"  EXCEPTIONS
*"      NODATA
*"----------------------------------------------------------------------
* Die Tabelle DA_SERTAB wird mit der Historie einer oder mehrerer
* Serialnummern zu den einzelnen Belegen gefuellt

  data da_sertab like riserx1 occurs 10 with header line.
  data da_objk   like objk    occurs 10 with header line.
  data da_serxx  like rserxx.
  data da_equnr  like equi-equnr.
  data da_entry_flag.                  "Kennzeichen Eintrag gefunden

  data: r_aufnr type tr_aufnr with header line.             
  move 'E'  to r_aufnr-sign.                               

  move 'EQ' to r_aufnr-option.                              


    da_equnr = equnr.
    check not da_equnr is initial.

* Es werden alle Objektlisten zur Serialnummer selektiert.
    select * from objk into table da_objk
             where equnr = da_equnr.
*  ENDIF.

  loop at da_objk.
    clear da_serxx.
    clear da_sertab.
    if not da_objk-taser is initial.
      case da_objk-taser.
* Lieferungen zur Serialnummer
        when taser_ser01.
          perform ser01_select
                        using    da_objk-obknr
                        changing da_serxx
                                 da_entry_flag.
* SD-Auftraege zu Serialnummern
        when taser_ser02.
          perform ser02_select
                        using    da_objk-obknr
                        changing da_serxx
                                 da_entry_flag.
* Materialbelege zu Serialnummern
        when taser_ser03.
          perform ser03_select
                        using    da_objk-obknr
                        changing da_serxx
                                 da_entry_flag.
* Prueflose zu Serialnummern
        when taser_ser04.
          perform ser04_select
                        using    da_objk-obknr
                        changing da_serxx
                                 da_entry_flag.
* PP-Auftraege zu Serialnummern
        when taser_ser05.
          perform ser05_select
                        using    da_objk-obknr
                        changing da_serxx
                                 da_entry_flag.
* Handlingunits zu Serialnummern
        when taser_ser06.
          perform ser06_select
                        using    da_objk-obknr
                        changing da_serxx
                                 da_entry_flag.
* Inventurbelege zu Serialnummern
        when taser_ser07.
          perform ser07_select
                        using    da_objk-obknr
                        changing da_serxx
                                 da_entry_flag.
        when others.

*ENHANCEMENT-POINT SERIAL_HISTORY_01 SPOTS ES_SAPLIPW1.

      endcase.
    endif.
    case da_objk-objvw.
      when objvw_a.
      when objvw_w.
* Selektieren aller Wartungspositionen mit Sernr/Equnr  in Objektliste
        perform pm_mpos_select
                   using    da_objk-obknr
                   changing da_serxx
                            da_entry_flag.
      when others.
    endcase.
* Eintrag gefunden -> ja -> Append SERTAB
    if da_entry_flag = con_charx.
      clear da_entry_flag.
      move-corresponding da_objk to da_sertab.
      move-corresponding da_serxx  to da_sertab.
      append da_sertab.
    endif.
  endloop.
* Selektieren aller Wartungspositionen mit Sernr/Equnr
  perform mpos_select
               tables   da_sertab
               using    da_equnr
               changing da_entry_flag.
* Selektieren aller IH-Meldungen mit Sernr/Equnr
  perform viqmel_select
               tables   da_sertab
               using    da_equnr
               changing da_entry_flag.

*--- Instllation history
  perform install_select
               tables   da_sertab
               using    da_equnr
               changing da_entry_flag.

  sort da_sertab descending by datum uzeit.

loop at da_sertab where vorgang = 'SDC3' and
                        bwart   = '601'  and              "SET HERE YOUR GOOD ISSUE MOVEMENT TYPE
                        blart   = 'WL'   and
                        taser   = 'SER03'.
  w_datum = da_sertab-datum.
  exit.
endloop.

if w_datum is initial.
  raise nodata.
else.
  sy-subrc = 0.
endif.

endfunction.

Generate and test it. Remember to check that the good movements you set in the FM are the one used in your system (601 is the SAP standard one).

2. SAP CRM steps

The CRM steps are:

A) Define a new custom Date Rule (ex: ZWTY_005 Good Issue Date). Add the XML code to call a custom function module:

 

<?xml version="1.0"?>

<SAPTimeRule>

<ABAPTimeRule function="Z_WARRANTY_DATE_RULE"/>

</SAPTimeRule>

B) Add the Date Rule to your Warranty date profile

C) Create the FM Z_WARRANTY_DATE_RULE that is called when the warranty rule is triggered.

   FUNCTION z_warranty_date_rule.
*"----------------------------------------------------------------------
*"*"Interfaccia locale:
*"  IMPORTING
*"     REFERENCE(CONTEXT) TYPE REF TO  IF_TIMECONTEXT
*"     REFERENCE(TIMEMESSAGE) TYPE REF TO  CL_TIMEMESSAGE
*"  EXPORTING
*"     REFERENCE(ERROR) TYPE  XFLAG
*"----------------------------------------------------------------------

  CLASS cl_timecalc DEFINITION LOAD.
  CLASS cl_timeunit_broker DEFINITION LOAD.
  INCLUDE timecalc_const.
  DATA:
* General Data for dealing with the timecontext:
  lv_date_prf              TYPE crmt_dates_prf_ext,
  ls_event_info            TYPE v_timepfev,
  li_time_result           TYPE REF TO cl_timetime,
  li_result                TYPE REF TO cl_timeevent,
  li_eventset              TYPE REF TO cl_timeset_generic,
  li_timecontext_complete  TYPE REF TO cl_crm_wty_timecontxt_complete,
  li_timeobject            TYPE REF TO if_timeobject,
  li_timeobject_callback   TYPE REF TO if_timeobject_callback,
  li_profile               TYPE REF TO if_timectprofile,
* data from the application
  lv_ref_guid              TYPE comt_object_guid,
  lv_wty_guid              TYPE comt_object_guid,
  lv_obj_guid              TYPE comt_object_guid,
  lv_obj_ref               TYPE crmt_il_wty_reference,
* timestamp (contains value which is returned)
  lv_timestamp             TYPE timestamp.
* equipment data
  DATA: ls_com_ta_r3_id    TYPE com_ta_r3_id,
        gi_date            TYPE sydatum,
        lv_tzone           TYPE timezone.


* ERP site determination
  DATA: lt_siteselect TYPE TABLE OF siteselect INITIAL SIZE 0,
        ls_siteselect TYPE siteselect.


****************************************************
* This rule sets timestamp value out of the
* R/3 equipment, linked to warranty and
* returns the value as return-value of the
* corresponding timerule
****************************************************

* take the eventset
  li_eventset = context->get_eventset( ).

* get context via cast
  CATCH SYSTEM-EXCEPTIONS move_cast_error = 4.
    li_timecontext_complete ?= context.
  ENDCATCH.
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.

* get date/profile which is currently processed
  lv_date_prf = li_timecontext_complete->m_date_prf.
  li_profile  = li_timecontext_complete->m_ctprofile.
* get application info from context
  lv_ref_guid = li_timecontext_complete->m_ref_guid.
  lv_wty_guid = li_timecontext_complete->m_wty_guid.
  lv_obj_guid = li_timecontext_complete->m_object_guid.
  lv_obj_ref  = li_timecontext_complete->m_object_ref.




* read info about date type for given profile
  CALL METHOD li_profile->m_timeevents->get_info
    EXPORTING
      name = lv_date_prf-name_event
    IMPORTING
      info = ls_event_info.
* get callback class for timeobject definition
  li_timeobject_callback
    = li_timecontext_complete->if_timecontext~get_timeobject_callback( )
.
* get timeobject definition
  IF NOT li_timeobject_callback IS INITIAL.
    li_timeobject
      = li_timeobject_callback->get_timeobject_byname(
      ls_event_info-name_objfr ).
  ENDIF.

********************************************
* get value for timestamp out of application
********************************************
  CASE lv_obj_ref.
    WHEN gc_ref-product.
    WHEN gc_ref-iobject.

* get R3 equipment number
      SELECT SINGLE * FROM com_ta_r3_id INTO ls_com_ta_r3_id WHERE product_guid = lv_obj_guid.

* get ERP site

      CALL FUNCTION 'SMOF0_READ_SITESELECT'
        TABLES
          to_siteselect = lt_siteselect.

      READ TABLE lt_siteselect INTO ls_siteselect
             WITH KEY sitetypeid = cl_smw1_siteprovider=>c_sitetype_r3oltp.


      CALL FUNCTION 'ZCRM_SERIAL_HISTORY'
        DESTINATION ls_siteselect-rfcdest
        EXPORTING
          equnr   = ls_com_ta_r3_id-r3ident
        IMPORTING
          w_datum = gi_date
        EXCEPTIONS
          nodata  = 1
          OTHERS  = 2.
*IF sy-subrc <> 0.
** MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
**         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
*ENDIF.

*       get system time zone for conversion
      CALL FUNCTION 'GET_SYSTEM_TIMEZONE'
        IMPORTING
          timezone = lv_tzone.
      IF NOT gi_date IS INITIAL.
*       convert date into timestamp
        CONVERT DATE gi_date
                 TIME '000000'
                 INTO TIME STAMP lv_timestamp
                 TIME ZONE lv_tzone.
      ENDIF.

    WHEN gc_ref-ibasehead.
    WHEN gc_ref-ibasecomp.
    WHEN OTHERS.
  ENDCASE.
*******************************************

* create time
  CREATE OBJECT li_time_result
    EXPORTING
      timeobject = li_timeobject
      timestamp  = lv_timestamp.

* create result and insert it into the eventset
  CHECK NOT li_time_result IS INITIAL.
  li_result ?= li_eventset->get_by_name( 'RESULT' ).
  IF li_result IS INITIAL.
    CREATE OBJECT li_result
      EXPORTING
        name      = 'RESULT'
        time_from = li_time_result.
    CALL METHOD li_eventset->insert
      EXPORTING
        item        = li_result
      EXCEPTIONS
        fatal_error = 1
        OTHERS      = 2.
  ELSE.
    CALL METHOD li_result->set_time_from
      EXPORTING
        time = li_time_result.
  ENDIF.

ENDFUNCTION.

The way I solved this issue can be used also for other R/3 based date check (for example an invoice date check).