Wednesday, January 26, 2011

Adding attributes to a BOR Object

As mentioned in the previous post, actions can be scheduled according to schedule conditions and started according to start conditions.

Schedule conditions are checked during the saving of the document.
Start conditions are checked when transaction SPPFP is run.

This way, you can influence both whether an action is to be scheduled, and when it is to be executed.

The schedule and start conditions check whether conditions are met based on the context of the document. The context is both the document itself as well as attributes of the document such as the activity partner or the sold-to party or the product assigned to the document.

In some cases you might want to check on conditions that are not available in the standard system such as a marketing attribute of the sold-to party or an attribute of the assigned product.
In these cases, you might consider extending the BOR object with custom attributes.

Your new attribute will be occupied with a value by implementing ABAP code specific for this attribute.

Note that if you extend an object with new attributes, these attributes will be determined every time the object is used, so also outside of the action triggering mechanism.

If for instance you extend the BUS2000126, the coding behind the attribute will be run every time an object is occupied with a certain instance. The system does this all the time, so decent coding is exceptionally important here. You don’t want to lose performance because you have added a custom attribute.

The best way to add attributes is to create a subtype of the object you would like to enhance, and add the attribute here. This way, the standard stays the standard. Make sure that when defining the action definition, you enter your custom object as main object, or you will not be able to use you custom attribute.

Let’s say you want to use an attribute of the activity partner which is not available in the standard BOR object, such as a marketing attribute you have maintained.
This would be the way to do it:

Create a subtype
In transaction SWO1, find the object you would like to extend, in our case the BUS1006005 (business partner CRM). In the menu bar, click the ‘create new subtype’ button. Give the object a name (like ZUS1006005) Enter the details.






Add the attribute to the object
Open the newly created Z-object. Note that all attributes and methods are pink. This means they are inherited from their parent-object.
If you want to create a new attribute, click on the attributes node and click the ‘new’ button.
Enter the attributes properties in the details screen (like data type etc) and continue.

Add the coding to occupy the attribute
Now click on the new attribute, and navigate to the coding by clicking on ‘Program’.
I apologize for the old-school editor, there is unfortunately no way around it.
Check some of the standard attributes to see how SAP usually collects the coding.
In our case we want to read the values of a certain marketing attributes, so I enter the following code:

GET_PROPERTY changing <attribute_value> container.   

DATA: lt_bp_list TYPE TABLE OF crmt_mktbp_guid_range,
  ls_bp_list TYPE crmt_mktbp_guid_range,
  lt_ausp TYPE TABLE OF ausp,
  ls_ausp TYPE ausp,
  lv_partner_guid TYPE bu_partner_guid,
  lt_return TYPE TABLE OF bapiret2,
  lt_kssk TYPE TABLE OF kssk_v0,
  let_bp_list TYPE TABLE OF crmt_mktbp_inob_guid_str,
  lv_atinn TYPE ausp-atinn.


  CALL FUNCTION 'BUPA_NUMBERS_GET'
    EXPORTING
      iv_partner = object-key-businesspartner
    IMPORTING
      ev_partner_guid = lv_partner_guid
    TABLES
      et_return = lt_return.


  IF lt_return[] IS INITIAL.
    ls_bp_list-sign = 'I'.
    ls_bp_list-option = 'EQ'.
    ls_bp_list-low = lv_partner_guid.
    APPEND ls_bp_list TO lt_bp_list.
    CALL FUNCTION 'CRM_MKTBP_READ_KSSK_AUSP'
      TABLES
         it_bp_list = lt_bp_list
         et_ausp = lt_ausp
         et_kssk = lt_kssk
         et_bp_list = let_bp_list
       EXCEPTIONS
         others = 4.


     IF sy-subrc EQ 0.
      CALL FUNCTION 'CONVERSION_EXIT_ATINN_INPUT'
        EXPORTING
          input = '<name of the marketing attribute>'
        IMPORTING
          output = lv_atinn
      .


      READ TABLE lt_ausp INTO ls_ausp WITH KEY atinn = lv_atinn.
      IF sy-subrc EQ 0.
        object- = ls_ausp-atflv.
      ELSE.
        object-<attribute_value>= '0'.
      ENDIF.
    ELSE.
      object-<attribute_value>= '0'.
    ENDIF.
    swc_set_element CONTAINER '' object-<attribute_value>.
  ENDIF.
END_PROPERTY.

Generate the object
When you are confident you have done your work properly, you can generate and release the new object by clicking on the generate button and selecting release object from the menu bar.

Check the attribute is properly occupied.
SWO1 allows you to test an object by occupying the object with an instance. You will now immediately be able to see the outcome of your coding. This also allows you to debug your coding.

Create the delegation relationship between the standard and the new object in SWO6.
when you want to use your own object (like ZUS1006005), you should overrule the standard using SWO6. This way, the system looks at the Z-object instead of the standard BUS. In SWO6, create a new entry for the standard object. In the field 'Delegation type' enter the name of your new BUS object.
Enter the custom object as the main object in the action definition
When you are done coding your new attribute, you can now add it to the action definition, allowing you to use the attribute in the schedule and start condition. In our case though, we should also create a subobject for the BUS200110 (Activity CRM), where we add attribute ZACTIVITY_PARTNER as a related object of the type ZUS1006005 and copy the coding from attribute ACTIVITYPARTNER.

Add the attribute as a condition attribute
In the schedule and start conditions you should now be able to select the new attribute, and use it to determine whether an action should be scheduled and whether it should be executed under certain circumstances.

2 comments:

  1. Hi Pieter,

    This is another one of your excellent posts. It hits home as I've had to do this recently.
    But one question don't you have to also delegate this object using transaction SW06 ? That way the system knows that you will utilize the 'ZUS1006005' instead of using the standard object ?

    ReplyDelete
  2. It has been a while. I think you are right. :-). I am afraid I missed a step. Thanks!

    ReplyDelete