SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 1
Archiving PPM Item Documents to
SAP RMS
Applies to:
This document applies to Web Dynpro for JAVA, ABAP/4, SAP Net weaver and SAP PPM 4.5. For more information, visit the Web Dynpro ABAP homepage.
Summary
This article details a solution approach to archive the documents in an item’s ‘Attachments and Links’ to SAP RMS and provide a link in portal to view and edit the archived document.
Author: Sumit Oberoi
Company: Infosys Technologies Limited
Created on: 27 December 2010
Author Bio
Sumit Oberoi is a Technology Analyst with Infosys Technologies Limited. His areas of expertise include Web Dynpro for JAVA , Web Dynpro ABAP, Enterprise Portal, SAP PI , CAF and portal administration.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 2
Table of Contents
Overview ............................................................................................................................................................. 3
About PPM Item .............................................................................................................................................. 3
About SAP RMS .............................................................................................................................................. 3
Functionality ........................................................................................................................................................ 3
Solution Steps ..................................................................................................................................................... 3
ABAP Development ........................................................................................................................................ 3
Web Dynpro JAVA Development .................................................................................................................. 13 Create a WD JAVA Project rms_send in NWDS to get the PPM Item folder details. ................................................. 13
Create Another Web Dynpro JAVA Project Send_doc_content. ................................................................................ 18
Portal Configuration setup ............................................................................................................................ 27
Disclaimer ..................................................................................................................................................... 27
Output……… .................................................................................................................................................... 28
Related Content ................................................................................................................................................ 29
Disclaimer and Liability Notice .......................................................................................................................... 30
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 3
Overview
This development is a tool build using Web Dynpro JAVA and ABAP/4 to achieve the following:
List the files from a given ‘Attachment and Links’ folder and present them in a new window with their metadata.
Provide user the functionality to choose files from the list and then send their content to SAP RMS.
To provide a link in the ‘Attachment and Links’ folder pointing to access the archived file.
About PPM Item
In PPM system each project is denoted by an Item. When you navigate into an item from the Item Dashboard there is a link called ‘Attachments and Links’. This is actually a KM folder assigned to the item where all the item related documents are stored. When we create a PPM item a folder is automatically created.
Items are contain in buckets and Buckets in Portfolios, so every ‘Attachment and Links’ folder has a fixed KM path as per configuration. In our case the path has below structure:
Documents/cprxrpm/<Portfolio GUID>/RIH/<Item GUID>
About SAP RMS
In this scenario we are planning to use SAP RMS as the tool for storing the archived documents. We are assuming that the necessary setups have been done in your landscape prior to implementing this solution.
SAP RMS is accessed by transactions SCASE.
Functionality
Provides functionality for archiving KM documents and providing their link in KM.
This development provides user a facility to list only the files from a KM folder with their metadata.
User can select the files and send them for archival by clicking on the ‘Send Files’ button.
A Record is in SAP RMS with the document contained in it as an attachment.
A link to that document is created in KM folder to view and edit the document.
Solution Steps
We have to do following steps to develop this solution :
ABAP Development
1. Create BAPI ZPM9_BAPI_CREATE_RMS_DOC to create the record in SAP RMS.
This BAPI receives the document content as binary table and the document metadata. Below is the code for the BAPI with its signature:
Import Parameters :
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 4
Export Parameters:
Tables:
Code:
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(DESC) TYPE BAPISRMDOC-DESCR OPTIONAL
*" VALUE(KEY_WORD) TYPE BAPIPROPVA OPTIONAL
*" EXPORTING
*" VALUE(OBJECTID) LIKE BAPISRMDOC-GUID
*" VALUE(DOCUMENTCLASS) LIKE BAPISRMDOC-DOCCLASS
*" VALUE(ERROR_MSG) TYPE BAPI_MSG
*" TABLES
*" BIN_CONTENT STRUCTURE BAPICONTEN OPTIONAL
*" COMPONENTS STRUCTURE BAPIDOCCOMP
*"----------------------------------------------------------------------
CONSTANTS: c_rms_id TYPE bapirmsid VALUE 'S_SNG_NUCLEAR_RMS'," RMS ID
c_d_elem_name TYPE srmrgename VALUE 'ZTEST', " Element name for document
c_d_srule_name TYPE srmhllname VALUE 'DEFAULT'," Rule name for document
c_nuc_rec_zscmg_intern TYPE bapisrmdoc-
spsid VALUE 'ZSCMG_SPS_DOC_NUCLR_NQA_INTERN',
c_sps_rec TYPE bapisrmdoc-spsid VALUE 'ZSCMG_SPS_NUCLEAR_NQA_RECORDS',
c_d_srule_type TYPE srmrgtype VALUE 'DOC', " Rule type for docum
ent
c_attachments TYPE bapisrmrec-
spsid VALUE 'ZSCMG_SPS_DOC_NUCLR_NQA_INTERN',
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 5
c_r_elem_name TYPE srmrgename VALUE 'COUNTER'," Element name for record
c_r_srule_name TYPE srmhllname VALUE 'DEFAULT'," Rule name for record
c_r_srule_type TYPE srmrgtype VALUE 'REC', " Rule type for record
c_model_sps_id TYPE bapisrmrec-spsid
VALUE 'ZSCMG_SPS_RECORD_MODEL_TEST', "Element Type
ID
c_nuc_rec_model TYPE bapisrmrec-docid VALUE
'46F960AA403201D700000000AC10A015',
c_check TYPE bapisrmrec-boolean VALUE 'X',
c_error TYPE bapiret2-type VALUE 'E', " error
c_keyword TYPE bapipropna VALUE 'SRM_KEYWORD'.
DATA: v_document_id TYPE srmrgcount " Unique Document id
, v_doc_id TYPE bapisrmdoc-docid " Unique Document id
, v_docsps_id TYPE bapisrmdoc-spsid
, wa_return TYPE bapiret2
, wa_rprop TYPE bapipropertytab
,v_record_id TYPE srmrgcount " Unique Record id
,v_rec_no TYPE n LENGTH 15 " Recordnumber
,v_rec_id TYPE bapisrmrec-docid " Record id
,v_model TYPE bapisrmrec-docid " Unique ID of Record Model
,v_rec_object_id TYPE bapisrmrec-guid " Internal ID of Record
,v_rec_object_class TYPE bapisrmrec-docclass " Storage location of Record
, it_rprop TYPE STANDARD TABLE OF bapipropertytab.
* , wa_rprop TYPE bapipropertytab.
DATA : it_property TYPE STANDARD TABLE OF bapiproptb,
wa_property TYPE bapiproptb,
wa_doc_context TYPE bapidoccontext,
wa_error TYPE bapiret2,
it_ident TYPE TABLE OF bapipropme,
wa_ident TYPE bapipropme,
it_insert TYPE TABLE OF bapiinsert,
wa_insert TYPE bapiinsert,
it_error1 TYPE TABLE OF bapiret2,
wa_error1 TYPE bapiret2.
CALL FUNCTION 'ZPM1_GENERATE_SRM_DOC_ID'
EXPORTING
rms_id = c_rms_id
elem_name = c_r_elem_name
srule_name = c_r_srule_name
srule_type = c_r_srule_type
context_string = ' '
IMPORTING
highestnum = v_record_id
EXCEPTIONS
counter_id_not_found = 1
record_id_not_found = 2
update_failed = 3
OTHERS = 4.
IF sy-subrc NE 0.
EXIT.
ENDIF.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 6
v_rec_no = v_record_id.
v_rec_id = v_rec_no.
v_model = c_nuc_rec_model.
* Get the Internal ID and Storage Location for the new Record
CALL FUNCTION 'BAPI_RECORD_CREATE'
EXPORTING
rms_id = c_rms_id
sps_id = c_sps_rec " ZSCMG_SPS_NUCLEAR_NQA_RECORDS
documentid = v_rec_id
description = ' '
model_sps_id = c_model_sps_id
model = v_model
documentid_check_unique = c_check " X
IMPORTING
return = wa_return
objectid = v_rec_object_id
documentclass = v_rec_object_class.
IF wa_return-type EQ c_error.
ENDIF.
wa_doc_context-rms_id = c_rms_id.
wa_doc_context-sps_id = c_sps_rec.
* Add/Change the properties of the Record
*Fill the property value(Key Word)
REFRESH it_rprop.
CLEAR wa_rprop.
wa_rprop-name = c_keyword.
wa_rprop-value = key_word.
APPEND wa_rprop TO it_rprop.
CLEAR wa_rprop.
* Append property values
wa_property-name = 'LANGUAGE'.
wa_property-value = 'EN'.
APPEND wa_property TO it_property.
CLEAR wa_property.
wa_property-name = 'DESCRIPTION'.
wa_property-value = desc.
APPEND wa_property TO it_property.
CLEAR wa_property.
wa_property-name = 'Z_DOCUMENT_DATE'.
wa_property-value = sy-datum.
APPEND wa_property TO it_property.
CLEAR wa_property.
CLEAR wa_error.
CALL FUNCTION 'BAPI_RECORD_CHANGEPROPERTIES'
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 7
EXPORTING
objectid = v_rec_object_id
documentclass = v_rec_object_class
whole_document = ' '
doc_context = wa_doc_context
IMPORTING
return = wa_error
TABLES
properties = it_property.
IF wa_error-type EQ 'E'.
ENDIF.
v_docsps_id = c_nuc_rec_zscmg_intern.
* Generate the Unique document id
CALL FUNCTION 'ZPM1_GENERATE_SRM_DOC_ID'
EXPORTING
rms_id = c_rms_id
elem_name = c_d_elem_name
srule_name = c_d_srule_name
srule_type = c_d_srule_type
context_string = ' '
IMPORTING
highestnum = v_document_id
EXCEPTIONS
counter_id_not_found = 1
record_id_not_found = 2
update_failed = 3
OTHERS = 4.
IF sy-subrc NE 0.
ENDIF.
v_doc_id = v_document_id.
SHIFT v_doc_id LEFT DELETING LEADING space.
*Get the Internal ID and Storage Location for the new Document
CALL FUNCTION 'BAPI_SRM_DOC_CREATE'
EXPORTING
rms_id = c_rms_id
sps_id = v_docsps_id
documentid = v_doc_id
description = desc
do_commit = 'X'
IMPORTING
return = wa_return
objectid = objectid
documentclass = documentclass
TABLES
required_properties = it_rprop.
CALL FUNCTION 'SRM_DOCUMENT_CHECKIN_VIA_TAB'
EXPORTING
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 8
objectid = objectid
documentclass = documentclass
as_new_version = space
do_commit = 'X'
return = wa_return
TABLES
components = components
bin_content = bin_content
EXCEPTIONS
internal_error = 1
parameter_error = 2
not_authorized = 3
doc_not_found = 4
yet_locked = 5
OTHERS = 6
.
REFRESH it_rprop. CLEAR wa_ident.
wa_ident-elem_no = 1.
wa_ident-name = '%SPS_ID%'.
wa_ident-value = c_attachments. " ZSCMG_SPS_DOC_NUCLR_NQA_INTERN
APPEND wa_ident TO it_ident.
CLEAR wa_ident-value.
wa_ident-name = 'DOC_ID'.
wa_ident-value+0(10) = documentclass.
wa_ident-value+10(32) = objectid.
APPEND wa_ident TO it_ident.
CLEAR wa_ident-value.
wa_ident-name = 'VARIANT'.
wa_ident-value = '0'.
APPEND wa_ident TO it_ident.
CLEAR wa_ident-value.
wa_ident-name = 'VERSION'.
wa_ident-value = '0'.
APPEND wa_ident TO it_ident.
wa_insert-elem_no = 1.
wa_insert-anchor = 'NQ01'.
wa_insert-descr = desc.
APPEND wa_insert TO it_insert.
* Add the elements to the record
CLEAR wa_doc_context-sps_id.
wa_doc_context-rms_id = c_rms_id.
wa_doc_context-sps_id = c_sps_rec. " ZSCMG_SPS_NUCLEAR_NQA_RECORDS
CALL FUNCTION 'BAPI_RECORD_ADDELEMENTS'
EXPORTING
objectid = v_rec_object_id
documentclass = v_rec_object_class
doc_context = wa_doc_context
omit_authority_check = 'X'
TABLES
element_identification = it_ident
element_insertion = it_insert
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 9
return = it_error1.
IF it_error1[] IS NOT INITIAL.
CLEAR wa_error.
READ TABLE it_error1 INTO wa_error WITH KEY type = 'E'.
IF sy-subrc = 0.
* assigning bapiret-message to the error_msg
error_msg = wa_error-message.
ELSE.
error_msg = 'No Error'.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
ENDIF.
ENDIF.
ENDFUNCTION.
2. BAPI to display the Documents stored in SAP RMS.
We are using the standard BAPI SRM_DOCUMENT_DISPLAY to display the archived document.
Import Parameters:
3. Create BAPI Z_PM9_AUTHORIZATION_CHECK to check the logged in user’s permissions on the item. We will check direct item permissions as well as the derived permissions.
Import Parameters:
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 10
Export Parameters:
Code :
FUNCTION Z_PM9_AUTHORIZATION_CHECK.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(IV_GUID) TYPE /RPM/TV_GUID
*" VALUE(IV_OBJECT_TYPE) TYPE /RPM/OBJECT_TYPE
*" EXPORTING
*" VALUE(E_AUTHORIZED) TYPE CHAR1
*"----------------------------------------------------------------------
DATA: WA_CONTEXT TYPE /RPM/TS_OBJECT_HIER,
IT_ACO_ROLES TYPE /RPM/TT_ACL_ROLES,
V_AGRNAME TYPE AGR_USERS-AGR_NAME,
IT_ACT TYPE /RPM/TT_ACO_PERMISSIONS.
CONSTANTS: c_rbh(3) TYPE c VALUE 'RBH',
c_rih(3) TYPE c VALUE 'RIH',
c_read(10) TYPE c VALUE 'Read',
c_write(10) TYPE c VALUE 'Write',
c_admin(10) TYPE c VALUE 'Admin'.
REFRESH IT_ACT.
CLEAR E_AUTHORIZED.
REFRESH : IT_ACT,
IT_ACO_ROLES.
CLEAR WA_CONTEXT.
IF IV_OBJECT_TYPE = c_rih.
WA_CONTEXT-OBJECT_TYPE = IV_OBJECT_TYPE.
WA_CONTEXT-OBJECT_GUID = IV_GUID.
ELSEIF IV_OBJECT_TYPE = c_rbh.
WA_CONTEXT-OBJECT_TYPE = IV_OBJECT_TYPE.
WA_CONTEXT-OBJECT_GUID = IV_GUID.
*Get the portfolio id from /RPM/BUCKET_D.
SELECT SINGLE portfolio_guid INTO
WA_CONTEXT-portfolio_guid
FROM /rpm/bucket_d
WHERE guid = IV_GUID.
ENDIF.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 11
CALL FUNCTION '/RPM/ACL_DISPLAY'
EXPORTING
IS_CONTEXT = WA_CONTEXT
IMPORTING
ET_ACL = IT_ACT
ET_ACL_ROLES = IT_ACO_ROLES.
DELETE IT_ACO_ROLES WHERE ACTIVITY = c_read. "#EC NOTEXT
DELETE IT_ACO_ROLES WHERE ACTIVITY = c_write. "#EC NOTEXT
SORT IT_ACO_ROLES BY ROLE_ID.
DELETE ADJACENT DUPLICATES FROM IT_ACO_ROLES COMPARING ROLE_ID.
SORT IT_ACT BY ACTIVITY USER.
READ TABLE IT_ACT TRANSPORTING NO FIELDS WITH KEY ACTIVITY = c_admin
USER = SY-UNAME
BINARY SEARCH. "#EC NOTEXT
IF SY-SUBRC = 0.
E_AUTHORIZED = 'X'.
EXIT.
ENDIF.
*get the roles assigned to the user.
IF NOT IT_ACO_ROLES IS INITIAL.
SELECT AGR_NAME FROM
AGR_USERS UP TO 1 ROWS
INTO V_AGRNAME
FOR ALL ENTRIES IN IT_ACO_ROLES
WHERE AGR_NAME = IT_ACO_ROLES-ROLE_ID(30)
AND FROM_DAT LE SY-DATUM
AND TO_DAT GE SY-DATUM.
IF SY-SUBRC = 0.
E_AUTHORIZED = 'X'.
EXIT.
ENDIF.
ENDSELECT.
ENDIF.
ENDFUNCTION.
4. Create a report to call BAPI SRM_DOCUMENT_DISPLAY.
We will create an ABAP report program to call the SRM_DOCUMENT_DISPLAY BAPI. This is required as we want to create an SAP APPINTEGRATOR LINK in KM for each archived document.
We will use this report program’s transaction to create the APP integrator link.
Report Program Looks like this:
REPORT zpm9_call_disp_rms_doc.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-t01.
PARAMETERS: p_objid TYPE bapisrmdoc-guid.
SELECTION-SCREEN END OF BLOCK b1.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 12
START-OF-SELECTION.
* Call FM SRM_DOCUMENT_DISPLAY
to display the document by passing the object ID and document class
CALL FUNCTION SRM_DOCUMENT_DISPLAY
EXPORTING
objectid = p_objid
documentclass = 'ZSNG09'
EXCEPTIONS
not_authorized = 1
internal_error = 2
parameter_error = 3
not_found = 4
OTHERS = 5
Note: The document class can be different for your scenario.
Go to Se91 and create a transaction ZDIPLSAY_RMS_DOC to execute this program.
The transaction should look like this:
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 13
Web Dynpro JAVA Development
Create a WD JAVA Project rms_send in NWDS to get the PPM Item folder details.
Create component and view in the project. The project should look like this:
Add a button ‘Send to RMS’ on the view.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 14
In the action handler method on ActionSend add the below code:
wdThis.wdGetSend_RmsController().send();
Create a model BAPI_CHK_AUTH for the BAPI Z_PM9_AUTHORIZATION_CHECK.The model
should look like this after creation:
Create JCO destinations for the model BAPI_CHK_AUTH.
In the component controller Context, create two model nodes Mn_Chk_Auth_Input and Mn_Chk_Auth_Output for model and a value node Vn_Enable_btn.
Map model nodes with the Models Input and Output Nodes.
Add an attribute va_enable of type Boolean in the Vn_Enable_Btn node.
The Context should look like this:
Go to the component controller’s Implementation tab and add below code:
import sap.com.model.BAPI_CHK_AUTH;
import sap.com.model.Z_Pm9_Authorization_Check_Input;
import sap.com.model.Z_Pm9_Authorization_Check_Output;
import sap.com.wdp.IPrivateSend_Rms;
import com.sap.tc.webdynpro.clientserver.navigation.api.WDPortalNavigation;
import com
.sap
.tc
.webdynpro
.clientserver
.navigation
.api
.WDPortalNavigationHistoryMode;
import com.sap.tc.webdynpro.clientserver.navigation.api.WDPortalNavigationMode;
import com.sap.tc.webdynpro.progmodel.api.IWDMessageManager;
import com.sap.tc.webdynpro.progmodel.model.api.WDModelFactory;
import com.sap.tc.webdynpro.services.sal.um.api.WDClientUser;
import com.sap.xapps.cprxrpm.common.cache.CacheObject;
import com.sap.xapps.cprxrpm.common.cache.CacheObjectException;
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 15
Getting the PPM item and bucket details from Server cache using standard PPM APIs.
public void wdDoInit()
{
//@@begin wdDoInit()
IWDMessageManager msg_mgr = wdComponentAPI.getMessageManager();
// Obtain the RPM Object GUID, Type and parent guid from server
cache.
guid = new byte[16];
pguid = new byte[16];
try {
CacheObject _rpmCache = new CacheObject();
guid = _rpmCache.getRPMObjectGUID();
pguid = _rpmCache.getPortfolioGUID();
type = _rpmCache.getRPMObjectType();
// Check for Item or bucket type
if (type.compareTo(cn_item) == 0) {
byte[] parentguid = new byte[16];
bucket_id = _rpmCache.getRPMCpoID();
} else if (type.compareTo(cn_bucket) == 0) {
bucket_id = _rpmCache.getRPMObjectID();
/*Converting the byte to hexadecimal string*/
if (guid != null) {
hex_guid = "";
for (int i = 0; i < guid.length; i++)
hex_guid
+= Integer.toString(
(guid[i] & 0xff) + 0x100,
16).substring(
1);
hex_guid.toUpperCase();
/*Converting the byte to hexadecimal string*/
for (int i = 0; i < pguid.length; i++)
hex_pguid
+= Integer.toString(
(pguid[i] & 0xff) + 0x100,
16).substring(
1);
hex_pguid.toUpperCase();
} //end if
/*check the ACL Permissions*/
wdThis.checkACLPermissions();
} catch (CacheObjectException e) {
//Utility.logException(logger, "wdDoInit()", e);
msg_mgr.reportException("No Item ID found", true);
//@@end }
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 16
Method to check Logged in User’s permissions on the current item.
public void checkACLPermissions( )
//@@begin checkACLPermissions()
/* check permissions on the item */
try {
msg_mgr = wdComponentAPI.getMessageManager();
/*Get the logged in user details*/
String strUserID =
WDClientUser.getCurrentUser().getSAPUser().getUniqueName();
/* prepare BAPI input for executing BAPI */
Z_Pm9_Authorization_Check_Input input =
new Z_Pm9_Authorization_Check_Input();
/* setting the input for BAPI */
input.setIv_Guid(guid);
input.setIv_Object_Type(type);
/* Binding the input with the input node*/
wdContext.nodeMn_Chk_Auth_Input().bind(input);
/* calling the Bapi */
wdContext.currentMn_Chk_Auth_InputElement().modelObject().execute();
/*checking the authorization for logged in user*/
wdContext.nodeMn_Chk_Auth_Input().invalidate();
Z_Pm9_Authorization_Check_Output output = input.getOutput();
String fl_auth = output.getE_Authorized();
IPrivateSend_Rms.IVn_Enable_btnElement btn_elem =
wdContext.createVn_Enable_btnElement();
if (fl_auth.compareTo(cn_auth) == 0) {
/* Enable the Send RMS button */
btn_elem.setVa_enable(true);
} else {
/* Disable the Send RMS button */
btn_elem.setVa_enable(false);
wdContext.nodeVn_Enable_btn().bind(btn_elem);
} catch (Exception ex) {
msg_mgr.reportException(
"Error while checking the ACL permissions",
false);
msg_mgr.reportException(ex.toString(), false);
} finally {
//Releasing the connection//
BAPI_CHK_AUTH send_mod =
(BAPI_CHK_AUTH) WDModelFactory.getModelInstance(
BAPI_CHK_AUTH.class);
send_mod.disconnectIfAlive();
// Invalidate the BAPI input node
wdContext.nodeMn_Chk_Auth_Input().invalidate();
//@@end
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 17
Method to show the details of Files in a new window.
public void send( )
//@@begin send()
Added PCD path for the iView which will show the list of files in the
present KM folder***************/
WDPortalNavigation.navigateAbsolute(
iview_path,
WDPortalNavigationMode.SHOW_EXTERNAL,
WDPortalNavigationHistoryMode.NO_DUPLICATIONS,
"guid="
+ hex_guid
+ "&pguid="
+ hex_pguid
+ "&type="
+ type
+ "&Bucket="
+ bucket_id);
//@@end
//@@begin others --- GLOBAL Variables
private String hex_guid = "";
private String type = "";
private String hex_pguid = "";
private String bucket_id = "";
private String cn_item = "RIH";
private String cn_bucket = "RBH";
private String cn_auth = "X";
private byte[] guid = new byte[16];
private byte[] pguid = new byte[16];
final String iview_path =
"pcd:portal_content/SAP/com.sap.portfolio_management/com.sap.ppm.iviews/com.sap.iv
u.send_content_to_rms";
private IWDMessageManager msg_mgr = null;
//@@end
Create Web Dynpro Application Send_Rms_App for this WD Component.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 18
Create Another Web Dynpro JAVA Project Send_doc_content.
To display the list of files in a new window, we will create a separate WD JAVA component and then create an iview from it.
Go to NWDS and create the new project send_doc_content.
Create a WD component Send. It should look like this:
Create a model Bapi_Create_Rms_Doc for BAPI ZPM9_BAPI_CREATE_RMS_DOC. It should look like this:
Create JCO destinations for the model Bapi_Create_Rms_Doc
In component controller’s context, create Two Model nodes Create_Rms_Doc_Input and Create_Rms_Doc_Output. Map these nodes to the Model nodes.
Create a structure KMFileDetail in the Local Dictionary as per the screen below:
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 19
Create a Value node FileDetails from the above structure.
Create a value node Global with value attribute Collection_Ref of type com.sapportals.wcm.repository.ICollection
Create a value node ResourceContainer with an attribute Resource of type com.sappportals.wcm.repository.IResource
The Context should look like this now:
Go to the View and add a Table UI element. Bind the table datasource to the Node FileDetails
Add a button ‘Send_Files’ to the view . The view should be look like below:
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 20
Create action SendFiles for the button ‘Send_Files and add below code:
wdThis.wdGetSendController().sendFiles();
Go to the Component Controller’s Implementation tab and add the below code:
//@@begin imports
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import sap.com.model.Bapi_Create_RMS_Doc;
import sap.com.model.Bapiconten;
import sap.com.model.Bapidoccomp;
import sap.com.model.Zpm9_Bapi_Create_Rms_Doc_Input;
import sap.com.model.Zpm9_Bapi_Create_Rms_Doc_Output;
import sap.com.wdp.IMessageSend;
import sap.com.wdp.IPrivateSend;
import com.sap.tc.webdynpro.modelimpl.dynamicrfc.WDDynamicRFCExecuteException;
import com.sap.tc.webdynpro.progmodel.api.IWDMessageManager;
import com.sap.tc.webdynpro.progmodel.model.api.WDModelFactory;
import com.sap.tc.webdynpro.services.sal.adapter.api.IWDProtocolAdapter;
import com.sap.tc.webdynpro.services.sal.adapter.api.IWDRequest;
import com.sap.tc.webdynpro.services.sal.adapter.api.WDProtocolAdapter;
import com.sap.tc.webdynpro.services.sal.um.api.IWDClientUser;
import com.sap.tc.webdynpro.services.sal.um.api.WDClientUser;
import com.sap.tc.webdynpro.services.task.TaskBinder;
import com.sapportals.wcm.repository.ICollection;
import com.sapportals.wcm.repository.IResource;
import com.sapportals.wcm.repository.IResourceContext;
import com.sapportals.wcm.repository.IResourceFactory;
import com.sapportals.wcm.repository.IResourceList;
import com.sapportals.wcm.repository.IResourceListIterator;
import com.sapportals.wcm.repository.ResourceContext;
import com.sapportals.wcm.repository.enum.LinkType;
import com.sapportals.wcm.util.content.IContent;
import com.sapportals.wcm.util.uri.RID;
import com.sapportals.wcm.util.uri.URL;
import com.sapportals.wcm.util.usermanagement.WPUMFactory;
//@@end
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 21
Create method to check the uniqueness of the Filename for each new document/link being created.
public boolean checkDuplicate( java.lang.String FileName )
{
//@@begin checkDuplicate()
try {
ICollection songsFolder =
wdContext
.nodeGlobal()
.currentGlobalElement()
.getCollection_Ref();
IResourceList res_list = songsFolder.getChildren();
IResourceListIterator list_iter = res_list.listIterator();
boolean duplicate = false;
while (list_iter.hasNext() || duplicate == true) {
IResource tempresource = list_iter.next();
if (tempresource.getName().compareTo(FileName) == 0) {
duplicate = true;
return duplicate;
return duplicate;
} catch (Exception ex) {
ex.printStackTrace();
}
return true;
//@@end
Method to read the items’s ‘Attachment and Links’ folder and prepare list of Files.
public void listResources( )
{
//@@begin listResources()
/*Code to get the GUID of the bucket*/
msg_mgr = wdComponentAPI.getMessageManager();
IWDProtocolAdapter protocolAdapter =
WDProtocolAdapter.getProtocolAdapter();
IWDRequest request = protocolAdapter.getRequestObject();
String GUID = request.getParameter("guid");
String TYPE = request.getParameter("type");
String PGUID = request.getParameter("pguid");
Bucket_id = request.getParameter("Bucket");
try {
IWDClientUser wdClientUser = WDClientUser.getLoggedInClientUser();
com.sap.security.api.IUser sapUser = wdClientUser.getSAPUser();
// create an ep5 user from the retrieved user
com.sapportals.portal.security.usermanagement.IUser ep5User =
WPUMFactory.getUserFactory().getEP5User(sapUser);
IResourceContext resourceContext = new ResourceContext(ep5User);
// get a resource factory
IResourceFactory resourceFactory =
com.sapportals.wcm.repository.ResourceFactory.getInstance();
// get a RID from the current path to display the according
content
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 22
path =
"/documents/cprxrpm/"
+ PGUID.toUpperCase()
+ "/"
+ TYPE
+ "/"
+ GUID.toUpperCase();
RID rid = new RID(path);
//Get a IResource object to work on
ICollection songsFolder =
(ICollection) resourceFactory.getResource(rid,
resourceContext);
/*Storing the collection reference*/
IPrivateSend.IGlobalElement gl_elem =
wdContext.nodeGlobal().createGlobalElement();
gl_elem.setCollection_Ref(songsFolder);
wdContext.nodeGlobal().addElement(gl_elem);
IResourceList resourceList = songsFolder.getChildren();
// Reading the KM collection pointed by songsFolder
if (resourceList.size() > 0) {
IResourceListIterator resourceListIterator =
resourceList.listIterator();
wdThis.readCollection(songsFolder);
} //end of resourceList if
//} //end of OPRN if.
else
msg_mgr.reportException("No Resource found", true);
} catch (Exception e) {
msg_mgr.reportException(e.toString(), true);
//@@end
Method for Reading the KM folder recursively for subfolders.
public void readCollection( com.sapportals.wcm.repository.ICollection im_collection
//@@begin readCollection()
msg_mgr = wdComponentAPI.getMessageManager();
try {
IResourceList resourceList = im_collection.getChildren();
if (resourceList.size() > 0) {
IResourceListIterator resourceListIterator =
resourceList.listIterator();
while (resourceListIterator.hasNext()) {
IResource tempResource = resourceListIterator.next();
if (tempResource.isCollection() == true) {
ICollection temp_collcn = (ICollection)
tempResource;
wdThis.readCollection(temp_collcn);
} else if (
tempResource.isCollection() == false
&& tempResource.getLinkType() ==
LinkType.NONE) {
//Storing the resource reference //
IPrivateSend.IResourceContainerElement
resource_elem =
wdContext
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 23
.nodeResourceContainer()
.createResourceContainerElement();
resource_elem.setResource(tempResource);
wdContext.nodeResourceContainer().addElement(
i,
resource_elem);
/*Converting java.util.Date to java.sql.Date*/
java.util.Date created_on_ut =
tempResource.getCreationDate();
long t = created_on_ut.getTime();
java.sql.Date created_on = new java.sql.Date(t);
java.util.Date modified_on_ut =
tempResource.getLastModified();
t = modified_on_ut.getTime();
java.sql.Date modified_on = new java.sql.Date(t);
/*Storing File Details*/
IPrivateSend.IFileDetailsElement file_det_elem =
wdContext.createFileDetailsElement();
file_det_elem.setNAME(tempResource.getName());
file_det_elem.setCREATED_BY(
tempResource.getCreatedBy());
file_det_elem.setCREATED_ON(created_on);
file_det_elem.setMODIFIED_BY(
tempResource.getLastModifiedBy());
file_det_elem.setMODIFIED_ON(modified_on);
file_det_elem.setDESCRIPTION(
tempResource.getDescription());
RID
current_rid = tempResource.getRID();
file_det_elem.setPATH(current_rid.getPath());
wdContext.nodeFileDetails().addElement(
i,
file_det_elem);
i++;
} // end of isCollection IF
} //end of while loop
} // end of resourceList size IF
} catch (Exception ex) {
msg_mgr.reportWarning(ex.toString());
//@@end
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 24
Loop into the filedetails node and send the files’ content to SAP RMS.
public void sendFiles( )
{
//@@begin sendFiles()
//Get message manager reference
msg_mgr = wdComponentAPI.getMessageManager();
try {
//Get the Node size
int size = wdContext.nodeFileDetails().size();
IPrivateSend.IFileDetailsElement file_elem =
wdContext.nodeFileDetails().createFileDetailsElement();
IWDClientUser wdClientUser = WDClientUser.getCurrentUser();
com.sap.security.api.IUser sapUser = wdClientUser.getSAPUser();
// create an ep5 user from the retrieved user
com.sapportals.portal.security.usermanagement.IUser ep5User =
WPUMFactory.getUserFactory().getEP5User(sapUser);
//Establish resource context
IResourceContext resourceContext = new ResourceContext(ep5User);
//Get a resource factory
IResourceFactory resourceFactory =
com.sapportals.wcm.repository.ResourceFactory.getInstance();
//Loop into the FileDetails node to send the content for each file to RMS
for (int i = 0; i < size; i++) {
file_elem =
wdContext.nodeFileDetails().getFileDetailsElementAt(i);
if (file_elem.getARCHIVE() == true) {
//Get a RID for the current resource
RID rid_res = new RID(file_elem.getPATH());
RID rid_collecn = rid_res.parent();
//Get the resource and resource content
ICollection songsFolder =
(ICollection) resourceFactory.getResource(
rid_collecn,
resourceContext);
IResource res =
resourceFactory.getResource(rid_res,
resourceContext);
IContent res_content = res.getContent();
InputStream is = res_content.getInputStream();
/* Call BAPI ZPM9_BAPI_CREATE_RMS_DOC */
//Setting the BAPI input values
Zpm9_Bapi_Create_Rms_Doc_Input input =
new Zpm9_Bapi_Create_Rms_Doc_Input();
int length = is.available();
int itrn = length / 1022;
int off = 0;
String doc_s_size =
Long.toString(res_content.getContentLength());
msg_mgr.reportSuccess(
"Document size = " + doc_s_size + " bytes");
for (int j = 0; j <= itrn; j++) {
Bapiconten bapi_cont = new Bapiconten();
byte[] bcon = new byte[1022];
int bytes_read = is.read(bcon, 0, 1022);
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 25
bapi_cont.setLine(bcon);
input.addBin_Content(bapi_cont);
off += bytes_read;
} // end of j for loop
//Setting the Component values//
Bapidoccomp comp = new Bapidoccomp();
comp.setComp_Count(1);
comp.setComp_Id(Bucket_id + "_" + file_elem.getNAME());
comp.setMimetype(res_content.getContentType());
comp.setBinary_Flag("X");
comp.setComp_Size(Integer.parseInt(doc_s_size));
input.addComponents(comp);
input.setDesc(file_elem.getDESCRIPTION());
input.setKey_Word(file_elem.getKEYWORD());
wdContext.nodeCreate_Rms_Doc_Input().bind(input);
//Calling the BAPI ZPM9_BAPI_CREATE_RMS_DOC_INPUT//
wdContext
.currentCreate_Rms_Doc_InputElement()
.modelObject()
.execute();
//Get the Document Class and Object Id of the new RMS document//
Zpm9_Bapi_Create_Rms_Doc_Output output =
input.getOutput();
String doc_class = output.getDocumentclass();
String doc_id = output.getObjectid();
if (doc_class != null && doc_id != null &&
doc_id.length()>0) {
msg_mgr.reportSuccess(
"Document "
+ file_elem.getNAME()
+ " created with Object ID "
+ doc_id);
/*Delete the file from KM folder*/
res.delete();
} else {
String msg_error = output.getError_Msg();
msg_mgr.reportWarning(
"Document "
+ file_elem.getNAME()
+ " is not created");
msg_mgr.reportException(msg_error,false);
}
/* Create a link in KM folder*/
//Get the hostname, port and protocol type for Link URL
String hostname =
TaskBinder
.getCurrentTask()
.getProtocolAdapter()
.getServerName()
.trim();
String serv_port =
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 26
Integer.toString(
TaskBinder
.getCurrentTask()
.getProtocolAdapter()
.getServerPort());
String protocol_type =
TaskBinder
.getCurrentTask()
.getProtocolAdapter()
.getProtocolType()
.getType();
String link_target =
protocol_type
+"://"
+ hostname
+ ":"
+ serv_port
+ trans_view_path
+ doc_id
+ trans_view_options;
URL trgt_url = URL.getInstance(link_target);
String link_name = "URL_" + file_elem.getNAME();
if (wdThis.checkDuplicate(link_name) == true) {
//Add dTimestamp to the name if the name is already existing
SimpleDateFormat dateFormat =
new SimpleDateFormat("yyyy-MM-
dd_HH:mm:ss");
Date currentdate = new Date();
String date = dateFormat.format(currentdate);
String new_name =
date.concat("_").concat(link_name);
IResource link_res =
songsFolder.createLink(
new_name,
trgt_url,
LinkType.EXTERNAL,
null);
} else {
IResource link_res =
songsFolder.createLink(
link_name,
trgt_url,
LinkType.EXTERNAL,
null);
}
}
}
} catch (Exception ex) {
msg_mgr.reportMessage(
IMessageSend.RFC__ERROR,
new Object[] { ex.getMessage()},
false);
msg_mgr.reportException(ex.toString(),false);
} finally {
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 27
//Releasing the connection//
Bapi_Create_RMS_Doc send_mod =
(Bapi_Create_RMS_Doc) WDModelFactory.getModelInstance(
Bapi_Create_RMS_Doc.class);
send_mod.disconnectIfAlive();
//@@end
//@@begin others -- Global Variables
String path = " ";
String Bucket_id = "";
int i = 0;
final String trans_view_path =
"/irj/servlet/prt/portal/prtroot/pcd!3aportal_content!2fSAP!2fTemplates!2fiViews!2
fcom.sap.ivu.ppm_portal?System=<SYSTEM_ALIAS>&TCode=ZDISPLAY_RMS_DOC%20P_OBJID=";
final String trans_view_options = "&AutoStart=Yes&&GuiType=WinGui";
private IWDMessageManager msg_mgr = null;
final String cn_admin_name = "cmadmin_service";
//@@end
Create your WD Application Send_Content_App for this WD Component.
Portal Configuration setup
We need to do the below configurations in portal:
Create a system in Portal for your ECC system where your RMS resides.
Create an iview for WD JAVA application Send_Rms_App and place it on the ‘Attachment and Links’ page in PPM portal.
Create an iview for the WD JAVA application Send_Content_App.
Disclaimer
I would mention a few points about this article:
1) It is one-way of achieving the solution as per my experience.
2) This article explains the solution based on PPM 4.5 environment. You can tweak it to use it for your own purpose.
3) There are hardcoded values in the code; they need to be replaced by values as per your scenario.
4) The output UI color is different as it inherits my PPM portal theme.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 28
Output
After implementation you should be able to see a button on top of Attachment and Links screen as shown below:
Note: The screen shows the ‘Attachment and Links’ page of a PPM item with the custom ‘Send to RMS’ button.
On Click of the ‘Send to RMS’ button a new window opens with the files and their details as shown below:
Select the ‘Archive’ checkbox and click on ‘Send Files’ button. The file will be sent to the SAP RMS.
New Link URL_<FILENAME> will be created in the KM folder.
On Click on the link the document can be accessed in a new window.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 29
Related Content
JAVA Docs Reference for NW04
Web Dynpro Model : Backend Access
How to use KM Functionality in Web Dynpro DC
For more information, visit the Web Dynpro ABAP homepage.
Archiving PPM Item Documents to SAP RMS
SAP COMMUNITY NETWORK SDN - sdn.sap.com | BPX - bpx.sap.com | BOC - boc.sap.com | UAC - uac.sap.com
© 2010 SAP AG 30
Disclaimer and Liability Notice
This document may discuss sample coding or other information that does not include SAP official interfaces and therefore is not supported by SAP. Changes made based on this information are not supported and can be overwritten during an upgrade.
SAP will not be held liable for any damages caused by using or misusing the information, code or methods suggested in this document, and anyone using these methods does so at his/her own risk.
SAP offers no guarantees and assumes no responsibility or liability of any type with respect to the content of this technical article or code sample, including any liability resulting from incompatibility between the content within this document and the materials and services offered by SAP. You agree that you will not hold, or seek to hold, SAP responsible or liable with respect to the content of this document.