Skip to Content
Author's profile photo Balloni Nicola

Implement “Near Me” in SAP CRM Sales Mobile

To use the SAP CRM Sales mobile application Near Me feature, extract the Geocode data for BP master data when Accounts or Contacts are pushed from CRM to  NetWeaver Mobile.

A Customer User Exit is provided as a BADI which the customers can implement to determine the geocode data for each Account or Contact address. Customer should implement this BADI /MSA/BADI_BUSINESS_PARTNER, Method GETDETAIL to fill the LONGITUDE and LATITUDE fields available for the CT_BUPA_HEADER_DETAILS node.

You can obtain LATITUDE and LONGITUDE by free google service.

This google service implements a daily query limit, so you need to store google response for a specific parameter in a table and reuse this latitude and longitude for the same parameter without make a new query everytime.

If you run the data trasmission more times in different day you can see that the Ztable increase row number.

This implementation permit you to bypass google limits.


Create the table ZMOBILEGEOLOC:



Implement /MSA/BADI_BUSINESS_PARTNER and write GETDETAIL method with the following code:

                 <fs_bupa_note> type line of crms_bupa_mob_note_t.
 data: l_http_client TYPE REF TO IF_HTTP_CLIENT,
        l_http_url type string,
        content type string,
        temp type GEOLON,
        via_esc type string,
        num_esc type string,
        cap type string,
        comune_esc type string,
        country type string,
        prov type string,
        status type string,
        v1 type char50,
        v2 type char50,
        v3 type char50,
        v4 type char50,
        lv_address type char255,
        wa_zmobilegeoloc type zmobilegeoloc.
  sort ct_bupa_note by spras seq_no ascending.
  loop at ct_bupa_header_details ASSIGNING <fs_hd>.
      l_http_url = ''.
      via_esc = <fs_hd>-street.
      num_esc = <fs_hd>-house_no.
      if num_esc is initial.
        num_esc = '1'.
      comune_esc = <fs_hd>-location.
      if comune_esc is initial.
        comune_esc = <fs_hd>-city.
      cap = <fs_hd>-postl_cod1.
      country = <fs_hd>-country.
      prov = <fs_hd>-region.
          via_esc = cl_http_client=>escape_url( via_esc ).
      num_esc = cl_http_client=>escape_url( num_esc ).
      comune_esc = cl_http_client=>escape_url( comune_esc ).
      REPLACE '%20' WITH '+' INTO via_esc in CHARACTER MODE.
      REPLACE '%20' WITH '+' INTO num_esc in CHARACTER MODE.
      REPLACE '%20' WITH '+' INTO comune_esc in CHARACTER MODE.
      check ( comune_esc is not initial or cap is not initial or prov is not initial ).
      CONCATENATE num_esc ',' via_esc ',' comune_esc ',' cap ',' prov ',' country into lv_address.
      select single * into corresponding fields of wa_zmobilegeoloc
        from zmobilegeoloc
        where indirizzo eq lv_address.
      if sy-subrc eq 0 and wa_zmobilegeoloc-longitudine is not initial and wa_zmobilegeoloc-latitudine is not initial.
         <fs_hd>-longitude = wa_zmobilegeoloc-longitudine.
         <fs_hd>-latitude = wa_zmobilegeoloc-latitudine.
        CONCATENATE l_http_url num_esc ',' via_esc ',' comune_esc ',' cap ',' prov ',' country '&sensor=false' into l_http_url.
*       Creation of new IF_HTTP_Client object
        CALL METHOD cl_http_client=>create_by_url
            url                = l_http_url
            client             = l_http_client
            argument_not_found = 1
            plugin_not_active  = 2
            internal_error     = 3
            OTHERS             = 4.
*       Check this was successful
        CHECK : sy-subrc IS INITIAL.
*       Set the request method
        l_http_client->request->set_header_field( name  = '~request_method'
                                                  value = 'GET' ).
