For a complete list of my blogs regarding content management, please see here.

In our CRM social integration project we extract the picture of one tweet from twitter website  and store them in CRM system as attachment.

We are creating attachment in CRM via the approach described in this blog.

 

However, we found the Create by property for an attachment is always hard coded with sy-uname, even we explicitly specify the created_by property when calling

cl_crm_documents=>create_with_table. However our requirement is it should be filled by the screen name in twitter website who posts the tweet.

clipboard1.png

clipboard2.png

 

After some debugging I found the created_by property could only be modified after the attachment is created.

First I query all attachments of a given tweet:

 

     DATA(ls) = VALUE SIBFLPORB( INSTID = iv_guid typeid = iv_bor_type catid = 'BO' ).

 

     CALL METHOD CL_CRM_DOCUMENTS=>get_info

       EXPORTING

          BUSINESS_OBJECT = ls

       IMPORTING

          LOIOS = LOIOS

          phios = phios.

 

Then I use FM SDOK_PHIO_PROPERTIES_SET to change the property

 

 

  DATA(ls_property) = VALUE SDOKPROPTY( name = iv_attr_name value = iv_new_value ).

 

  APPEND ls_property TO lt_properties.

 

 

  LOOP AT phios ASSIGNING FIELD-SYMBOL(<ios>).

 

       ls_header-class =  <ios>-class.

       ls_header-objid = <ios>-objid.

      CALL FUNCTION 'SDOK_PHIO_PROPERTIES_SET'

        EXPORTING

          object_id = ls_header

        TABLES

          properties = lt_properties

        EXCEPTIONS

          NOT_EXISTING = 1

          BAD_PROPERTIES = 2

          NOT_AUTHORIZED = 3

          EXCEPTION_IN_EXIT = 4.

ENDLOOP.

 

I have put the code into a utility class and test it:

 

clipboard3.png

And that's done:

clipboard4.png

Never forget to activate internal mode, or else you will fail with an error message that created_by field is read only.

clipboard5.png


In CRM web client UI we use CL_BSP_WD_MESSAGE_SERVICE to raise message into UI.

clipboard1.png

The service class simply appends the message structure to its internal table.

 

During the final UI rendering phase, the message raised by application code is fetched from internal table of the message class.

clipboard2.png

clipboard3.png

Regarding CL_BSP_MESSAGES, as Thomas Jung has clearly explained here, it has similiar usage as CL_BSP_WD_MESSAGE_SERVICE, that is to queue the message raised by application into its own internal table. However, neither of them are responsible for message display in UI, and the message stored by latter will not be handled by Web client UI component errorview2.htm, so if you have to use your own logic to display the messages.

Just a small example:

clipboard4.png


There is a public attribute message with type CL_BSP_MESSAGES and you can add message as below:

clipboard5.png

It looks not so good compared with the message displayed in the message area handled by CL_BSP_WD_MESSAGE_SERVICE. 

clipboard6.png

For a complete list of all my blogs regarding content management, please see here.
When I am creating attachment for my business object via code provided in solution:

  ls_prop-name = 'DESCRIPTION'.

    ls_prop-value = 'created by Tool'.

    APPEND ls_prop TO lt_prop.

    ls_prop-name = 'CREATED_BY'.

 

    ls_prop-value = XXX - some one else other than sy-uname

    APPEND ls_prop TO lt_prop.

CALL METHOD cl_crm_documents=>create_with_table

      EXPORTING

        business_object     = ls_bo

        properties          = lt_proproperties_attr     = lt_properties_attr

        file_access_info    = lt_file_info

        file_content_binary = lt_file_content

        raw_mode            = 'X'

      IMPORTING

        loio                = ls_loio

        phio                = ls_phio

        error               = ls_error.

I meet with the error below:Characteristic of class CRM_L_DOC is not valid

clipboard1.png


I debugged a little and found it is caused because the content management code regards "CREATED_BY" field as read only ( protected field ) if internal mode is inactive.

clipboard2.png

clipboard3.png


I use where use list on the field internal_mode and found the FM below could activate internal mode with 02 passed into.

clipboard4.png


clipboard5.png

After I call that FM in my program, the error is gone and attachment could be created. Unfortunately, I still could not specify the created_by field, I find it is always filled as sy-uname in line 298.

