Can you imagine a new way to get support from SAP, without the need to search for notes in SMP or opening an incident because you can’t find a code correction for a specific error?

 

With this opened question we started our presentation on “Automated Note Search Tool” (ANST) during the ASUG Ontario Chapter last November. The reaction from the audience was “It sounds great!!”, and it really IS great.

 

As you may know, ANST is new approach to help out customer searching for notes and also for troubleshooting and root-cause analysis for of any SAP related issue within ABAP environments.

 

The fact you don’t have to identify keywords to do the search in SMP or double-check if you can or can’t implement a note, makes ANST a very powerful tool for our customers, saving them time and eliminating re-work.

 

If it won’t be enough, customer does not have to wait for an SAP Engineer to review and provide feedback about a known bug. Check out the following diagram for the complete work flow revolutionized by ANST:

Blog #2.png

 

The tool was not only for note searches but also about customer code and customizing tables and how following this simple process makes the difference, saving time and efforts they would have otherwise have to spend in an incident/message.

 

It was an amazing experience to get in touch with our customers and show them life demos where they can validate how this tool works and how their work (and life) can be easier. If you want to learn more about ANST please take a look at the following videos ANST @CRM and ANST @ECC.


Background of this blog


The reason to write the blog is recently we found that in several CRM projects in China, the ABAP Webdynpro is wrongly chosen by local partners as custom devopment UI technology, which has caused several issues after project is on line and led to huge maintenance effort. Many partners choose ABAP Webdynpro because they are more familiar with it and they consider Webclient UI has performance issue compared with ABAP webdynpro.


in my previous blog Webclient UI vs ABAP webdynpro - performance loss in BOL / Genil Layer discussion I made some performance discussion regarding CRM Webclient UI and ABAP webdynpro and finally my conclusion is when talking about CRM custom development, we should always stick to Webclient UI technology and avoid the ABAP webdynpro if possible.


In this blog, I will try to collect issues if ABAP Webdynpro is unfortunately used in CRM application. Feel free to raise your parts, if they are not mentioned here


Issue list

Some of the issues described here do not immediately make the application stop working, but can lead to potential issues in the future, make the application unstable, or cause inconsistent user experience for end users. All of these inconsistency makes your application really inprofessional.


Back Button

in CRM UI, there is a Back button in top right part of window, and UI developers could implement page navigation and back ( so called breadcrumb )  by implementing respective methods defined in Component Workbench.

clipboard1.png

Of course this is not available for ABAP webdynpro components. After ABAP webdynpro component is integrated CRM UI, end user would see two Back buttons - the red one is CRM standard one, and the green one is developed by developers on their own.

clipboard2.png

The issues would be:

These two buttons will make end user confused.

Additional effort must be paid to implement the back button function by developers.

It is technically impossible to register an ABAP webdynpro UI component to CRM Breadcrumb framework, so when the red button above is clicked, end user will not return to the expected search view, but to home page instead. This makes sense, since CRM Breadcrumb framework does not recognize the ABAP webdynpro component at all.


Data loss handling

in CRM webclient UI, you can follow the wiki to implement data loss. The steps are quite simple, as most of tasks are done by UI framework.

When you make some changes on UI without save and plan to navigate to other UIs for example by clicking other work center in the left navigation bar, the data loss dialog will be popped up automatically.


clipboard3.png

It is difficult to implement data loss scenario in ABAP webdynpro(See SCN discussion here). Developer have to take care the logic how to detect the ABAP webdynpro UI element is changed, which has already been done by CRM UI framework. Developers have to write lengthy and dirty code to achieve it.

The toggle between display and edit mode

In Webclient UI framework, the edit button plus switching all editable UI elements to edit mode is quite simple:


 

  method EH_ONEDIT.

    DATA:   lr_entity             TYPE REF TO cl_crm_bol_entity.


    lr_entity ?= me->typed_context->socialpost->collection_wrapper->get_current( ).


    CHECK lr_entity IS NOT INITIAL.


    IF lr_entity->lock( ) EQ abap_true.

      me->view_group_context->set_all_editable( ).

    ENDIF.

  endmethod.