*       Set the header
        l_http_client->request->set_header_field( name  = 'Content-Type'
                                                  value = 'text/xml; charset=utf-8' ).
*       Send the request
        clear status.
        data num_request type int4.
        num_request = 0.
        WHILE status ne 'OK' and num_request < 3.
          " google limit
          WAIT UP TO 1 SECONDS.
          l_http_client->send( ).
*         Reterive the result
          CALL METHOD l_http_client->receive
              http_communication_failure = 1
              http_invalid_state         = 2
              http_processing_failed     = 3
              OTHERS                     = 4.
          content = l_http_client->response->get_cdata( ).
*        *************************************PARSE XML**************************
*             initialize iXML
          type-pools: IXML.
          class CL_IXML definition load.
*             create main factory
          data: IXMLFACTORY type ref to IF_IXML.
*             create stream factory
          data: STREAMFACTORY type ref to IF_IXML_STREAM_FACTORY.
*             create input stream
          data: ISTREAM type ref to IF_IXML_ISTREAM.
*             parse input document ==============================================
*             initialize input document
          data: IDOCUMENT type ref to IF_IXML_DOCUMENT.
*             parse input document
          data: IPARSER type ref to IF_IXML_PARSER.
                                   STREAM_FACTORY = STREAMFACTORY
                                   ISTREAM = ISTREAM
                                   DOCUMENT = IDOCUMENT ).
          IPARSER->PARSE( ).
          " read xml
          data: loc_node type ref to IF_IXML_NODE,
                geo_node type ref to IF_IXML_NODE,
                lng_node type ref to IF_IXML_NODE,
                lat_node type ref to IF_IXML_NODE,
                res_node type ref to IF_IXML_NODE,
                status_node type ref to IF_IXML_NODE,
                loc_node_collection TYPE REF TO IF_IXML_NODE_COLLECTION,
                geo_node_collection TYPE REF TO IF_IXML_NODE_COLLECTION,
                status_node_collection TYPE REF TO IF_IXML_NODE_COLLECTION,
                res_node_collection TYPE REF TO IF_IXML_NODE_COLLECTION,
                res_children_node_list TYPE REF TO IF_IXML_NODE_LIST.
            res_node_collection = idocument->get_elements_by_tag_name( 'result' ).
            status_node_collection = idocument->get_elements_by_tag_name( 'status' ).
            if status_node_collection is not initial.
              status_node = status_node_collection->get_item( 0 ).
               move status_node->get_value( ) to status.
               move status to v1.
            num_request = num_request + 1.
        CHECK res_node_collection is not initial.
        res_node = res_node_collection->get_item( 0 ).
        CHECK res_node is not initial.
        res_children_node_list = res_node->get_children( ).
        clear geo_node.
        data: tmp_node type ref to IF_IXML_NODE,
             i type int4.
        i = 0.
        do res_children_node_list->get_length( ) TIMES.
          tmp_node = res_children_node_list->get_item( i ).
          if tmp_node->get_name( ) = 'geometry'.
            geo_node = tmp_node.
          i = i + 1.
        CHECK geo_node is not initial.
        loc_node = geo_node->get_first_child( ).
        check loc_node is not initial.
        lat_node = loc_node->get_first_child( ).
        lng_node = loc_node->get_last_child( ).
        check lng_node is not initial.
        move lng_node->get_value( ) to <fs_hd>-longitude.
        check lat_node is not initial.
        move lat_node->get_value( ) to <fs_hd>-latitude.
        clear wa_zmobilegeoloc.
        check lv_address is not initial and <fs_hd>-latitude is not initial and <fs_hd>-longitude is not initial.
        wa_zmobilegeoloc-indirizzo = lv_address.
        wa_zmobilegeoloc-latitudine = <fs_hd>-latitude.
        wa_zmobilegeoloc-longitudine = <fs_hd>-longitude.
        modify zmobilegeoloc from wa_zmobilegeoloc.


Run data transmission

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.