clipboard6.png

For a complete list of all my blogs regarding content management, please see here.

In CRM Product UI, A thumbnail could be displayed in Product header and Thumbmail assignment block.

clipboard1.png


clipboard2.png


The Thumbnail assignment block is not available in SAP predefined UI configuration. Customer needs to manually make it visible via UI configuration change:


clipboard3.png


The thumbnail view implementation itself is very simple, just use the lib thtmlb image tag.


clipboard4.png

The thumbnail view implementation itself is very simple, just use the lib thtmlb image tag.

clipboard5.png

If a product has multiple attachments, how does the UI know which one should be displayed as thumbnail? The default attachment with type BDS_IMAGE will be choosen.

clipboard6.png

However, these two fields are not available in default standard configuration of GS_CM/EditProp

clipboard7.png

if your application need also allow users to specify these two fields, you can create a new configuration by copying from the one with object type = PRD_MATSRV.

clipboard8.png

For a complete list of all my blogs regarding content management, please see here.

 

During my recent project I found a strange behavior in attachments.

Click the hyperlink of Properties

http://farm3.staticflickr.com/2810/11200858386_bd70a61722_o.png

 

do not change anything, and click back

http://farm3.staticflickr.com/2843/11200843184_97e631df3c_o.png

After back to product overview page, the overview page looks exactly the same before you click Property hyperlink.

However, if you use SM12 to check in backend, you will find the current product is locked, although it still looks as under display mode in UI!

The same behavior could be observed in one order application. I would assume this as a bug.

 

http://farm3.staticflickr.com/2836/11200858266_ac466767ae_o.png

 

By debugging I found the parent node, Product instance, is explicitly locked by content management class.

http://farm4.staticflickr.com/3827/11200966453_9543f35a92_o.png

 

However, in my application I do not need this behavior - in my application, the whole attachment assignment block has read only mode, so I don't want my BO to be locked after property hyperlink is clicked. The solution is very easy: do not bind my BO node to PARENTNODE of content management UI component GS_CM by commenting out the related code:

http://farm3.staticflickr.com/2876/11200966293_91f42ef6a4_o.png

  Yesterday when I am doing my development under interaction center environment, I suddenly find I cannot log on interaction center UI any more.

  

 

http://farm4.staticflickr.com/3754/11187610996_b557606515_o.png

After I choose my business role ZSOCIAL, the UI hangs there with only information "Starting". Ten minutes later, I got a time out error in UI.

http://farm3.staticflickr.com/2814/11187610926_c7dc301ca6_o.png

I did a quick check on my development objects and I can ensure this is not caused by my new development. I checked SM21 and SM50 and could not find any hints.

So again I have to debug to find the root cause. But where should I set breakpoint? Since in principle the component set for IC CRMIC_DEFAULT will always be loaded when IC UI is launched, it will be a good starting point to set breakpoint in method CL_CRM_BOL_CORE=>load_component_set. Soon I found the application will hang once that method is called, so I know I am not far from the truth.

http://farm3.staticflickr.com/2828/11187719943_5d1e891fbb_o.png

In this customizing you can find all components belonging to component set CRMIC_DEFAULT.

 

http://farm4.staticflickr.com/3799/11187719873_cbbe2ab206_o.png

The timeout must come from loading one of these components.

http://farm3.staticflickr.com/2859/11187719723_48fea9c3e9_o.png

Finally I found the component ERP is the trouble maker. The system hangs after I click F6 in line 101.

http://farm3.staticflickr.com/2854/11187609434_7dee258db1_o.png

 

The root cause is that RFC destination EBJCLNT001 does not work, so RFC call hangs until time out occurred.

http://farm6.staticflickr.com/5521/11187609304_b7eacfe6e7_o.png

 

This RFC destination is maintained in this customizing:

http://farm4.staticflickr.com/3756/11187609144_d9ac8e892d_o.png

http://farm4.staticflickr.com/3772/11187609034_590fe3ffae_o.png

For a complete list of all my blogs regarding content management, please see here.

When you create attachments for your business objects via cl_crm_documents=>create_with_table, you have to pass in an internal table for attachment property.
The namelist of attribute name could be got from attachment class via function module SDOK_PHIO_ATTRIBUTES_GET.

