Add custom service request forms in #ServiceManager2012


Okay,


The service request class can be extended in order to be able to create specific service requests. But how do we keep track of all these extensions ?
Are we going to customise the default service request form ? We’ll quickly reach the limits of the customisations if we dump all the information in one form.


So we decided to do the following :
-> We create a class based on service requests and add the custom properties
-> We create a custom form based on the default service request form and add the custom inputs


This way we get a similar experience for the Analyst (using the custom form) as the End-user (using the self service portal).

We found a lot of information on the web but nothing that described step by step what we wanted to do. So we describe it here in detail.


First we create a new class based on the service request class. Just fire up the authoring console.

Create a new management pack.


Search for the default service request class and select “Inherit from this class” and save in the new unsealed management pack.


Give the class a logical name.



Rename the class in the console ( makes it easier to search later otherwise you’ll have Inhertited from … )


Create the requested properties for example we’ll create ( Firstname, lastname, department, Startdate )


Now create the new form.


Select the newly created class as base class.


Select the correct assembly ( these can be found under the library folder of the service manager 2012 Authoring console installation )


And select the servicerequestForm Type.



Add the requested form controls and bind to the newly created properties.
Tip ! Create an additional tab entry to store all customisations.




Save the management pack.


And now for the tricky part ! ( Thanks to Alexander Markel See : http://social.technet.microsoft.com/Forums/en/customization/thread/68dedc84-fc00-44a0-a842-f2f3f7ce35d3 )


Create a copy of the mp ( hey things could go wrong not ? ) and perform the following modifications :
Add the following block of code after </ClassType> :
<TypeProjection ID=”UserProvisioning_TP” Accessibility=”Public” Type=”CL_SR_User_Provisioning” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemAssignedToUser’]$” Alias=”AssignedTo” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemClosedByUser’]$” Alias=”ClosedBy” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemCreatedByUser’]$” Alias=”CreatedBy” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemAffectedUser’]$” Alias=”AffectedUser” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemRelatesToConfigItem’]$” Alias=”RelatedConfigItems” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemAboutConfigItem’]$” Alias=”AboutConfigItem” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemAboutConfigItem’ TypeConstraint=’System!System.Service’]$” Alias=”AffectedServices” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemRelatesToWorkItem’]$” Alias=”RelatedWorkItems”>
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemAssignedToUser’]$” Alias=”RelatedWorkItemAssignedTo” />
</Component>
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemRelatesToWorkItem’ SeedRole=’Target’]$” Alias=”RelatedWorkItemSource”>
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemAssignedToUser’]$” Alias=”RelatedWorkItemAssignedTo” />
</Component>
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemHasFileAttachment’]$” Alias=”FileAttachments”>
<Component Path=”$Target/Path[Relationship=’SupportingItem!System.FileAttachmentAddedByUser’]$” Alias=”FileAttachmentAddedBy” />
</Component>
<Component Path=”$Target/Path[Relationship=’CoreKnowledge!System.EntityLinksToKnowledgeDocument’]$” Alias=”RelatedKnowledgeArticles” />
<Component Path=”$Target/Path[Relationship=’Catalog!System.WorkItemRelatesToRequestOffering’]$” Alias=”RelatedRequestOffering” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemHasActionLog’ TypeConstraint=’WorkItem!System.WorkItem.TroubleTicket.ActionLog’]$” Alias=”ActionLog” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemHasCommentLog’ TypeConstraint=’WorkItem!System.WorkItem.TroubleTicket.AnalystCommentLog’]$” Alias=”AnalystCommentLog” />
<Component Path=”$Target/Path[Relationship=’WorkItem!System.WorkItemHasCommentLog’ TypeConstraint=’WorkItem!System.WorkItem.TroubleTicket.UserCommentLog’]$” Alias=”EndUserCommentLog” />
</TypeProjection>
</TypeProjections>

The typeProjectionID must be a unique name and will be used to reference the Form tag. The Type must be the same as the class ID.

Math the typeProjectionID with the form ID.

 

If the above procedure is not performed correctly you will recieve this error after opening the form : System.ArgumentException: propertyName See http://blog.scsmsolutions.com/2012/05/propertyname-error-on-form-targeted-to-custom-class/ for additional information.


The different components can be copied from the default service request class, you can view these by exporting the ServiceManager.ServiceRequest.Library.xml.



Now we need to add the necesarry Alias References. ( again these can be found in the ServiceRequestLibrary )

<Reference Alias=”WorkItem”>
<ID>System.WorkItem.Library</ID>
<Version>7.5.1561.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias=”CoreKnowledge”>
<ID>System.Knowledge.Library</ID>
<Version>7.5.1561.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias=”SupportingItem”>
<ID>System.SupportingItem.Library</ID>
<Version>7.5.1561.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias=”Catalog”>
<ID>System.ServiceCatalog.Library</ID>
<Version>7.5.1561.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>



Save the MP and bundle it. See http://jtruher3.wordpress.com/2009/09/03/introducing-management-pack-bundles/ for detailed info about how to bundle an MP.



Now import the mp. ( You should seal it but we didn’t do that here )



Now create a new template used for SR User Provisioning.


Add the required activites. As you notice all the default service request form control are available.


And now test … Create sr from template.



Use the tab to fill in the service request info and provide the requested service.
That’s it … We’ll add the automation workflow using orchestrator in another post.


Enjoy…


P.S. If you have alternative ways of fullfilling these needs for custom service request let me know, it might be that there are other solutions.

6 Responses to Add custom service request forms in #ServiceManager2012

  1. Antoni says:

    Great Blog Post. Thank you! I think you may have an extra / in the first line that caused me some problems , but eventually I figured it out. I think it should be without the slash at the end before the ‘>’. Also I had to replace the ” with ” as cut and past doesn’t like quotes 🙂 . But seems to work well after these small modifications. Cheers!

  2. Rob says:

    Note that the type projections should be after the not

  3. Rob says:

    if you need to add a relationship how do you get the relationship to be exposed to something like a request offering?

  4. […] Add custom service request forms in #ServiceManager2012 @ https://dynamicdatacenter.wordpress.com/ […]

  5. Julio B says:

    Great post! Im new to this and this helped me out alot. I have a bit of a problem. I’ve done the same thing with the change request form and added some required fields. Everything worked 100% except when I go to close the change request I get the following error message:
    Application: System Center Service Manager
    Application Version: 7.5.2905.0
    Severity: Error
    Message: ChangeRequestStatusChangeTaskHandler has parameter that is not valid.
    Parameter name: node.DataTypeCCM_CustomCR

    System.ArgumentException: ChangeRequestStatusChangeTaskHandler has parameter that is not valid.
    Parameter name: node.DataTypeCCM_CustomCR
    at Microsoft.EnterpriseManagement.UI.SdkDataAccess.ConsoleTaskHandler.DoTask(IList`1 navigationNodes, NavigationModelNodeTask task, List`1 parameterList)
    at Microsoft.EnterpriseManagement.UI.SdkDataAccess.ConsoleTaskHandler.DoTask(IList`1 navigationNodes, NavigationModelNodeTask task)
    at Microsoft.EnterpriseManagement.ConsoleFramework.WindowJobRecord.ExecuteBackgroundJob(Object sender, ConsoleJobEventArgs eventargs)
    at Microsoft.EnterpriseManagement.ServiceManager.UI.Console.ConsoleJobExceptionHandler.ExecuteJob(IComponent component, EventHandler`1 job, Object sender, ConsoleJobEventArgs args)

    Any ideas?
    Julio B

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.