*Parameters: *IV_HEADER_GUID TYPE CRMT_OBJECT_GUID | GUID of a CRM Order Object *IV_BP_OLD TYPE BPARTNER | Business Partner *IV_BP_NEW TYPE BPARTNER | Business Partner *ERROR_OCCURRED Something happened METHOD exchange_partner_db. DATA: lv_partner_guid TYPE but000-partner_guid, lv_partner_number TYPE but000-partner, lv_partner_id TYPE but000-partner, lt_crmd_partner TYPE TABLE OF crmd_partner, lt_crmd_order_index TYPE TABLE OF crmd_order_index, lv_addr_nr TYPE adrnr, lv_addr_np TYPE adrnp, lv_addr_type TYPE addr_type, lv_addr_origin TYPE comt_addr_origin, lv_addr_operation TYPE bu_operation, lv_relation_partner TYPE bu_partner_guid, lv_addr_is_standard TYPE comt_partner_std_bp_address. FIELD-SYMBOLS: <fs_partner> LIKE LINE OF lt_crmd_partner, <fs_order_index> LIKE LINE OF lt_crmd_order_index. *------------------------------------------------------------------------- *Get partner identifications of old partner. SELECT SINGLE partner_guid INTO lv_partner_guid FROM but000 WHERE partner = iv_bp_old. SELECT SINGLE partner INTO lv_partner_number FROM but000 WHERE partner = iv_bp_old. IF lv_partner_number IS NOT INITIAL. CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT' EXPORTING input = lv_partner_number IMPORTING output = lv_partner_id. ENDIF. IF lv_partner_guid IS INITIAL OR lv_partner_number IS INITIAL. *Partner number &1 is invalid. MESSAGE e050(/glb/9gtis_solman) WITH iv_bp_old RAISING error_occurred. ENDIF. *------------------------------------------------------------------------- *Select partner dataset for header. SELECT * INTO TABLE lt_crmd_partner FROM crmd_partner WHERE partner_guid IN ( SELECT p~partner_guid FROM crmd_partner AS p JOIN crmd_link AS l ON ( l~guid_set = p~guid AND l~objtype_hi = '05' AND l~objtype_set = '07' ) JOIN crmd_orderadm_h AS h ON ( l~guid_hi = h~guid ) WHERE h~guid = iv_header_guid AND ( p~partner_no = lv_partner_guid OR p~partner_no = lv_partner_number OR p~partner_no = lv_partner_id ) AND ( p~no_type = ' ' OR p~no_type = 'BP' ) ). *Select partner dataset for item. SELECT * APPENDING TABLE lt_crmd_partner FROM crmd_partner WHERE partner_guid IN ( SELECT p~partner_guid FROM crmd_partner AS p JOIN crmd_link AS l ON ( l~guid_set = p~guid AND l~objtype_hi = '06' AND l~objtype_set = '07' ) JOIN crmd_orderadm_i AS i ON ( l~guid_hi = i~guid ) WHERE i~header = iv_header_guid AND ( p~partner_no = lv_partner_guid OR p~partner_no = lv_partner_number OR p~partner_no = lv_partner_id ) AND ( p~no_type = ' ' OR p~no_type = 'BP' ) ). IF lt_crmd_partner IS INITIAL. *Dataset not found in CRMD_PARTNER. MESSAGE e051(/glb/9gtis_solman) WITH iv_bp_old RAISING error_occurred. ENDIF. *Select index dataset for header or item. SELECT * INTO TABLE lt_crmd_order_index FROM crmd_order_index WHERE header = iv_header_guid AND ( partner_no = lv_partner_number OR partner_no = lv_partner_id ). *------------------------------------------------------------------------- *Get partner identifications of new partner. *Get Partner GUID. CALL FUNCTION 'COM_PARTNER_CONVERT_GUID_TO_NO' EXPORTING iv_partner = iv_bp_new IMPORTING ev_partner_guid = lv_partner_guid EXCEPTIONS partner_does_not_exist = 1 OTHERS = 2. IF sy-subrc <> 0. *Partner number &1 is invalid. MESSAGE e050(/glb/9gtis_solman) WITH iv_bp_new RAISING error_occurred. ENDIF. *Get Address data. CALL FUNCTION 'COM_PARTNER_ADDRESS_DETERMINE' EXPORTING iv_partner = iv_bp_new * iv_std_addr_only = 'X' IMPORTING ev_addr_nr = lv_addr_nr ev_addr_np = lv_addr_np ev_addr_type = lv_addr_type ev_addr_origin = lv_addr_origin ev_addr_operation = lv_addr_operation ev_relation_partner = lv_relation_partner ev_addr_is_standard = lv_addr_is_standard EXCEPTIONS partner_not_defined = 1 partner_does_not_exist = 2 rel_partner_does_not_exist = 3 no_address_found = 4 OTHERS = 5. IF sy-subrc <> 0. *No address data for partner &1 found. * MESSAGE e052(/glb/9gtis_solman) WITH iv_bp_new RAISING error_occurred. ENDIF. *------------------------------------------------------------------------- *Exchange partner. LOOP AT lt_crmd_partner ASSIGNING <fs_partner>. *Exchange partner <fs_partner>-partner_no = lv_partner_guid. <fs_partner>-no_type = ' '. "Now key is a GUID <fs_partner>-display_type = 'BP'. "Enrure that partner is shown as BP *Exchange address. IF <fs_partner>-addr_origin = 'A' OR <fs_partner>-addr_origin = 'C' OR <fs_partner>-addr_origin IS INITIAL. <fs_partner>-addr_nr = lv_addr_nr. <fs_partner>-addr_np = lv_addr_np. <fs_partner>-addr_type = lv_addr_type. <fs_partner>-addr_origin = lv_addr_origin. <fs_partner>-addr_operation = lv_addr_operation. <fs_partner>-relation_partner = lv_relation_partner. <fs_partner>-std_bp_address = lv_addr_is_standard. ENDIF. ENDLOOP. *Correct index table used by reporting. LOOP AT lt_crmd_order_index ASSIGNING <fs_order_index>. <fs_order_index>-partner_no = iv_bp_new. ENDLOOP. *------------------------------------------------------------------------- *Save data to database. UPDATE crmd_partner FROM TABLE lt_crmd_partner[]. UPDATE crmd_order_index FROM TABLE lt_crmd_order_index[]. ENDMETHOD.
Kategorie: SAP CRM & SAP Web Client UI
Tipps und Tricks speziell zu SAP CRM und SAP Web Client UI Funktionen und Features.
Report to add, change or delete Business Partners from/to/of Business Transactions
REPORT ztemp_partner_change. TABLES: bapibus20001_object_id. SELECT-OPTIONS: s_objid FOR bapibus20001_object_id-object_id OBLIGATORY. "Object ID of Business Transaction PARAMETERS: p_pfct TYPE comt_partner_wrk-partner_fct OBLIGATORY, "Partner Function to be changed. p_pnum TYPE but000-partner. "Partner Number (can be left empty to delete partner) *------------------------------------------------------------------------- INCLUDE crm_object_kinds_con. DATA: lv_partner_guid TYPE but000-partner_guid, lt_header_guid TYPE crmt_object_guid_tab, lt_partner_wrk TYPE crmt_partner_external_wrkt, lt_partner_com TYPE comt_partner_comt, ls_partner_com LIKE LINE OF lt_partner_com, lv_partner_handle LIKE ls_partner_com-ref_partner_handle, lt_input_field TYPE crmt_input_field_tab, ls_input_field TYPE crmt_input_field, ls_partner_logical_key TYPE comt_partner_logic_partner_key, ls_input_field_name TYPE crmt_input_field_names, lt_active_switch TYPE crmt_active_switch_t, ls_active_switch LIKE LINE OF lt_active_switch. FIELD-SYMBOLS: <fv_header_guid> LIKE LINE OF lt_header_guid, <fs_partner_wrk> LIKE LINE OF lt_partner_wrk. **Convert Partner Number to Partner GUID. *IF p_pnum IS NOT INITIAL. * * CALL FUNCTION 'BUPA_NUMBERS_READ' * EXPORTING * iv_partner = p_pnum * IMPORTING * ev_partner_guid = lv_partner_guid * EXCEPTIONS * no_partner_specified = 1 * no_valid_record_found = 2 * inconsistent_parameters = 3 * OTHERS = 4. * * IF sy-subrc <> 0. * MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno * WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. * EXIT. * ENDIF. *ELSE. * CLEAR lv_partner_guid. *ENDIF. *Select all business transactions according to selection criteria. SELECT guid INTO TABLE lt_header_guid FROM crmd_orderadm_h WHERE object_id IN s_objid. *Read partner data for all selected business transactions (if partners are already maintained). CALL FUNCTION 'CRM_ORDER_READ' EXPORTING it_header_guid = lt_header_guid IMPORTING et_partner = lt_partner_wrk * ET_EXCEPTION = EXCEPTIONS document_not_found = 1 error_occurred = 2 document_locked = 3 no_change_authority = 4 no_display_authority = 5 no_change_allowed = 6 OTHERS = 7. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. EXIT. ENDIF. *Process every single business transaction. LOOP AT lt_header_guid ASSIGNING <fv_header_guid>. CLEAR ls_partner_com. *Read corresponding partner (if already maintained). We assume that there can be only one per partner function. READ TABLE lt_partner_wrk ASSIGNING <fs_partner_wrk> WITH KEY ref_guid = ref_partner_fct = p_pfct. *Create a new entry to insert partner. IF sy-subrc <> 0. ls_partner_com-ref_guid = <fv_header_guid>. ls_partner_com-ref_kind = gc_object_kind-orderadm_h. "Header ADD 1 TO lv_partner_handle. ls_partner_com-ref_partner_handle = lv_partner_handle. *Take over all data from existing entry to change or delete partner. ELSE. MOVE-CORRESPONDING <fs_partner_wrk> TO ls_partner_com. ENDIF. *Delete partner. IF p_pnum IS INITIAL. CLEAR: ls_partner_com-partner_fct, ls_partner_com-partner_no. *Insert or change partner. ELSE. ls_partner_com-partner_fct = p_pfct. * ls_partner_com-partner_no = lv_partner_guid. * ls_partner_com-no_type = ' '. "Value is a GUID ls_partner_com-partner_no = p_pnum. ls_partner_com-no_type = 'BP'. "Value is a Business Partner Number ls_partner_com-display_type = 'BP'. ls_partner_com-kind_of_entry = 'D'. "Origin: Interface ENDIF. *Do some general data preparations. INSERT ls_partner_com INTO TABLE lt_partner_com. *Build input_fields. MOVE-CORRESPONDING ls_partner_com TO ls_input_field. ls_input_field-objectname = 'PARTNER'. MOVE-CORRESPONDING ls_partner_com TO ls_partner_logical_key. ls_input_field-logical_key = ls_partner_logical_key. ls_input_field_name-fieldname = 'PARTNER_FCT'. INSERT ls_input_field_name INTO TABLE ls_input_field-field_names. ls_input_field_name-fieldname = 'PARTNER_NO'. INSERT ls_input_field_name INTO TABLE ls_input_field-field_names. ls_input_field_name-fieldname = 'DISPLAY_TYPE'. INSERT ls_input_field_name INTO TABLE ls_input_field-field_names. ls_input_field_name-fieldname = 'NO_TYPE'. INSERT ls_input_field_name INTO TABLE ls_input_field-field_names. ls_input_field_name-fieldname = 'KIND_OF_ENTRY'. INSERT ls_input_field_name INTO TABLE ls_input_field-field_names. INSERT ls_input_field INTO TABLE lt_input_field. *Deactivate fieldcheck to change partners which are read-only. MOVE-CORRESPONDING ls_partner_com TO ls_active_switch. ls_active_switch-fieldcheck = abap_true. INSERT ls_active_switch INTO TABLE lt_active_switch. ENDLOOP. *Perform all changes. CALL FUNCTION 'CRM_ORDER_MAINTAIN' EXPORTING it_partner = lt_partner_com it_active_switch = lt_active_switch * IMPORTING * ET_EXCEPTION = CHANGING ct_input_fields = lt_input_field EXCEPTIONS error_occurred = 1 document_locked = 2 no_change_allowed = 3 no_authority = 4 OTHERS = 5. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. EXIT. ENDIF. *Perform transaction save. CALL FUNCTION 'CRM_ORDER_SAVE' EXPORTING it_objects_to_save = lt_header_guid[] * IV_UPDATE_TASK_LOCAL = FALSE it_active_switch = lt_active_switch * IMPORTING * ET_SAVED_OBJECTS = * ET_EXCEPTION = * ET_OBJECTS_NOT_SAVED = EXCEPTIONS document_not_saved = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. *ROLLBACK. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. EXIT. ENDIF. *COMMIT WORK AND WAIT. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = 'X'. *Clear buffers. CALL FUNCTION 'CRM_ORDER_INITIALIZE' EXPORTING it_guids_to_init = lt_header_guid[] EXCEPTIONS error_occurred = 1 OTHERS = 2.
Button to generate and send URL of change request or document
Requirement:
Sometimes you want to send an e-mail with a link to a change request or change document, but there is no feature to generate such a URL / e-mail.
Solution:
In SAP Solution Manager 7.2 such a feature is available as standard feature, but in SAP Solution Manager 7.1 you have to implement it by your own. However it is very easy.
Implementation steps:
- Add button „Link“ to AIC_CMCR_H/AICCMCROverview and AIC_CMCD_H/AICCMCDOverview. To use icons please use report SHOWICON to search for icon_mail (@1S@) or similar. Then use method cl_ai_crm_utility=>get_icon_name to convert it to an icon source.
- Add event to AIC_CMCR_H/AICCMCROverview and AIC_CMCD_H/AICCMCDOverview
- Get admin header data analogous to IF_BSP_WD_TOOLBAR_CALLBACK~GET_BUTTONS
- Get URL by cl_ai_crm_ui_api=>wd_start_crm_ui_4_display. If you want to use Single Sign On (SSO) by using SAP Netweaver Portal redirect, you have to add something as prefix.
- Build mailto URL
- lv_recipient = “.
- lv_subject = |CR { ls_admin_h-object_id }: { ls_admin_h-description }|.
- lv_body = |{ lv_document_url }|.
- lv_url = |mailto:{ lv_recipient }?subject={ cl_http_utility=>escape_url( lv_subject ) }&body={ cl_http_utility=>escape_url( lv_body ) } |.
- set attribute lc_ui_enhancement->bpca_url_to_start
Known issues:
- Solution is working for change documents but not for change requests? Ensure that HTML code of AIC_CMCR_H/AICCMCRHeaderEF is processing lc_ui_enhancement->bpca_url_to_start in correct way analogous to AIC_CMCD_H/AICCMCDHeaderEF (No use of iframe. That is a bug in older releases)
- You want to enable feature for Incidents as well? For incidents the steps are similar (web UI component AIC_INCIDENT_H). Additionally you have to adjust the html web page of AIC_INCIDENT_H/IncidentHeaderEF to process lc_ui_enhancement->bpca_url_to_start.
- You face the issue that Microsoft Outlook is opening only on first click? You face the issue that solution is working only if details form is visible which is not the case if you collapse it or if you are using tile layout? This is a bug in SAP standard. To solve it you have to perform following addition implementation steps:
- Create a new web UI component (Z_LINK_POPUP)
- Create a new form view for it with no context nodes
- Place the HTML source code which is processing lc_ui_enhancement->bpca_url_to_start. You can add additional information. You can also
- Assign view to window. Publish window as interface.
- Define component usage to new UI component in AIC_CMCR_H and AIC_CMCD_H and AIC_INCIDENT_H (ZLinkPopup).
- Improve event implemented before to generate and open a popup with new UI component as content.
That’s all. It is easy. It is working. It helps a lot.
method EH_ONLINK. * Added by wizard: Handler for event 'LINK' DATA: lr_cn TYPE REF TO cl_bsp_wd_context_node, lr_entity TYPE REF TO cl_crm_bol_entity, ls_admin_h TYPE crmst_adminh_btil, lv_portal TYPE string, lv_portlet TYPE string, lv_document_url TYPE string, lv_recipient TYPE string, lv_subject TYPE string, lv_body TYPE string, lv_url TYPE string, lc_ui_enhancement TYPE REF TO cl_aic_ui_enhancment, lr_popup TYPE REF TO if_bsp_wd_popup, lv_title TYPE string. * lv_text TYPE string. *Get Current Business Transaction. lr_cn = me->get_context_node( gc_cn_btadminh ). IF lr_cn IS BOUND. lr_entity ?= lr_cn->collection_wrapper->get_current( ). IF lr_entity IS BOUND. lr_entity->get_properties( IMPORTING es_attributes = ls_admin_h ). ENDIF. ENDIF. *Get URL of document CALL METHOD cl_ai_crm_ui_api=>wd_start_crm_ui_4_display EXPORTING i_guid = ls_admin_h-guid IMPORTING e_link = lv_document_url. *Build mailto URL lv_recipient = ''. lv_subject = |INC { ls_admin_h-object_id }: { ls_admin_h-description }|. lv_body = |{ lv_document_url }|. lv_url = |mailto:{ lv_recipient }?subject={ cl_http_utility=>escape_url( lv_subject ) }&body={ cl_http_utility=>escape_url( lv_body ) } |. *Send result to web ui component. lc_ui_enhancement = cl_aic_ui_enhancment=>get_instance( ). lc_ui_enhancement->bpca_url_to_start = lv_url. **Generate popup. * lv_title = 'Generate e-mail with link to document'(902). * lv_text = lv_url. * CALL METHOD comp_controller->window_manager->create_popup_2_confirm * EXPORTING * iv_title = lv_title * iv_text = lv_text * iv_btncombination = comp_controller->window_manager->co_btncomb_ok * RECEIVING * rv_result = lr_popup. * **Open popup. * lr_popup->open( ). *Generate popup. lv_title = 'Generate e-mail with link to document'(902). CALL METHOD comp_controller->window_manager->create_popup EXPORTING iv_interface_view_name = 'Z_LINK_POPUP/MainWindow' iv_usage_name = 'ZLinkPopup' iv_title = lv_title RECEIVING rv_result = lr_popup. *Open popup. lr_popup->open( ). endmethod.
POPUP.HTML <%@page language="abap" %> <%@extension name="thtmlb" prefix="thtmlb" %> <%@extension name="chtmlb" prefix="chtmlb" %> <%@extension name="bsp" prefix="bsp" %> <%-- <thtmlb:grid cellSpacing = "1" columnSize = "8" height = "100%" rowSize = "6" width = "100%" /> --%> <%-- Check if the pop-up needs to be opened form the BPCA url due to BPCA integration --%> <% DATA: MV_URL_OPENNED TYPE STRING. DATA: lc_ui_enhancement TYPE REF TO cl_aic_ui_enhancment. lc_ui_enhancement = cl_aic_ui_enhancment=>get_instance( ). IF lc_ui_enhancement->bpca_url_to_start IS NOT INITIAL AND cl_http_utility=>is_valid_url( lc_ui_enhancement->bpca_url_to_start ) = abap_true. Concatenate '"' lc_ui_enhancement->bpca_url_to_start '"' INTO MV_URL_OPENNED. %> <script type="text/javascript"> window.open(<%= mv_url_openned %>,"","scrollbars=yes"); window.close(); </script> Microsoft Outlook should open automatically.<br>Please click <a href=<%= mv_url_openned %>>here</a> if not. <% CLEAR lc_ui_enhancement->bpca_url_to_start. ENDIF. %>
Conditional mandatory field checks for tables
In Web UI it is possible to specify mandatory fields which should be checked by Web UI framework on every round trip. This is working for normal fields on details screen as well as for table fields. Developers don’t need to check these fields. They don’t need to create or delete corresponding error messages. Framework is doing it for free.
Please note that fields on detail screen can be configured as mandatory. However configuration is not working for tables. And: Configuration is not working for conditional mandatory fields at all. That is why we sometimes need following solution which is very powerful and easy to implement.
Actions you have to perform as developer:
- Redefine method DO_VALIDATE_INPUT of view controller.
- Perform some checks to find out whether fields are mandatory or not (in case they are not always mandatory).
- Build binding string and attribute path. For tables it is „//<contextnode>/Table[<index>].<fieldname>“. For structure fields it is „//<contextnode>/STRUCT.<fieldname>“ (standard fields from BOL/GenIL) or „//<contextnode>/EXT.<fieldname>“ (AET fields) or „//<contextnode>/<fieldname>“ (virtual fields).
- Register mandatory field by using method POST_MANDATORY_FIELD.
Important remark for tables: Sometimes it happens that mandatory checks are getting confused: Framework is not alerting empty fields or framework is alerting even if fields are not empty. Also custom sorting can be skipped or raising short dumps or just going wrong. In general (and especially in these cases) please ensure that you call method CLEAR_LAST_LINE in method ON_NEW_FOCUS before you perform sorting or mandatory checks.
Please note: SAP Solution Manager IT Service Management has an own solution to perform status dependent mandatory field checks. Maybe if we integrate this check here we would enable the framework to display mandatory fields with red color and star. I haven’t tried it yet. But I would expect this helpful behaviour…
Validate partner types / Restrict partner functions to specific partner types only
In ChaRM and ITSM we are using several partner functions. These partner functions can hold contact partners (external business partners, e.g. Requester), employees (internal end-users, e.g. Developer) and organizational units resp. groups (of internal organizational model, e.g. Support Team).
We want to validate that for partner functions which should hold a organizational unit only organizational units can be maintained/selected. We also want to ensure that employees are always business partners with a valid SAP user id assigned. A contact partner should always be a business partner with the role „Contact Partner“.
However this validation cannot be done in SAP CRM standard, because SAP CRM standard is not supporting the check „Organizational Unit only“.
Solution:
Please create your own partner function types using view cluster COMV_PARTNER_PFT (SM34). Note that „0005 Emloyee“ and „0007 Contact Person“ can be used as it is. But „0008 Person Responsible“, „0016 Support Team“ and „0034 Organization Responsible“ needs to be copied in customer namespace 9XXX and corrected. Please ensure following flags:
- 0005: Not unique at Doc./Item Level, Central Person
- 0007: Not unique at Doc./Item Level, Contact Person
- 9008: Unique at Doc./Item Level, Central Person
- 9016: Not unique at Doc./Item Level, Central Person + Central Person or Org.Unit
- 9034: Unique at Doc./Item Level, Central Person + Central Person or Org.Unit
Please adjust definition of partner functions in view COMV_PARTNER_FCT (SM30) and exchange partner function type by our (new) types. Note that you are not allowed to do this for SAP standard partner functions.
Please note that it can happen that you have to adjust mapping configuration in view AIC_PARTNER_FCT + CRMV_ORLALL_BTIL as well in case you are changing partner function types. This is specific to ITSM/ChaRM only.
Please note that it can happen that you have to configure business partner relationship assignment or that you have to adjust partner determination based on business partner relationship. (Only needed if you are changing partner function type. If you are in parallel changing business partner relationship. If you are using partner determination based on business partner relationship.)
Depending on you changes, it can also happen that you have to run report CRM_INDEX_REBUILD (if order index fields get changed because of partner function type change).
Please modify function module COM_PARTNER_CHECK_MASTER_DATA:
- Check for Central Person: Perform check only if check for „Central Person“ is activated and check for „Central Person or Org.Unit“ is deactivated.
- Check for Central Person or Org.Unit: Perform check only if check for „Central Person“ is deactivated and check for „Central Person or Org.Unit“ is activated.
- Check for Org.Unit (new check): Perform check only if check for „Central Person“ is activated and check for „Central Person or Org.Unit“ is activated. Here check for object type „O“ using function module BP_BUPA_GET_HROBJECT.
If you want, you can use SAP CRM Web UI message replacement feature to replace error messages COM_PARTNER-135 and COM_PARTNER-136:
- Replace “Partner &1 (&2) is neither an employee nor an organizational unit” by “Partner &1 cannot be a &2. Please select a group.”
- Replace “Partner &1 (&2) is not an emloyee” by “Partner &1 cannot be a &2. Please select a person.”
Remark: You can define and use your own partner function types. The given types were just examples.
Remark: This solution is not able to validate a partner function agains a business partner role „Developer“, „Tester“, „Change Manager“ etc. It is not able to validate against corresponding PFCG roles. Therefore this improvement is just a simple but very helpful improvement.