For example, attachment class CRM_P_DOC has 36 attributes.

 

http://farm8.staticflickr.com/7344/11187276154_5d528154be_o.png

The attributes could also be viewed in tcode DMWB

http://farm6.staticflickr.com/5547/11187275956_629a1f769f_o.png

The actual attribute value could be got via function module CRM_KW_PROPERTIES_GET:

http://farm8.staticflickr.com/7352/11187275846_c599721d2f_o.png

 

http://farm4.staticflickr.com/3700/11187275766_5006345943_o.png

 

The importing parameters are guid of logical/physical object instances:

http://farm8.staticflickr.com/7421/11187275844_b9e3bede8a_o.png

The attribute values are stored in PROPERTIES internal table.

http://farm4.staticflickr.com/3758/11187385233_729f26c7a5_o.png

 

Do you know why in the backend table, the property is stored in field PROP09?

http://farm4.staticflickr.com/3692/11187385283_ca182ecdc7_o.png

actually it is because I hard code the content of relative url as the attachment file name.

    ls_prop-name = 'KW_RELATIVE_URL'.

    ls_prop-value = iv_file_name.

    APPEND ls_prop TO lt_prop.

http://farm8.staticflickr.com/7325/11187229605_07b858c6df_o.png

 

The index of attribute could also be found in tcode DMWB.

http://farm3.staticflickr.com/2825/11187229635_9e2010bdd2_o.png

For a complete list of my blogs regarding content management in CRM, please see here.

In the beginning I consider it is very easy to delete attachments via code, just like below.

 

I have defined one method with following two importing parameters:

iv_bor_type type string - the BOR type of your business object

iv_uuid type raw16 - the guid of your business object instance

rv_successful type abap_bool - indicates whether the deletion is successful

 

DATA: ls_bo          TYPE SIBFLPORB,
          lt_loios    TYPE SKWF_IOS,
          ls_loios    TYPE SKWF_IO,
          ls_error    TYPE SKWF_ERROR,
          lt_badios   TYPE SKWF_IOERRS,
          lv_del_flag TYPE ABAP_BOOL.
    ls_bo-instid = iv_uuid.
    ls_bo-typeid = iv_bor_type.
    ls_bo-catid  = 'BO'.
    rv_successful = abap_false.
    CALL METHOD cl_crm_documents=>get_info
      EXPORTING
        business_object = ls_bo
      IMPORTING
        loios           = lt_loios.
    LOOP AT lt_loios INTO ls_loios.
      CALL METHOD cl_crm_documents=>lock
        EXPORTING
          is_bo    = ls_bo
          is_loio  = ls_loios
        IMPORTING
          es_error = ls_error.
      IF ls_error IS NOT INITIAL.
         RETURN.
      ENDIF.
    ENDLOOP.
    CALL METHOD cl_crm_documents=>delete
      EXPORTING
         business_object = ls_bo
         ios             = lt_loios
      IMPORTING
         bad_ios         = lt_badios
         error           = ls_error.
    IF ls_error IS INITIAL. " deletion failed
       rv_successful = abap_true.
    ENDIF.

 

Through testing I found it works perfectly well with most of BOR type like product, ibase, BP, and one order.

However, it does not work for my new BOR type CRMSOCPOST in CRM7.0 EHP3 - the relationship between my bo and the attachments is not really deleted until

an explicit call COMMIT WORK is written in the report. However, for any other standard CRM BOR type, the COMMIT WORK is not needed. Why?

 

After some debugging finally I find answer. Have you already observed the comments below? It is written quite clearly: if the business object exists in the database, the COMMIT WORK is not needed.

clipboard1.png

Back to my case, since CRMSOCPOST is a new BOR type created in CRM7.0 EHP3, the function module does not recoginize it, so the code reached line 225, and

then the bo instance is regarded as non-exist in DB. So an explicit COMMIT WORK is always necessary to make deletion work.

clipboard2.png

