In this blog, you’re going to read about how to extend custom logic so that you can bring a specific field and its value from service contracts to service orders that are created through scheduled maintenance plans. We're going to use the business partner “ship-to party” as the example to demonstrate how to do that.
If your company is a service provider, you sign service contracts with your customers and place service orders to perform one-time services for your customers. Such service provision can be periodic and scheduled based on maintenance plans. When these service orders are created, the system also copies the data in service contracts (such as contract item, sold-to party, sales org, service org, equipment) to the relevant service orders.
In service business, it’s common that the sold-to party is different from the ship-to party or service recipient defined in the partner functions. Currently the system does not support automatic copying of the ship-to party from a service contract to a service order through a maintenance plan.
You, as a key user (with business role SAP_BR_EXTENSIBILITY_SPEC), can use the business add-in (BAdI) Enhancement of Service Order Generation (CRMS4_MPLAN_SCHEDULING_MODIFY), to extend custom logic for system to automatically copy the required fields to all service orders created. No need of manual change to specific fields in service orders any more!
Go to Custom Logic App
Create an new implementation
Choose the business context "Maintenance Item" and choose the cloud BAdI Enhancement of Service Order Generation (CRMS4_MPLAN_SCHEDULING_MODIFY). Go to the next step to give your implementation a description and an ID.Specify Extension Point
After review, choose Create and then choose Publish.
Review, Create and Publish
Choose Open Code EditorOpen Code Editor
Add code to the Develop tab and choose Save and Publish
Add Code and Publish
Note that using this code the system copies all business partners, not only the ship-to party, to the service orders while creating them through a maintenance plan.
DATA next_item_number TYPE i.
*Get maintenance plan data
SELECT SINGLE maintenanceplan
FROM i_maintenanceplanbasic
WHERE maintenanceplan = @maintenanceplan
INTO @DATA(maintenance_plan).
*Get maintenance item data
SELECT SINGLE maintenanceitemdescription,
equipment,
functionallocation,
product,
serviceordertemplate,
servicecontract,
servicecontractitem,
servicedocumentpriority,
immediatereleaseisblocked, maintenanceitemobjectlist
FROM i_maintenanceitem
WHERE maintenanceitem = @maintenanceitem
INTO @DATA(maintenance_item).
*Get object list of maintenance item
SELECT equipment, functionallocation, product, techobjisequiporfuncnlloc
FROM i_maintitemobjlisttechobj
WHERE maintenanceitemobjectlist = @maintenance_item-maintenanceitemobjectlist
INTO TABLE @DATA(technical_objects).
*Prepare reference objects
LOOP AT technical_objects ASSIGNING FIELD-SYMBOL(<technical_object>).
CASE <technical_object>-techobjisequiporfuncnlloc.
WHEN 'EAMS_EQUI'.
CLEAR: <technical_object>-functionallocation,
<technical_object>-product.
WHEN 'EAMS_FL'.
CLEAR: <technical_object>-equipment,
<technical_object>-product.
WHEN OTHERS.
CLEAR: <technical_object>-equipment,
<technical_object>-functionallocation.
ENDCASE.
ENDLOOP.
SORT technical_objects BY equipment functionallocation product.
DELETE ADJACENT DUPLICATES FROM technical_objects COMPARING equipment functionallocation product.
DELETE technical_objects WHERE equipment = maintenance_item-equipment
AND functionallocation = maintenance_item-functionallocation
AND product = maintenance_item-product.
APPEND VALUE #( equipment = maintenance_item-equipment
functionallocation = maintenance_item-functionallocation
product = maintenance_item-product ) TO technical_objects.
*Get responsible employee from service order template header
SELECT SINGLE responsibleemployee
FROM i_servicedocumentenhcd
WHERE serviceobjecttype = 'BUS2000116'
AND servicedocument = @maintenance_item-serviceordertemplate
INTO @DATA(responsibleemployee).
*Get service order template items
SELECT servicedocumentitem,
servicedocumentitem AS new_item_number,
servicedocumentitemuuid,
parentservicedocumentitemuuid,
originallyrequestedproduct,
servicedocumentitemquantity,
servicedocitemquantityunit
FROM i_servicedocumentitemenhcd
WHERE serviceobjecttype = 'BUS2000116'
AND servicedocument = @maintenance_item-serviceordertemplate
INTO TABLE @DATA(service_template_items).
*Get Service Contract Item Partner details
* Service Contract item partners will be copied onto the created transaction header
SELECT FROM i_servicedocumentitemenhcd AS srv_i_enh
INNER JOIN i_custmgmtpartner WITH PRIVILEGED ACCESS AS _custpartner
ON srv_i_enh~servicedocument = _custpartner~custmgmtdocument
AND srv_i_enh~srvcdocitmpartreferenceitem = _custpartner~custmgmtdocumentitem
AND srv_i_enh~serviceobjecttype = _custpartner~custmgmtobjecttype
FIELDS
srv_i_enh~servicedocument AS srv_con,
srv_i_enh~servicedocumentitem AS srv_con_itm,
_custpartner~custmgmtbusinesspartner AS partner_no,
_custpartner~custmgmtpartner AS partner_guid,
_custpartner~custmgmtpartnerfunction AS partner_fct,
_custpartner~custmgmtpartfunctioncategory AS partner_pft
WHERE srv_i_enh~servicedocument = @maintenance_item-servicecontract
AND srv_i_enh~serviceobjecttype = 'BUS2000112'
INTO TABLE @DATA(serv_itm_contract_partner).
IF sy-subrc = 0 AND serv_itm_contract_partner IS NOT INITIAL.
*Prepare items partner data
LOOP AT serv_itm_contract_partner ASSIGNING FIELD-SYMBOL(<srv_itm_partners>).
serviceorderitempartners_out = VALUE #( BASE serviceorderitempartners_out
( serviceorderitem = <srv_itm_partners>-srv_con_itm
custmgmtbusinesspartner = <srv_itm_partners>-partner_no
custmgmtpartner = <srv_itm_partners>-partner_guid
custmgmtpartnerfunction = <srv_itm_partners>-partner_fct
custmgmtpartfunctioncategory = <srv_itm_partners>-partner_pft ) ).
ENDLOOP.
* Considering Service Contract Item partners shall be passed to the generated document header
MOVE-CORRESPONDING serviceorderitempartners_out TO serviceorderheaderpartners_out.
ELSE.
**Get Service Contract partner details
SELECT FROM i_servicedocumentenhcd AS srvcenh
INNER JOIN i_custmgmtpartner WITH PRIVILEGED ACCESS AS _custpartner
ON srvcenh~servicedocument = _custpartner~custmgmtdocument
AND srvcenh~serviceobjecttype = _custpartner~custmgmtobjecttype
AND _custpartner~custmgmtdocumentitem = '000000'
FIELDS
srvcenh~servicedocument AS srv_con,
_custpartner~custmgmtbusinesspartner AS partner_no,
_custpartner~custmgmtpartner AS partner_guid,
_custpartner~custmgmtpartnerfunction AS partner_fct,
_custpartner~custmgmtpartfunctioncategory AS partner_pft
WHERE srvcenh~servicedocument = @maintenance_item-servicecontract
AND srvcenh~serviceobjecttype = 'BUS2000112'
INTO TABLE @DATA(serv_hd_contract_partner).
IF sy-subrc = 0 AND serv_hd_contract_partner IS NOT INITIAL.
LOOP AT serv_hd_contract_partner ASSIGNING FIELD-SYMBOL(<srv_hd_partners>).
serviceorderheaderpartners_out = VALUE #( BASE serviceorderheaderpartners_out
( custmgmtbusinesspartner = <srv_hd_partners>-partner_no
custmgmtpartner = <srv_hd_partners>-partner_guid
custmgmtpartnerfunction = <srv_hd_partners>-partner_fct
custmgmtpartfunctioncategory = <srv_hd_partners>-partner_pft ) ).
ENDLOOP.
* Considering Service Contract Item partners shall be passed to the generated document items
MOVE-CORRESPONDING serviceorderheaderpartners_out TO serviceorderitempartners_out.
ENDIF.
ENDIF.
*Prepare service order header data
serviceorderheader_out = VALUE #( serviceorderdescription = maintenance_item-maintenanceitemdescription
servicedocumentpriority = maintenance_item-servicedocumentpriority
responsibleemployee = responsibleemployee
servicedocumentisreleased = boolc( maintenance_item-immediatereleaseisblocked = abap_false )
).
*Prepare service order items data
LOOP AT technical_objects ASSIGNING <technical_object>.
LOOP AT service_template_items ASSIGNING FIELD-SYMBOL(<service_template_item>).
next_item_number = next_item_number + 10.
<service_template_item>-new_item_number = next_item_number.
ENDLOOP.
LOOP AT service_template_items ASSIGNING <service_template_item>.
serviceorderitems_out = VALUE #( BASE serviceorderitems_out
( servicedocumentitem = <service_template_item>-new_item_number
parentservicedocumentitem = VALUE #( service_template_items[ servicedocumentitemuuid = <service_template_item>-parentservicedocumentitemuuid ]-new_item_number OPTIONAL )
servicetemplateitem = <service_template_item>-servicedocumentitem
product = <service_template_item>-originallyrequestedproduct
quantity = <service_template_item>-servicedocumentitemquantity
unit = <service_template_item>-servicedocitemquantityunit
referenceobjects = VALUE #( ( mainobject = abap_true
equipment = <technical_object>-equipment
functionallocation = <technical_object>-functionallocation
product = <technical_object>-product ) ) )
).
ENDLOOP.
ENDLOOP.
Now you can go back to test whether the custom logic works for your service orders. Comment with your result below this blog. Good luck!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
17 | |
6 | |
3 | |
3 | |
3 | |
3 | |
3 | |
3 | |
2 | |
2 |