The task to switch the element into edit mode is done by method set_all_editable.

However, in ABAP webdynpro you need to do all of these tasks by yourself: The read only properties of all editable UI elements must be bound to a new context attribute POST_LOCKED, and you also need to set the content of that attribute every time the object is locked or unlocked.

clipboard4.png

clipboard5.png

Session issue

For example, when we log on to CRM system via a business role:

clipboard6.png

use tcode SM04, we observed there is only one user session for the current UI:

clipboard7.png

When we go to the integrated ABAP webdynpro page:

clipboard8.png

Go to SM04 again, we can observe there is a new user session generated for ABAP webdynpro, which means the ABAP webdynpro UI resides in a different user session, whereas the left CRM UI page in the original user session.

clipboard9.png

The technical session isolation makes it difficult to exchange data between ABAP webdynpro UI and CRM webclient UI, as they are residing in two different user sessions.

clipboard10.png

if you need to pass data from CRM UI page to embedded ABAP webdynpro UI, One approach is to define the parameters in ABAP webdynpro applications, fill those parameter in CRM and populate the URL containing the passed parameter via cl_wd_utilities=>construct_wd_url:

clipboard11.png

clipboard12.png

However, this approach is not appropriate to pass large amount of data like internal tables. It is also difficult to pass data from ABAP webdynpro back to CRM UI. What's more, careful coding is necessary to ensure a consistent transaction state.


Inconsistent configurability

 

By clicking the configuration icon, we can directly enter configuration mode to make adaptations on UI layout:

clipboard13.png

clipboard14.png

clipboard15.png

When an ABAP webdynpro is displayed, the configuration icon is still enabled.

clipboard16.png

However, since it makes completely no sense to configure an ABAP webdynpro component via Webclient UI framework, once the icon is clicked,

We only get one notification saying currently no UI part is configurable.

clipboard17.png

ABAP webdynpro UI component configuration has a different development mechanism than Webclient UI. The coexistence of both leads to an inconsistent configuration experience for the end user.

clipboard18.png

Location of message area

The message raised in ABAP webdynpro via message manager will appear by default on top of the application UI page,

clipboard19.png

Whereas in CRM Webclient UI, the message appears in the right top of the UI framework, and the message text could also be collapsed or expanded by the small triangle.

clipboard20.png

Put the mouse onto the message text, then the technical information of the message could be displayed as tooltip, which is not available for the message raised by ABAP Webdynpro.

clipboard21.png

Incorrect use of underlying layer API

Let's review the benefit of using Webclient UI framework:


 

  • The object oriented BOL API is simple, generic, uniform and easy to use.
  • Your UI components are decoupled from any interface changes in the underlying application specific APIs, it is even not necessary for you to know the detail of underlying API at all; Your application is easier to maintain and sustainable for future development
  • Development of WEBCUIF applications is made easy, since the BOL has been designed to work hand in hand with the UI parts of the framework
  • The built-in buffer accelerates your applications: Once data it is read, the Object is buffered and could be retrieved in nearly no time. Way faster than calling various function modules again and afterwards preparing the data for business use.

 

so if you choose ABAP webdynpro, you will lose all of these benefits: Your UI component would bypass the BOL & Genil Layer and directly struggle with the underlying API.

clipboard22.png

When I am supporting customer on site customer has complained to me about the "poor quality" of FM CRM_ORDER_MAINTAIN. They directly call this FM in their ABAP webdynpro view controller and complain it does not work as expected. After investigation in their system with quite a time, finally I find it is caused by the inproper importing parameters passed in. Such issue could have been avoided if using BOL API in UI layer - you just need to fire the very simple and generic BOL API and all left things like interaction with the complex underlying API will be handled by Genil implementation. Such UI component will them be easier to maintain and more robust.


Conclusion


When you plan to fulfill the customer requirement by developing ABAP webdynpro and integrating them into CRM UI( via transaction launcher), please always think twice whether it is really necessary. If you decide to do this, you have to confront with all troubles described in this blog. Please kindly raise your findings, if it is not included in this blog



Background of this Blog