For a complete list of all my blogs regarding content management, please see here.
I create a utility class with method CREATE_DOC. It has following four input parameters:
iv_data type xstring - the binary data which you would like to store as attachment
iv_bor_type type string - the BOR type of your business object. You can view view business object model in tcode SWO1
iv_guid type raw16 - the guid of your business object instance
iv_file_name type string - the file name which will appear in attachment assignment block.
The source code of method below: ( in fact all attributes for an attachment could be available in the input parameters of this method. For simplicity reason I
just hard code them in the sample code )
DATA:
         ls_bo              TYPE sibflporb,
         ls_prop            TYPE LINE OF sdokproptys,
         lt_prop            TYPE sdokproptys,
         lt_properties_attr TYPE crmt_attr_name_value_t,
         ls_file_info       TYPE sdokfilaci,
         lt_file_info       TYPE sdokfilacis,
         lt_file_content    TYPE sdokcntbins,
         lv_length          TYPE i,
         lv_file_xstring    TYPE xstring,
         ls_loio            TYPE skwf_io,
         ls_phio            TYPE skwf_io,
         ls_error           TYPE skwf_error.
    ls_prop-name = 'DESCRIPTION'.
    ls_prop-value = 'created by Tool'. " replace it with your own description for attachment
    APPEND ls_prop TO lt_prop.
    ls_prop-name = 'KW_RELATIVE_URL'.
    ls_prop-value = iv_file_name. " in the sample code I just reuse file name as relative url
    APPEND ls_prop TO lt_prop.
    ls_prop-name = 'LANGUAGE'.
    ls_prop-value = sy-langu.
    APPEND ls_prop TO lt_prop.
    lv_file_xstring = iv_data.
    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        = lv_file_xstring
      IMPORTING
        output_length = lv_length
      TABLES
        binary_tab    = lt_file_content.
    ls_file_info-binary_flg = 'X'.
    ls_file_info-file_name = iv_file_name.
    ls_file_info-file_size = lv_length.
    ls_file_info-mimetype = 'image/jpeg'. "use the correct mime type for your attachment
    APPEND ls_file_info TO lt_file_info.
    ls_bo-INSTID = iv_guid.
    ls_bo-typeid = iv_bor_type.
    ls_bo-catid = 'BO'.
    CALL METHOD cl_crm_documents=>create_with_table
      EXPORTING
        business_object     = ls_bo
        properties          = lt_prop
        properties_attr     = lt_properties_attr
        file_access_info    = lt_file_info
        file_content_binary = lt_file_content
        raw_mode            = 'X'
      IMPORTING
        loio                = ls_loio
        phio                = ls_phio
        error               = ls_error. " evaluate if there is anything wrong during creation
COMMIT WORK.
I write a piece of code to test it. After report runs I could see the generated attachment.
clipboard1.png
clipboard2.png
You can also test whether the attachment is created successfully in the backend. Test class method get_info in SE24.
Specify importing parameter BUSINESS_OBJECT:
clipboard3.png
clipboard4.png
Execute and you should get result as below: one physical object and one logical object according to how-is-attachment-physically-stored-in-database-table-in-cm-framework.
clipboard5.png
Never forget to call COMMIT WORK in your code, since the persistence of the relationship between attachment and your business object are implemented via generic object service in a update process.You could easily find this via SAT trace on your code
clipboard7.png
or switch on update debugging in your debugger settings.
clipboard8.png

If you want to know more technical detail, please find my blog list here.

 

History:

Content Management(CM) was introduced in basis release 6.10 and implemented in CRM 3.0. Before CM was used, CRM applications was using the Business Document Service (BDS) or Generic Object Services (GOS) to implement Document management requirement. BDS was used in most applications like Business partners, products, product catalogues, solution database, campaigns. GOS was only used in the One Order objects like activities and opportunities. All BDS applications changed to CM in 3.0, the One Order objects only in 3.1.

 

A document in CM consists of several objects. The most important two are so called “logical info object” (LOIO) and a “physical info object” (PHIO). A LOIO as a logical folder or bracket which holds PHIOs together, while a PHIO represents the content of a specific version of a document. Let's use the word edit in the real world as example. If one works on a Word document and changes the document over time, each saved version would be represented by a PHIO. The LOIO would be the word document itself. This is much like if one looks at SE38 in ABAP: The program name is the LOIO and each transported version of the code is the PHIO.

Let's see an example. I have a product ZCM_DEMO with guid 0090FA0D8DC21ED395FD7C687F99BFF7, BOR type = BUS1178.

I create one attachment for it:

clipboard1.png

