Spend Management Blogs by Members
Check out community member blog posts about spend management and SAP Ariba, SAP Fieldglass, and SAP Concur solutions. Post or comment about your experiences.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

Requirement

Shopping cart attachments should be saved in the SharePoint instead of SAP Database/Tables. And also all the operations should be happen normally as usual(Delete, Renaming File name, Adding New attachments,etc).

Development Approach

Here we wanted to store the physical documents in SharePoint and URL of those documents in SAP. So we are using standard framework to perform all the attachment related operations but we are just making that with URL.

By default all the documents will be stored in SAP Database tables. We have an option to store the attachments as URL based or Normal (Content Based). Content Based will store the attachment physical information in to the SAP tables whereas URL based will store URLs.

Now we changed Content Repository BBPFILESYSTEM as URL based, so SAP system can store URL based attachments. After that we enhanced standard Function Modules that creates, updates, deletes Shopping cart attachments.

We haven't created any custom content server instead we used the standard content repository and framework. We created FM to store the documents in SharePoint using the HTTP classes and store that SharePoint URL in SAP standard framework tables.

Steps

  1. Changing the Content Repository BBPFILESYSTEM to store URL based attachments
  2. Enhancing the standard create, update, delete API function modules to bypass the documents to SharePoint.
  3. Custom Function/Class to store an attachment to SharePoint using the HTTP standard classes.

Development Steps


Changing Content Repository BBPFILESYSTEM

Goto SPRO-> SAP Web Application Server-> Application Server-> Basis Services -> Knowledge Provider-> Content Management Service-> Define Content Repositories

Click on BBPFILESYSTEM

You will see Rep. Sub-Type as Normal

Change Rep. Sub-Type to URL based

Enhancing Standard APIs

We have to find APIs which are creating, updating, Delete attachments, etc. The Package BBP_ATTACH has all the attachments related objects and function group BBP_ATTACH has API function modules that actually trigger while creating, updating, and deleting.

Based on your requirement you can enhance those FMs. Here we created an implicit enhancement at starting to these FMs

Create FM - BBP_ATTACH_METH_KW_CREATE_DOC

This function module creates an attachment for SRM documents. we have to enhance this and make the attachments to store in SharePoint.

ENHANCEMENT ZZ_AP_ATTACHMENTS_SHAREPOINT.    "active version
*****************************************************************************
* Purpose  : Route the Attachment Storing to SharePoint and Store URL only in SAP.
* Date     : 8/27/2014
* User     : SMARAPUREDDI
* Transport: SRDK900966       SMARAPUREDDI AP Enhancement - Storing Enhancements in SharePoint
******************************************************************************
* Declarations
DATA:
ls_skwfid_en           
TYPE skwf_objid,
ls_loio_en             
TYPE skwf_io,
ls_phio_en             
TYPE skwf_io,
lt_phio_prop_en        
TYPE TABLE OF sdokpropty,
lt_loio_prop_en        
TYPE TABLE OF sdokpropty,
ls_prop_en             
TYPE sdokpropty,
ls_error_en            
TYPE skwf_error,
ls_file_access_info_en 
TYPE sdokfilaci,
lt_file_access_info_en 
TYPE TABLE OF sdokfilaci.

* The INSERT & REPLACE blocks are the updated logic for Standard

*{   INSERT
*
DATA:
lv_url             
TYPE so_url,
ls_file_access_url 
TYPE sdokcompru,
lt_file_access_url 
TYPE TABLE OF sdokcompru,
lv_send            
TYPE c.
*}   INSERT

* exporting = importing plus KW-fields
es_attach
= is_attach.

ls_skwfid_en
= is_attach-guid.

* perpare properties of the attachments
ls_prop_en
-name = bbpoa_pn_desc.
ls_prop_en
-value = is_attach-description.
APPEND ls_prop_en TO lt_loio_prop_en.
ls_prop_en
-name = bbpoa_pn_relurl.
ls_prop_en
-value = is_attach-phio_fname.
APPEND ls_prop_en TO lt_loio_prop_en.