For several CRM projects in China which I am involved, I found the partner have chosen ABAP webdynpro when custom development is necessary. When asked why they do not consider webclient UI as the first choice, they argued that "Webclient ui is slower than ABAP webdynpro." or "the performance of Webclient UI is bad compared with ABAP webdynpro, since it has additional layers as BOL and Genil". From my point of view, such conclusion without concreate performance benchmark does not make too much senses.


clipboard1.png

Let's do not consider what we can benefit from webclient ui framework( for example better achitecture, cleaner code, better Maintainability, consistent session magement, consistent navigation management etc ) for the moment. I would like to figure out what is the percent of performance loss caused by additional layers introduced in webclient UI framework - the BOL and Genil. So I made the following performance testings.

 

Test Preparation

I have created one webclient UI component and one ABAP webdynpro component. Both have the exactly the same functionality:

 

  • Click search button to get several BO instance ( Social post) in result table. I choose the new Genil model named CRMSM delivered in CRM7.0 EHP3, as the structure of it is quite simple.
  • Click post ID hyperlink of one search request row, then we can navigate to detail page.
  • Click Edit button in detail page to switch to change mode, make some changes on post content, click save button to persist the change.

 

In the webclient UI component, I ensure that the view controller only calls methods defined in BOL interface, like cl_crm_bol_core~query and modify, cl_crm_bol_entity~set_property and get_property, and if_bol_transaction_context~save. In ABAP webdynpro UI component, I directly call the lower layer function modules SOC_POST_SEARCH, SOC_POST_MODIFY and SOC_POST_SAVE in view controller method.

 

The ABAP webdynpro search page looks like below:

clipboard2.png

CRM webclient UI Search page:

clipboard3.png

ABAP webdynpro detail page:

 

clipboardd.png

Webclient UI detail page:

clipboard5.png

Test using STAD


Note: The aim to use STAD for comparison here is not to get the overhead caused by Additional Layer Overhead, but just give the end user a concrete impression that, the performance of the two different UI technology, ABAP Webdynpro and Webclient UI, resides in the same order of magnitude.


Then I compare the response time of both application via STAD. Below is the performance data of Search button click. We observed the memory consumption of webclient UI component is almost twice than ABAP webdynpro. This makes sense since webclient UI framework needs additional memory to store the model metadata in the runtime and also for objects necessary for BOL / Genil framework processing.

1search time.png

And this is the performance data of post ID hyperlink click. Here webclient UI is slower than ABAP webdynpro, however the absolute time is less than 1 seconds, which does not make too much difference from end user point of view.

clipboard7.png

This performance data is for Edit button click. Again webclient ui is slower, total time less than 1 seconds.

clipboard8.png

This is for save button click:

clipboard9.png

Test using SAT


From this rough test, we are still not clear about what is the exact performance loss caused by the additional layers in webclient UI compared to ABAP webdynpro. So I plan to SAT to do more accurate performance testing using the following categories. I choose three Genil Models in CRM, the technical name of the model is CRMSM, PROD and BT accordingly. I want to know the percent of execution time spent in BOL & Genil layer compared with the total execution time of Search, Modify and Save. ( Category Modify means the property of a Genil model node is only changed in buffer. The change will not persisted into database until save call is performed ).

clipboard10.png


o(x): Additional Layer overhead of a given BOL model x

f(x): absolute execution time spent in BOL and GenIL layer

a(x): absolute execution time of application API


Post Search

I have written the following report to perform Social post search via cl_crm_bol_core~query. Then I can get the exact time spent on a(x)|x=CRMSM and calculate the o(x)|x=CRMSM.

 

 

REPORT  ZSAT_POST_SEARCH.

PARAMETERS: po_id type socialdata-internal_id,

            maxhit type i.

DATA: lo_core               TYPE REF TO cl_crm_bol_core,

      lo_collection         TYPE REF TO if_bol_entity_col,

      lo_root_entity        TYPE REF TO cl_crm_bol_entity,

      lv_view_name          TYPE crmt_view_name,

      lv_query_name         TYPE crmt_ext_obj_name VALUE 'PostSearch',

      lt_query_parameter    TYPE crmt_name_value_pair_tab.