Go to table SKWG_BREL, input product guid 0090FA0D8DC21ED395FD7C687F99BFF7, and we see two entries belonging to this product. The first entry indicates a folder instance which is actually a logical container to hold all attachments for the given product. 

 

clipboard2.png

The content of column INSTID_B has naming convention as <type: F(older) or L(ogical object)><Logical object type name><guid>.

The guid in the first row can be found in table CRM_FOLDER:

clipboard3.png

The guid 0090FA0D8DC21ED395FD830F8DD9DFFF in the second row can be found in table BDSLOIO22, together with the name of attachment.

 

clipboard4.png

You are asking how I get to know the name of table BDSLOIO22? If one application wants to use CM to store document, it should have its dedicated class for physical object and logical object, or use the default one CRM_L_DOC. The relationship between application and its class is maintained in tcode DMWB:

clipboard5.png

in table BDSPHIO22, by specifying logical information object ID, we can get all phyiscal object lists.

clipboard6.png

once you get phyical object id 0090FA0D8DC21ED395FD830F8DD9FFFF, you can find the respective entries in table BDSCONT22.

clipboard7.png

The real content of attachment is stored in a claster way, so you cannot see its detail in SE16.

clipboard8.png

How do I know the database table name BDSCONT22?

1. Get the storage category BDS_DB22 by physical class name.

clipboard9.png

2. execute function module SCMS_SDOKSTRE_LIST to get all lists of database table. Then you can find the table name BDSCONT22 for your storage category BDS_DB22.

clipboard10.png

Hi Friends,
It is a common requirement that a certain assignment block in overview page should only be displayed under some condition, for example under control of a business switch.
clipboard1.png
Here are three ways which could control the visibility of one assignment block via code.

Approach1: dynamical view detachment

refine method DETACH_STATIC_OVW_VIEWS of the controller class of your overview page. All views put into internal table rt_viewid will be hidden by UI framework in the runtime.The code below just means you can evaludate some condition in line 3, and if the condition is met, the assignment block SearchResult will be hidden.
clipboard2.png

Approach2: dynamic UI configuration load

Create a new configuration within which only Search view is displayed. The configuration is bound to a certain UI object type.
clipboard3.png
Now we have two UI configurations. The standard configuration will display two assignment blocks by default, the configuration with UI object type = CRM_SMC will only display Search view.
clipboard4.png
Implement DO_CONFIG_DETERMINATION:
clipboard5.png
  method DO_CONFIG_DETERMINATION.
  " IF search result view should be hidden
     me->set_config_keys( iv_object_type          = 'CRM_SMC'
                          iv_propagate_2_children = abap_false ).
  " ENDIF
  endmethod.

Approach3: Control the visibility via business switch

This is a most elegant way, however it could only be used if you would like to control the visibility of your view via a business switch.
When you are assigning your assignment view to the view area of Overview page in runtime repository, a business switch can be assigned as displayed in the picture below. If the switch is turned off, the related view will be automatically hidden by UI Framework.
clipboard6.png
After you have assigned a view to the view area of oviewpage, the switch ID is displayed after view name.
ass.png
You could first find the related business function for switch CRM_SOC_SFWS_SMI_2 via tcode SFW1,
clipboarda1.png
then find the business function status in SFW5:
clipboarda2.png
If the business function is deativated, the assignment block will also be hidden automatically.
Divya Gupta

Default text in notes

Posted by Divya Gupta Nov 21, 2013

Hi All,

 

This one takes us back to the basics of CRM, power of text determination procedure. We have been using notes in CRM transactions very
frequently to capture various texts entered by different Users during the process. Through this blog I am trying to showcase one of the old features
available in text determination procedures i.e. access sequence to source the content in the note type.

 

 

In my recent project, I got a requirement from customer where they wanted a default text to appear in the notes. As this note type was to be
used for printing CRM generated letter, it was acting as template for the letter and also it was supposed to be changeable by user during the process and
the changed version of the template should go for printing. As this criteria came into picture, we couldn’t just create a smartform with hardcoded text
instead found the standard way to find solution.

 

Access sequence in text determination procedure can be used in this case.

 

 

Following are the steps to make this work:

 

 

  1. Create the text template using SAPscript Tcode SO10

 

1.png

  Maintain the default text here:

 

1.png

 

2.  Create you text determination procedure and create access sequence for the text type for which the default text has to be sourced:

 

1.png



3. The function has to be created by technical team which has a small code for calling the SAPscript created in step 1:

 

 

Function ZFM_UPLOAD_TEXT

 

 

CLEAR: es_reference.

  es_reference-tdobject = 'TEXT'.

  es_reference-tdid = 'ST'.

  es_reference-tdname = 'ZTEMPLATE'.

  es_reference-tdspras = 'E'.

 

 

Endfunction.

 

 

4. Once the access sequence is created, assign this access sequence to the text type:

 

 

1.png

 

Leave the changes column as empty as you want it to be editable and select value “A” in transfer column for this text type.

 

 

That’s it. When this procedure is assigned to a transaction and when user creates the transaction, the default text appears in the
respective note type (text type) which can be changed by user.

 

1.png

 

A small configuration changed helped us in meeting the requirement. Thought of sharing this as a lot of us sometimes miss these
excellent features available as part of std CRM.

 

Hope you enjoyed revisiting the basics. sometimes it really helps.

With System Upgrade SAP delivers a whole new set of features and functionality to the end users but it takes also takes away some of the GUI transactions from the end users. In case of CRM solutions , the same functionality would be available from the WebUI but for developers it is a pain because it was possible to debug the same functionality easily and with a lesser effort. But now with the transaction not available in the backend , we have to go through the tedious process for debugging through WebUI.

 

I am big fan of SAP tools available in the ABAP backend as they make the task of the developer much much easier. For me it is like playing in the familiar territory and easier to ramp-up on newer areas. For some days I was struggling to understand how to debug Info-sets in Marketing area and I came across transaction CRMD_MKTSEG to perform the segmentation in ABAP backend. But the Transaction was no longer available. So I looked for another system we have and I could execute the transaction CRMD_MKTSEG. Thank god I could run it but then I wanted to run the same transaction in my system to analyze my problem. So I came across an ingenious idea. I did the following

  • I went to the trx SE93 in my another system. The trx CRMD_MKTSEG was available
  • As the transaction was available , so was the underlying program in the se93 transaction information.(  CRM_MKTTG_SEG_UI_START )
  • So I copied the program and ran it in my actual system.
  • And then I continued on doing what I love to do what I love to do-running scenarios from ABAP backend.

 

So if you want don't find a transaction in any system , you just have to look for another system where it runs. Also I was surprised that surprised that SAP just removed the transaction and left the underlying program. Instead it could have easily left it for the developers and put an extra authority object so that only developers could use it.

Hi friends,

 

I am CRM developer in SAP and our team has already integrated twitter ( also facebook ) into interaction center in CRM7.0 EHP3.

 

You can see an example below:

 

Create a tweet in twitter website:

 

 

clipboard1.png

 

Now I can see the tweet created just now in the web site.

 

clipboard2.png

 

And I can also see it in CRM IC agent inbox:

 

clipboard3.png

 

select the first row and I can directly reply it in CRM by clicking reply button:

 

clipboard4.png

 

just click the send button:

 

clipboard5.png

 

after click send button, I can see the reply also in twitter website:

 

clipboard6.png

Here below the screenshot is for Facebook:

 

I create a post in Facebook:

clipboardf1.png

clipboard23.png

And the post could also be found in CRM system:

clipboard24.png

 

if you would like to integrate other social channel than twitter and facebook, you just have to implement your own client class for the new social channel, and all left tasks are centrally done by us from framework side.

 

you can get more detail information from consulting note 1832462 about social integration achitecture. Implementation detail for facebook client class: note 1832481. And note 1832480 for twitter.

 

Update on 2013-11-20 for reply to Kavindra:

 

We have defined a BAdI enhancement spot which you could do your specific analysis on the data extracted from web site.

2clipboard1.png

 

2clipboard2.png

 

We have delivered a sample implmenetation which could calculate the sentiment of the text posted in twitter & facebook like "Positive, Negative, Strong Positive, Neutral", with the help of SAP HANA Text Analysis Engine. Of course you could use your own TA engine within that BAdI enhancement implementation.

2clipboard3.png

 

Welcome to post any questions you have here if you are interested with this topic.


New features available in EHP3 SP4


See the detail here.

Actions

Filter Blog

By author:
By date:
By tag: