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.
STEP 1
Create the table ZMOBILEGEOLOC:
STEP 2:
Implement /MSA/BADI_BUSINESS_PARTNER and write GETDETAIL method with the following code:
FIELD-SYMBOLS: <fs_hd> type /MSA/S_BUPA_HEADER,
<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 = 'http://maps.google.com/maps/api/geocode/xml?address='.
via_esc = <fs_hd>-street.
num_esc = <fs_hd>-house_no.
if num_esc is initial.
num_esc = '1'.
ENDIF.
comune_esc = <fs_hd>-location.
if comune_esc is initial.
comune_esc = <fs_hd>-city.
ENDIF.
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.
else.
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
EXPORTING
url = l_http_url
IMPORTING
client = l_http_client
EXCEPTIONS
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
EXCEPTIONS
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.
IXMLFACTORY = CL_IXML=>CREATE( ).
* create stream factory
data: STREAMFACTORY type ref to IF_IXML_STREAM_FACTORY.
STREAMFACTORY = IXMLFACTORY->CREATE_STREAM_FACTORY( ).
* create input stream
data: ISTREAM type ref to IF_IXML_ISTREAM.
ISTREAM = STREAMFACTORY->CREATE_ISTREAM_STRING( content ).
* parse input document ==============================================
* initialize input document
data: IDOCUMENT type ref to IF_IXML_DOCUMENT.
IDOCUMENT = IXMLFACTORY->CREATE_DOCUMENT( ).
* parse input document
data: IPARSER type ref to IF_IXML_PARSER.
IPARSER = IXMLFACTORY->CREATE_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.
endif.
num_request = num_request + 1.
ENDWHILE.
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.
ENDIF.
i = i + 1.
ENDDO.
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.
endif.
ENDLOOP.
STEP 3
Run data transmission
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.