START-OF-SELECTION.

  SHIFT po_id RIGHT DELETING TRAILING space.

  IF po_id NE space.

    DATA(ls_query_parameter) = VALUE crmt_name_value_pair( name = 'INTERNAL_ID' value = po_id ).

    APPEND ls_query_parameter TO lt_query_parameter.

  ENDIF.

  IF maxhit EQ space.

    maxhit = 100.

  ENDIF.

  ls_query_parameter = VALUE #( name = 'MAX_ROWS' value = maxhit ).

  APPEND ls_query_parameter TO lt_query_parameter.

  lo_core = cl_crm_bol_core=>get_instance( ).

  lo_core->load_component_set( 'CRMSMT' ).

  lo_collection = lo_core->query(

      iv_query_name               = lv_query_name

      it_query_params             = lt_query_parameter

      iv_view_name                = lv_view_name ).

  DATA(lv_size) = lo_collection->IF_BOL_BO_COL~SIZE( ).

  WRITE:/ 'Number of ' , lv_size, ' Posts has been found!'.

 

 

Here is the result for Social post search:

clipboard12.png

clipboard13.png

Total execution time of post search: 934 milliseconds

 

Overhead in Additional Layer: 218( spent on component set loading) + ( 634 – 234 – 289 ) = 329 ( 35% in total time ).

Considering that the component set load will only be performed once in the application lifetime, and it would be further improved by using share memory to store model metadata, so I do not regard the time spent on component set loading as overhead. As a result, the final overhead is 329 - 218 = 111 milliseconds, that is 12% of total time.

 

 

Post Modify

clipboard14.png

 

Total time in Post Modify: 55

 

Overhead in Additional Layer : 55 – 53 = 2 ( 3.6% )

 

Post Save

clipboard15.png

 

Total time in Save & Commit: 13 + 6 = 19

Overhead in Additional Layer : (13 – 12) + ( 6 – 3 ) = 4 ( 21.1% )

 

clipboard16.png

clipboard17.png

 

Total execution time: 2348 milliseconds

 

Overhead in Additional Layer : 896 – 348  = 548 ( 23.3% )

 

Product Modify

clipboard18.png

 

Total execution time: 58

 

Overhead in Additional Layer: 58 – 52 = 6 ( 10.3% )

 

Product Save

clipboard19.png

 

Total time in Save & Commit: 282 + 263 = 545

 

Overhead in Additional Layer : (282 – 280) + ( 263 – 41 – 97 ) = 127 ( 23.3% )

 

Note: 97 milliseconds spent on program SAPMSSY4 should be deducted since it contains the execution of routines registered on COMMIT, such as middleware logic, the workflow event, update function module etc. Those are nothing to do with BOL & Genil framework processing.

 

clipboard20.png

clipboard21.png

 

Total execution time: 1160 milliseconds

Overhead in Additional Layer : 658 – 608  = 50 ( 4.3% in total time )

 

Sales Order modify

clipboard22.png

clipboard23.png

 

Total execution time: 105

 

Overhead in Additional Layer : 105 – 93 = 6 ( 11.4% )

 

Sales Order save

clipboard24.png

clipboard25.png

clipboard26.png

Total time in Save & Commit: 6202 + 354 = 6556

Overhead in Additional Layer: (6202 – 6199) + ( 354 – 24 – 175 ) = 158 ( 2.4% )

 

Conclusion

 

The testing result about overhead percent for the three Genil Model could be found in below graph:

clipboard27.png

clipboard28.png

 

clipboard29.png

According to the formula, the more complex the application API is, the less performance loss caused by additional layer overhead in Web client UI. Also in reality, the performance bottleneck resides in application API, not in the call stack of BOL & GenIL delegation. So in my opinion, performance reason should NEVER be used as the excuse when you do not use Webclient UI as the first choice for custom development in CRM.