lt_phio_prop_en[]
= lt_loio_prop_en[].
ls_prop_en
-name = bbpoa_pn_langu.
ls_prop_en
-value = sy-langu.
APPEND ls_prop_en TO lt_phio_prop_en.
ls_prop_en
-name = bbpoa_pn_mime.
ls_prop_en
-value = is_attach-phio_mime.
APPEND ls_prop_en TO lt_phio_prop_en.
ls_prop_en
-name = bbpoa_pn_ver_no.
ls_prop_en
-value = is_attach-phio_version_no.
APPEND ls_prop_en TO lt_phio_prop_en.

* create logical and physical objects
CALL FUNCTION 'SKWF_LOIO_WITH_PHIO_CREATE'
EXPORTING
loio_class     
= bbpoa_loioclass
phio_class     
= bbpoa_phioclass
loio_unique_id 
= ls_skwfid_en
phio_unique_id 
= ls_skwfid_en
IMPORTING
loio           
= ls_loio_en
phio           
= ls_phio_en
error          
= ls_error_en
TABLES
loio_properties
= lt_loio_prop_en
phio_properties
= lt_phio_prop_en.

IF NOT ls_error_en IS INITIAL.
PERFORM kw_error_messages TABLES et_messages
USING ls_error_en.
EXIT.
ENDIF.

* Store the physical attachment in SharePoint of corrsponding folder(Dev,QA,PRD)
*{   INSERT
*
DATA: lv_error      type sy-subrc,
lv_error_text
type string.

CALL FUNCTION 'Z_SEND_ATTACHMENT'
EXPORTING
IS_ATTACH
= is_attach
IV_LOIO  
= ls_loio_en-objid
IMPORTING
EV_URL   
= lv_url
EV_ERROR 
= lv_error
EV_ERROR_TEXT
= lv_error_text
EXCEPTIONS
NO_OBJEC_TYPE
= 1
NO_SHAREPOINT_DIRECTORY
= 2
OTHERS = 3.

IF LV_ERROR > 2.
ls_error_en
-type = 'E'.
ls_error_en
-id = 'BBP_ATT'.
ls_error_en
-no = '004'.
ls_error_en
-v1 = 'ERROR: Unable to upload document to sharepoint.'.
ls_error_en
-v2 = ' '.
ls_error_en
-v3 = lv_error_text.
PERFORM kw_error_messages TABLES et_messages
USING ls_error_en.
EXIT.
ENDIF.

" Send to sharepoint.
if lv_error = 0.
lv_send
= 'X'.
" Clear the object type info.
clear es_attach-PHIO_CHECKOUT_USER.
endif.
*}   INSERT
* Store URL instaed of physica attachment in SAP
*{   REPLACE
*\  ls_file_access_info-file_name  = is_attach-phio_fname.
*\  ls_file_access_info-property   = bbpoa_bbp_appl.
*\  ls_file_access_info-mimetype   = is_attach-phio_mime.
*\  ls_file_access_info-binary_flg = c_on.
*\  ls_file_access_info-file_size  = is_attach-phio_fsize.
ls_file_access_url
-file_name  = is_attach-phio_fname.
ls_file_access_url
-property   = bbpoa_bbp_appl.
ls_file_access_url
-mimetype   = is_attach-phio_mime.
ls_file_access_url
-file_size  = is_attach-phio_fsize.

if lv_send is initial.
ls_file_access_info_en
-binary_flg = c_on.
else.
ls_file_access_url
-file_type  = 'B'.
ls_file_access_url
-uri        = lv_url.
endif.
*}   REPLACE

*{   REPLACE
*\  APPEND ls_file_access_info TO lt_file_access_info.
if lv_send is initial.
APPEND ls_file_access_info_en TO lt_file_access_info_en.
else.
APPEND ls_file_access_url TO lt_file_access_url.
endif.
*}   REPLACE

if lv_send is initial.
* store attachmentcontent with content
CALL FUNCTION 'SKWF_PHIO_STORE_CONTENT'
EXPORTING
phio               
= ls_phio_en
x_raw_mode         
= c_on
IMPORTING
error              
= ls_error_en
TABLES
file_access_info   
= lt_file_access_info_en
file_content_binary
= is_attach-phio_content.
else.
* store attachmentcontent with URL
CALL FUNCTION 'SKWF_PHIO_STORE_CONTENT'
EXPORTING
phio               
= ls_phio_en
x_raw_mode         
= c_on
IMPORTING
error              
= ls_error_en
TABLES
*{   REPLACE
*\      file_access_info    = lt_file_access_info
file_access_url   
= lt_file_access_url
*}   REPLACE
file_content_binary
= is_attach-phio_content.
endif.

IF NOT ls_error_en IS INITIAL.
PERFORM kw_error_messages TABLES et_messages
USING ls_error_en.
EXIT.
ENDIF.

es_attach
-loio_class    = ls_loio_en-class.
es_attach
-loio_objid    = ls_loio_en-objid.
*{   INSERT
*
if lv_send is initial.
es_attach
-loio_class    = ls_loio_en-class.
es_attach
-loio_objid    = ls_loio_en-objid.
else.
es_attach
-url = lv_url.
es_attach
-type = c_att_type_url.
endif.
*}   INSERT

* Return
return.

ENDENHANCEMENT.

Change FM - BBP_ATTACH_METH_KW_UPDATE_DOC

In the same way you have to make the logic to update the document and store that in SharePoint.

Version FM - BBP_ATTACH_LOIO_GET_VERSIONS

Code for these FMs are attached.. Basically we are routing the documents to SharePoint and Storing the URL in SAP.

Include LBBP_ATTACHF03

You have to restrict an error message logging here

*{   REPLACE        SRDK900254                                        1
*\  IF NOT ls_error IS INITIAL.
IF NOT ls_error IS INITIAL AND
NOT ( ls_error-id ='SKWF_SDOKERRS' AND ls_error-no = 33 ).
*}   REPLACE
PERFORM kw_error_messages TABLES pt_messages
USING ls_error.
EXIT.
ENDIF.

Custom FM for storing attachments in SharePoint

We enhanced standard framework to store attachments URL and store physical attachments in SharePoint using custom FM 'Z_SEND_ATTACHMENT'.

FUNCTION z_send_attachment.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IS_ATTACH) TYPE  BBP_PDS_ATT_T
*"     REFERENCE(IV_LOIO) TYPE  SDOK_DOCID OPTIONAL
*"  EXPORTING
*"     REFERENCE(EV_URL) TYPE  SO_URL
*"     REFERENCE(EV_ERROR) TYPE  SY-SUBRC
*"     REFERENCE(EV_ERROR_TEXT) TYPE  STRING
*"  EXCEPTIONS
*"      NO_OBJECT_TYPE
*"      NO_SHAREPOINT_DIRECTORY
*"----------------------------------------------------------------------
DATA:  ls_obj_attachment TYPE zobj_attachments,
lv_object_type
TYPE crmt_subobject_category_db,
data TYPE xstring,
length
TYPE i,
server_name
TYPE string,
server_port
TYPE string,
auth_server_name
TYPE string,
auth_server_port
TYPE string,
lv_filename
TYPE string,
lv_attachment_time
(15) TYPE n,
lv_attachment_version
TYPE bds_dverno,
lv_loio
TYPE sdok_docid,
lv_file_ext
TYPE string,
lv_url
TYPE string,
lv_tmp
TYPE service_rl,
ret
TYPE string.
DATA:  client TYPE REF TO if_http_client.

" Get the object attachment configuration.
SELECT SINGLE *
FROM   zobj_attachments
INTO   ls_obj_attachment.
*  WHERE  name = lv_object_type.

" Not found?
IF ls_obj_attachment IS INITIAL OR ls_obj_attachment-send_external <> 'X'.
RAISE no_sharepoint_directory.
*     message 'ERROR: Unable to upload document to sharepoint due to configuration error.' type 'E'.
ENDIF.

* Convert to string.
length
= is_attach-phio_fsize.
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
EXPORTING
input_length
= length
IMPORTING
buffer       = data
TABLES
binary_tab  
= is_attach-phio_content
EXCEPTIONS
OTHERS       = 1.

" Error?
IF sy-subrc <> 0.
ev_error
= sy-subrc.
MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO ev_error_text.
RETURN.
ENDIF.

" Set the external server information.
server_name
= ls_obj_attachment-server_name.
server_port
= ls_obj_attachment-server_port.
auth_server_name
= ls_obj_attachment-auth_server_name.
auth_server_port
= ls_obj_attachment-auth_server_port.
CALL METHOD cl_http_client=>create
EXPORTING
proxy_host   
= auth_server_name
proxy_service
= auth_server_port
host         
= server_name
service      
= server_port
scheme       
= 1
IMPORTING
client        = client
EXCEPTIONS
OTHERS        = 1.

" Error?
IF sy-subrc <> 0.
ev_error
= sy-subrc.
MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO ev_error_text.

RETURN.
ENDIF.

" Get the file extension, if any.
CALL FUNCTION 'BBP_OUTPUT_X_PATH_FILE_EXT'
EXPORTING
i_pathfile 
= is_attach-phio_fname
IMPORTING
e_file_pure
= lv_filename
e_extens   
= lv_file_ext
EXCEPTIONS
OTHERS      = 1.

CONDENSE lv_filename NO-GAPS.
CONDENSE lv_file_ext NO-GAPS.

REPLACE ALL OCCURRENCES OF '#' IN lv_filename WITH '_'.
REPLACE ALL OCCURRENCES OF '?' IN lv_filename WITH '_'.
REPLACE ALL OCCURRENCES OF '&' IN lv_filename WITH '_'.
REPLACE ALL OCCURRENCES OF '%' IN lv_filename WITH '_'.
REPLACE ALL OCCURRENCES OF '/' IN lv_filename WITH '_'.
REPLACE ALL OCCURRENCES OF '#' IN lv_file_ext WITH '_'.
REPLACE ALL OCCURRENCES OF '?' IN lv_file_ext WITH '_'.
REPLACE ALL OCCURRENCES OF '&' IN lv_file_ext WITH '_'.
REPLACE ALL OCCURRENCES OF '%' IN lv_file_ext WITH '_'.
REPLACE ALL OCCURRENCES OF '/' IN lv_file_ext WITH '_'.

" Set the version number.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
EXPORTING
input  = is_attach-phio_version_no
IMPORTING
output = lv_attachment_version.

" Set the URL.
lv_attachment_time
= is_attach-creationtime.
IF NOT is_attach-loio_objid IS INITIAL.
lv_loio
= is_attach-loio_objid.
ELSE.
lv_loio
= iv_loio.
ENDIF.

IF lv_file_ext IS INITIAL.
"      concatenate ls_obj_attachment-folder_name '/' lv_filename '_' sy-uname '_' lv_attachment_time into lv_url.
CONCATENATE ls_obj_attachment-folder_name '/' lv_filename '_' sy-uname '_V' lv_attachment_version '_' lv_loio INTO lv_url.
ELSE.
"      concatenate ls_obj_attachment-folder_name '/' lv_filename '_' sy-uname '_' lv_attachment_time '.' lv_file_ext into lv_url.
CONCATENATE ls_obj_attachment-folder_name '/' lv_filename '_' sy-uname '_V' lv_attachment_version '_' lv_loio '.' lv_file_ext INTO lv_url.
ENDIF.

CALL METHOD cl_http_utility=>set_request_uri
EXPORTING
request
= client->request
uri    
= lv_url
EXCEPTIONS
OTHERS  = 1.

" Error?
IF sy-subrc <> 0.
ev_error
= sy-subrc.
MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO ev_error_text.

RETURN.
ENDIF.

CALL METHOD client->request->set_method
EXPORTING
method = 'PUT'.

CALL METHOD client->request->set_data
EXPORTING
data = data.

CALL METHOD client->send
EXCEPTIONS
OTHERS = 1.

" Error?
IF sy-subrc <> 0.
ev_error
= sy-subrc.
MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO ev_error_text.

RETURN.
ENDIF.

CALL METHOD client->receive
EXCEPTIONS
OTHERS = 1.

" Error?
IF sy-subrc <> 0.
ev_error
= sy-subrc.
MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO ev_error_text.

RETURN.
ENDIF.

ret
= client->response->get_cdata( ).

" Error?
IF ret IS NOT INITIAL.
MESSAGE 'ERROR: Unable to upload document to sharepoint.' TYPE 'E'.
ENDIF.

CALL METHOD client->close.

CONCATENATE 'http://'
ls_obj_attachment
-server_name
lv_url
INTO ev_url.

RETURN.
ENDFUNCTION.

Custom table zobj_attachments

This custom table will have the SharePoint URL folder path info based on the document type

5 Comments