What we can benefit from BOL& GenIL

  • The benefit to use Webclient UI framework in CRM custom development is apparent:
  • The object oriented BOL API is simple, generic, uniform and easy to use.
  • Your UI components are decoupled from any interface changes in the underlying application specific APIs, it is even not necessary for you to know the detail of underlying API at all; Your application is easier to maintain and sustainable for future development
  • Development of WEBCUIF applications is made easy, since the BOL has been designed to work hand in hand with the UI parts of the framework
  • The built-in buffer accelerates your applications: Once data it is read, the Object is buffered and could be retrieved in nearly no time. Way faster than calling various function modules again and afterwards preparing the data for business use.

 

Taken these benefits into consideration, in my opinion, the gain outweighs the minor performance overhead in additional BOL & Genil layer, if we always stick to Webclient UI in CRM custom development.

 

Please kindly let me know your opinion on this topic. Thank you very much!

SAP Fiori is everywhere these days. If you don't know what it is, I'd recommend to go through a few blog posts available here on SCN (non exhaustive list):

What is SAP Fiori

Fiori arrives - first impressions and thoughts

What is SAP Fiori? Maybe it's more than you think

SAP Fiori Wave 2 is here - so what's new ?

 

To sum it up very quickly Fiori allows end users to access some "transactions" from their mobile phone, tablet or desktop with the same user experience. All you need is a browser recent enough to display HTML5. As a SAP CRM consultant I wanted to give it a try and see what we can get with those ~10 apps dedicated to sales representatives... And the good news is: a few weeks ago I noticed this big orange button on http://marketplace.saphana.com/Line-of-Business/Sales/SAP-Fiori/p/3570 to try Fiori for free!

pict1.png

In fact this button never worked for me: I was just directed to a page asking me to actually buy the whole package... So I contacted someone from SAP support, who asked me to contact someone else who knew the guy that heard someone tried Fiori etc. (you got my point :-) But in the end I could finally get the links I was looking for (thank you Mr. Enrique Espinosa):

www.sap.com/natrysapfiori (americas)

www.sap.com/emeatrysapfiori (emea)

www.sap.com/apjtrysapfiori (asia pacific)

 

If you click on one of those links (depending on your location) and enter promotion code TRYFIORI during checkout, you'll be able to download everything you need to install SAP Fiori applications on your CRM system to test it during 45 days for free.

 

Edit 15th May 2015: links are not working anymore. You may wait for the cloud trial version to be released instead: SAP Fiori, Demo Cloud Edition

 

That's what I did, except that I didn't have any CRM7.0 EhP3 (minimum required) available. So I created a virtual machine on my laptop running Win7 64bits, with 8Go RAM and 120Go free hard drive. I must admit that the installation process went quite smoothly until I had to download support packages: can you believe that you need someone to "approve" your download basket via Solution Manager? I'll probably write another blog post about it because obviously I didn't need to install SolMan to complete my installation, however I did had to contact a friend with a valid user on SolMan to be able to download the needed files from SAP Service Marketplace (which makes me think that this is a cra**y piece of software otherwise SAP wouldn't have to force people to use it).

 

Anyway, now it's working fine so I began to create a series of video showing what it looks like. I'll update this blog post as soon as new videos are ready to go so don't forget to click the "follow" button or "receive email notifications" on the right hand side of the page if you want to get notified when new stuff is out :-)

Video 1 >> SAP FIORI for CRM: Getting started

Video 2 >> SAP FIORI for CRM: My appointments

Video 3 >> SAP FIORI for CRM: My appointments app vs WebUI calendar

Video 4 >> SAP FIORI for CRM: My accounts

Video 5 >> SAP FIORI for CRM: My tasks

Video 6 >> SAP FIORI for CRM: My opportunities

 

Enjoy!

PS: for the record after everything was up and running, I downloaded the following OSS notes to fix a few bugs:

1878995    LPD: Display of further attributes in LPD_CUST

1907696    New synchronization functions in the launchpad

1927493    Mapping Formats are saved inconsistently

1928317    News Tile Drill Down image correction

1929563    ACE Checks for Contacts and Accounts

1930670    BP_SRV: Runtime error GETWA_NOT_ASSIGNED in FSBP_CNS_TYPE_HA

1930684    KPIs for Account FactSheet not available

1930800    Performance improvement 'resolvelink'in INTEROP Service

1930931    My Leads: Filtering the Search Results

1931051    SAPUI5 upgrade to version 1.16.4

1931635    Hotfix for UI AddOn 1.16.4 SC: UI2_SRVC

1931654    UI2_FND (SP06): Improving performance of Fiori Startup Page

1933579    UI2_FND, UI2_700 (SP06): Improving performance of UI2 Intero

1939288    Hotfix for UI AddOn 1.16.5

1939404    HTML 5 compability for IE 9 - meta tag "http-equiv" in "head" of popup; popup looks empty when loading pdf

Actually the code of this example comes from a Thoughworker in China and this is his blog.

I just move his code to a BSP component. Feel free to have a look at his blog directly, in case you understand Chinese

 

Once the bsp application is launched, all the tags will move in an ellipse trace:

 

 

clipboard1.png

clipboard2.png

clipboard3.png

To achieve it you just need a BSP component with a simple view:

clipboard4.png

paste the html source below to main.htm:

 

<%@page language="abap"%>
<%@extension name="htmlb" prefix="htmlb"%>
<script type="text/javascript" src="test.js"></script>
<div id="tagCloud">
<style type = "text/css">
  #tagCloud {
    height: 300px;
    width: 600px;
    position: relative;
    margin: 0;
    overflow: hidden;
}
#tagCloud a {
    position: absolute;
    text-decoration: none;
    color: #0B61A4;
    text-shadow: #66A3D2 1px -1px 1px;
}
</style>
    <ul>
        <li><a href="#">ABAP</a></li>
        <li><a href="#">BSP</a></li>
        <li><a href="#">Webdynpro</a></li>
        <li><a href="#">RFC</a></li>
        <li><a href="#">Interaction Center</a></li>
    </ul>
    <script type="text/javascript">
          var tagCloud = new JsTagCloud({ CloudId: 'tagCloud' });
          tagCloud.start();
    </script>
</div>

 

Note:

a. define an CSS ID selector "tagCloud". It is used as the container for all tag clouds. Specify a default width and height. Set position property to relative.

b. define an CSS class selector for tag cloud. The position is set as absolute, as we will change X and U coordinate of tag cloud elements by Javascript.

 

Create an text file locally and paste the javascript code below into it:

 

function JsTagCloud(config) {
    var cloud = document.getElementById(config.CloudId);
    this._cloud = cloud;
    var w = parseInt(this._getStyle(cloud, 'width'));
    var h = parseInt(this._getStyle(cloud, 'height'));
    this.width = (w - 100) / 2;
    this.height = (h - 50) / 2;
    this._items = cloud.getElementsByTagName('a');
    this._count = this._items.length;
    this._angle = 360 / (this._count);
    this._radian = this._angle * (2 * Math.PI / 360);
    this.step = 0;
}
JsTagCloud.prototype._getStyle = function(elem, name) {
    return window.getComputedStyle ? window.getComputedStyle(elem, null)[name] :
            elem.currentStyle[name];
}
JsTagCloud.prototype._render = function() {
    for (var i = 0; i < this._count; i++) {
        var item = this._items[i];
        var thisRadian = (this._radian * i) + this.step;
        var sinV = Math.sin(thisRadian);
        var cosV = Math.cos(thisRadian);
        item.style.left = (sinV * this.width) + this.width + 'px';
        item.style.top = this.height + (cosV * 50) + 'px';
        item.style.fontSize = cosV * 10 + 20 + 'pt';
        item.style.zIndex = cosV * 1000 + 2000;
        item.style.opacity = (cosV / 2.5) + 0.6;
        item.style.filter = " alpha(opacity=" + ((cosV / 2.5) + 0.6) * 100 + ")";
    }
    this.step += 0.007;
}
JsTagCloud.prototype.start = function() {
    setInterval (function(who) {
        return function() {
            who._render();
        };
    } (this), 20);
}

 

Then import it via context menu->Create->Mime Object->Import:

clipboard6.png

In the javascript we first get the radian of each tag cloud element, and change its X and Y coordinate, that is left and top property based on calculation on it from time to time( in 20 millisecond's interval ). The same logic is done on font size, the opacity and Z-Order index so that we got a Pseudo 3D effect: the more the element is near to us, the bigger and more vivid it is, and vice visa.

There is a good blog about how to get PDF preview in CRM web client UI. However several development are invovled in that solution. You have to implement your own ICF node to make PDF displayed in UI, and you have to generate the binary code of PDF by yourself.

 

There is just another approach to achieve the same result but with much less coding by leveraging the standard control "Adobe Interactive form" in ABAP webdynpro. In this way no ICF node implementation, no manual PDF binary code generation, just a few model task.

 

1. Create an form interface in tcode SFP.

clipboard1.png

Choose interface type as ABAP Dictionary-Based Interface.

clipboard2.png

Just create two parameter NAME and SCORE. Activate the interface.

clipboard3.png

2. Create a new form template via tcode SFP.

clipboard4.png

Click "Context"tab, drag the two parameters from Interface to the right part Context ZPF_EXAMPLE and drop there.

clipboard5.png

Click tab Layout, design your form layout. Here I create a caption and two text fields. Bind the data source of the two fields to your form context parameter. Here text field NAME is bound to ZPF_EXAMPLE.NAME and Score field bound to ZPF_EXAMPLE.SCORE.

clipboard6.png

3. Create a new ABAP webdynpro in SE80. A view MAIN will be created by workbench automatically.

Just put a new Adobe Interactive form control into the empty view. You can choose "Insert Element" from context menu and choose "Interactive form"

clipboard7.png

clipboard8.png

Specify the form template name ZPF_EXAMPLE to property "templateSource" created in step2.

clipboard9.png

After that the property "dataSource" is also determined automatically.

clipboard10.png

Click tab "Context", now you should see the two parameters defined in form interface is also displayed in context node of view MAIN.

clipboard11.png

4. Create a new Webdynpro application and assign two parameter NAME and SCORE to it.

clipboard12.png

5. Double click WDDOINIT to implement:

clipboard13.png

The init method will retrieve name and score from application parameter included in url. The url will be populated from CRM webclient UI side.

Till now the development of ABAP webdynpro is finished. You don't care about the PDF generation and display, it will be handled by ABAP webdynpro framework.

 

method WDDOINIT .
  data(lo_node) = wd_context->get_child_node( 'ZPF_EXAMPLE' ).
  DATA: lv_name type string,
        lv_score type int4.
  lv_name = cl_wd_runtime_services=>get_url_parameter( name = 'NAME' ).
  lv_score = cl_wd_runtime_services=>get_url_parameter( name = 'SCORE' ).
  lo_node->set_attribute( name = 'NAME' value = lv_name ).
  lo_node->set_attribute( name = 'SCORE' value = lv_score ).
endmethod.

6. The left task would be quite easy for a CRM UI developer:

 

I create a simple view with two input fields for Name and Score, and one hyperlink.

clipboard14.png

The event handler for hyperlink click:

 

DATA: lr_popup    TYPE REF TO if_bsp_wd_popup,
        lr_cn       TYPE REF TO cl_bsp_wd_context_node,
        lr_obj      TYPE REF TO if_bol_bo_property_access,
        lt_parameters TYPE tihttpnvp,
        ls_params   TYPE crmt_gsurlpopup_params.
  data(lo_data) = me->typed_context->data->collection_wrapper->get_current( ).
  DATA(ls_line) = VALUE ihttpnvp( name = 'NAME' value = lo_data->get_property_as_string( 'NAME' ) ).
  APPEND ls_line TO lt_parameters.
  ls_line = VALUE ihttpnvp( name = 'SCORE' value = lo_data->get_property_as_string( 'VALUE' ) ).
  APPEND ls_line TO lt_parameters.
  cl_wd_utilities=>construct_wd_url(
      EXPORTING
        application_name = 'ZADOBEFORM'
        in_parameters    = lt_parameters
      IMPORTING
        out_absolute_url = mv_url ).
  lr_popup =  me->comp_controller->window_manager->create_popup(  iv_interface_view_name = 'GSURLPOPUP/MainWindow'
                                                                  iv_usage_name          = 'GSURLPOPUP'
                                                                  iv_title               = 'Adobe Interactive Form Control' ).
  lr_cn = lr_popup->get_context_node( 'PARAMS' ).           "#EC NOTEXT
  lr_obj = lr_cn->collection_wrapper->get_current( ).
  ls_params-url = mv_url.
  ls_params-height = '700'.                                 "#EC NOTEXT
  lr_obj->set_properties( ls_params ).
  lr_popup->set_display_mode( if_bsp_wd_popup=>c_display_mode_plain ).
  lr_popup->set_window_width( 700 ).
  lr_popup->set_window_height( 700 ).
  lr_popup->open( ).

Of course you need to add component GSURLPOPUP via component usage.

 

In the runtime after name and score fields are maintained in CRM UI and hyperlink is clicked, the corresponding PDF will be generated and displayed by ABAP Webdynpro framework.

clipboard15.png

Luís Pérez Grau

To BDT or not BDT

Posted by Luís Pérez Grau Dec 10, 2013
ComponentSupport Package
SAP_BASISSAPKB73105
SAP_ABASAPKA73105
WEBCUIFSAPK-73105INWEBCUIF
BBPCRM

SAPKU70204

 

Hi,

 

Recently I was involved in a discussion and in a customer requeriment which required a knowledge I didn't have, BDT.

 

A good starting point what's BDT and how it works is the in the SCN Wiki:

 

Business Data Toolset (BDT) - ABAP Development - SCN Wiki

 

Other recommendation is the SAP Press book:

 

ABAP Objects: Application Development from Scratch - SAP PRESS Bookstore

 

But what's the main problem with BDT? well BDT was meant to extend the BP model, User interface, APIs, etc. from a central perspective, that's really cool but the problem here is the user interface when BDT was designed is based on SAP GUI, as we all know SAP CRM has suffered lots of changes since back then, the whole user framework was replaced by the Web UI, its tools and methodology, so, what now? Well some BDT were replaced by BADIs and  Enhancement points and some others simply not, so the BDT events still working in some scenarios, for example during the maintenance of the BP relationships.

 

Force Child Realtionship(ZZ23REEWRel) when creating Parent(BuilRealtionship)

 

Can we still using BDT? Well I like the concept  "all for one and one for all" enhancing the fronted forgetting about the APIs i think is a very big mistake and with BDT we have this covered, but what about BADIs and Enhancement points? of course if there's a BADI or a Enhancement spot shouldn't be a BDT because SAP should replace it, or because this BADI Enhancement point give us more detail about what we can or can't do and how to do it (the BDT FMs usually doesn't have interface so we need to deal with FG memory, i find this very dangerous as is the path is very open, maybe we don't have the time to really analyze how the stack is working and the real impact of what we performing, IMHO if I lack on documentation I prefer to be restricted by the system architecture/design )

 

All said, I will share with you some tips & ticks:

 

  • To invoke the BDT menu use the code BUPT in SAP GUI
  • In order to trace which events are been called or can be called during a process you can check the FG BDT_MEM_CONTROL searching by the FMs *GET, especially the FM BDT_TBZ1F_GET is the one for reading the FM related to events.
  • Usually BUP*CALLBACK FM will be useful as a bridge to retrieve the "in-memory" data, in order to use them, especially in the BDT scenario, be sure your event is preformed after the standard events/FM which manages the global Memory of the FG  which comprehend the callback FM, one very common example is in the event  DSAVC when the system stores the changes of a relationship in memory the first FRM called the standard FM BUB_BUPR_EVENT_DSAVC once this FM is executed without errors the global variables of the FG will be filled so the FM BUPA_BUT050_CALLBACK will return something. If you place your FM before this one you won't be able to read those values.
  • Analyze, analyze and analyze, take a look to various FM which are placed at the same event which you are enhancing in order to use the correct FM in the correct sequence.


I hope you find this blog helpful.



Cheers!

 

 

Luis


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

Actions

Filter Blog

By author:
By date:
By tag: