Home Cireson Uploads
image


IT Monkey will place code here as examples of what Cireson's consulting team has to offer as well as examples for public consumption to benefit the Microsoft System Center community as a whole.

DISCLAIMER

All files and projects located here come as is and without any warranty or support. We will attempt to improve the projects as time goes on based on customer and community demand. Comments and improvements are welcome as well as customization requests. Your use of these Cireson Uploads is subject to our Terms of Use.


Cireson's support team has no information on these projects outside of what you have available and will not provide support for these enhancements, extensions, and scripts.

Dont forget to checkout solutions uploaded by our customers, partners and community members here.

Convert IR to PR

IT MonkeyIT Monkey O.G.
edited May 2016 in Cireson Uploads

Cireson Web Portal Extension - Convert to Problem Task

 

The Problem 

From the Service Manager Console, you can open an Incident and use the “Create Problem” task to automatically create an associated Problem.  The Cireson Web Portal doesn’t allow this capability out-of-the-box.  If an Incident was created and needed to be converted into a Problem, you would have to create a new Problem and then add the Incident as a Related Item.

The Solution

This capability is available in the Cireson Web Portal with the use of a custom task that utilizes custom JavaScript (ext_ConvertIRtoPR.js) and an HTML template (ext_ConvertIRtoPR_template.html).  The “ext_ConvertIRtoPR.js” file contains 1 main Function and 4 sub functions that I have detailed below.

Function - Form Task

This function adds the “Convert to Problem” task to the Incident Form.


Function – convertIRtoPR

This function is the base function for the task. It defines the problem class ID and then makes a call to the Web API to pull back all available problem templates. It then sends those templates forward to the ‘loadTemplates’ function.


Function - loadTemplates

This function first loads the custom HTML Template “ext_ConvertIRtoPR_template.html”.  It then adds the Problem Templates to the drop-down within the HTML Template.  Next it creates an OK button and adds logic around the click of that button.  It creates a variable that is assigned the value of the selected item in the drop-down.  When OK is clicked, it calls the createProblem function and sends the selected item’s templateid and then closes the window.  There is also a Cancel button created that just closes the window when clicked.  The actual loading of the Window and Binding of the above logic occurs in the var _vmWindow section.


Function - createProblem

This function receives the templateid from the loadTemplates function and sets a variable for the logged in user’s User ID. It then makes a call to the Web API to create a projection by the templateid and the User ID.  This is the part that creates the Problem.  If the call is successful, it copies the Title, Description, Contact Method, Affected User, all related WorkItems, all related Configuration Items, and Created By User from the Incident to the Problem. It also creates a relationship between the incident and the problem.  It then commits/posts the data and re-directs the user to the newly created.

 


Function – setIRresolved

This function is called from the createProblem function once it successfully creates the new Problem. It receives the view model as a parameter and then sets all of the relevant information needed to set an Incident to resolved.  Once it has set all of the parameters, it commits/updates the changes using the Web API.  In order to update a work item you need to send the Web API the original work item JSON object and the new (current) JSON Object that contains the updated values.


How to use it

1.       Open an Incident, and click “convert to problem” from the Tasks on the right.


2.       Select the Template you would like to apply to the newly created Problem and then click OK.


3.       Once created, you will be redirected to the newly created ticket.


How to install it

  1. Copy the contents of the ‘ext_ConvertIRtoPR.js’ file to the ‘custom.js’ file (located under the CiresonPortal\CustomSpace folder) beneath any other content in the file. Then add the following code snippet to the top of the ‘custom.js’ file.
  2. Copy the ‘ext_ConvertIRtoPR_template.html’ file to the CiresonPortal\CustomSpace folder.  
  3. Refresh your browser and the new task should appear when an Incident is open.

 

Download the attached .zip file below.

Comments

  • Adrian_PaechAdrian_Paech Customer Advanced IT Monkey ✭✭✭

    Could not get it to working unfortunately :(

    I followed the install instructions, but it stopped the custom.js file from working all together (my other add-ons stopped working, and I did not see the convert ir to pr task appear).

    Any thoughts?

    Regards,

    Adrian 

  • Adrian_PaechAdrian_Paech Customer Advanced IT Monkey ✭✭✭

    Could not get it to working unfortunately :(

    I followed the install instructions, but it stopped the custom.js file from working all together (my other add-ons stopped working, and I did not see the convert ir to pr task appear).

    Any thoughts?

    Regards,

    Adrian 

    Ignore this, I managed to get it working after some fiddling..

    Cheers,

    Adrian

  • Michael_BaldryMichael_Baldry Customer Advanced IT Monkey ✭✭✭
    Hi @Nicholas_Velich, I'm hoping you can help out with this. We've implemented this task, but have a common question from our analysts: can we include the file attachments in the converted work item?

    I looked at the type projection that's being used, and saw that it does have a "FileAttachment" property listed. The Work Item to File Attachment relationship also seems to have the same cardinality on both sides as the Work Item to Work Item relationship, so I assumed that I could use code very similar to the other relationships to add them in too. I add the following parts to the code, and am a bit stumped as to why they aren't getting pulled over properly:

    Loop through file attachments:
    data.FileAttachment = [];
    for (var i = 0; i < vm_Incident.FileAttachment.length; i++) {
    console.log(vm_Incident.FileAttachment[i].Description);
    data.FileAttachment.push({
    "ClassTypeId": "68a35b6d-ca3d-8d90-f93d-248ceff935c0",
    "Id": vm_Incident.FileAttachment[i].Id,
    "BaseId": vm_Incident.FileAttachment[i].BaseId
    });
    }

    Add the relationship to the "NameRelationship" section, using the property name from the type projection:
    {
    "Name": "FileAttachment",
    "RelationshipId": "aa8c26dc-3a12-5f88-d9c7-753e5a8a55b4"
    }

    I print the resulting data object to the console before conversion, and it includes all of the attachments, and I don't get any Javascript errors, but the File Attachments area is blank when I open up the resulting work item. And when I go into the Javascript console and try to access the FileAttachment property, it returns a blank array.

    Any ideas/suggestions?

    Thanks!
  • Nicholas_VelichNicholas_Velich Cireson Consultant Ninja IT Monkey ✭✭✭✭
    Hi Michael,

    File attachments are currently handled a bit differently in the Portal than other relationship types; unfortunately it is not possible to use the API to create/copy a work item with an attachment at this time. I know some folks have requested this internally and in the community, so hopefully it is supported soon. When we have more info on this we will absolutely pass it along. 

    Thanks,
    Nick
  • Jais_HyltoftJais_Hyltoft Partner Adept IT Monkey ✭✭
    edited June 2016

    Thanks! used it for creating a Convert to Service Request Task, you just need to change a few things in the file :-)

  • Eugen_MuellerEugen_Mueller Customer IT Monkey ✭

    Thanks! used it for creating a Convert to Service Request Task, you just need to change a few things in the file :-)


    Share please :wink::smile:
  • Jais_HyltoftJais_Hyltoft Partner Adept IT Monkey ✭✭

    Thanks! used it for creating a Convert to Service Request Task, you just need to change a few things in the file :-)


    Share please :wink::smile:
    Will do, just need to clean it during the weekend. B)
  • Eugen_MuellerEugen_Mueller Customer IT Monkey ✭

    THX.

    One question. After selecting a template (PR or SR) nothing happens. IR form still open and no PR or SR is created? Any ideas?

  • Jais_HyltoftJais_Hyltoft Partner Adept IT Monkey ✭✭
    Maybe it's your browser security or version. Have you tried different browsers?
  • Eugen_MuellerEugen_Mueller Customer IT Monkey ✭

    Yes, tried IE, FF and Chrome. Portal-Admin/SCSM-Admin same behaviour.

  • Jais_HyltoftJais_Hyltoft Partner Adept IT Monkey ✭✭
    OK, any events local or on the web server?
  • Eugen_MuellerEugen_Mueller Customer IT Monkey ✭
    Nothing unusual. Which logs should I have to look for? Webconsole.log from portalserver? Debuglevel is ALL for portal. Which entries should the log have to had if works fine?
  • Jais_HyltoftJais_Hyltoft Partner Adept IT Monkey ✭✭
    edited July 2016

    Hi Eugen, Sorry for the late reply. I have been busy with 2 "Go Live" Dates. I properly got the same issue with the task as you now, I don't know why I didn't get it before. If you run the task in ”Inspect element mode” you will properly see this error:  “Unable to get property 'length' of undefined or null reference” on the vm_Incident.RelatesToConfigItem.lengt property , I investigated and the vm_Incident.RelatesToConfigItem is not there. I do not have time to investigate further now, so I did a quick work around, not transferring the RelatesToConfigItem to the Service Request.

    You just have to comment this section out in the script:


    /* Work through all CI related to IR and attach them to SR */

                    /*data.RelatesToConfigItem = [];

                    for (var i=0; i < vm_Incident.RelatesToConfigItem.length; i++) {

                        console.log(vm_Incident.RelatesToConfigItem[i].BaseId)

                       

                        data.RelatesToConfigItem.push({

                            ClassTypeId: vm_Incident.RelatesToConfigItem[i].ClassTypeId,

                            BaseId: vm_Incident.RelatesToConfigItem[i].BaseId,

                            Name: vm_Incident.RelatesToConfigItem[i].Name

                        });

                    };*/

     

    Hope this works for you.

  • Justin_ClarkeJustin_Clarke Customer Advanced IT Monkey ✭✭✭
    Great work on the above. IR to SR and IR to PR works great.

    Once question i have, is it possible to close the IR your have converted from easily? and maybe put a closed description of converted to SR/PR #XXXXXX.

    As the SR/PR will now be used to do the work the IR will now be closed

    thought?
  • Michael_BaldryMichael_Baldry Customer Advanced IT Monkey ✭✭✭
    One quick note on this script - if you care about keeping the Billable Time records on the original Incident, you'll need to modify it slightly. When working with an Incident, all of the Billable Time records are stored in the "AppliesToWorkItem" array. That array gets overwritten by the part of this script that adds an action log comment:
      finalIR.AppliesToWorkItem = [{
                "ActionType": {
                  "Id": "5ca2cfee-6740-1576-540B-ce17222840b8",
                  "Name": "Record Resolved"
                },  
                "Description": "This Incident was converted to a Problem.",
                "EnteredBy": displayName,
                "EnteredDate": new Date().toISOString().split(".")[0],
                "LastModified": new Date().toISOString().split(".")[0],
                "Title": "Record Resolved",
                "Image": "/Content/Images/Icons/ActionLogIcons/recordresolved.png",
                "BillableTime": {
                  "BasedId": null,
                  "DisplayName": null
                },
                "LastUpdatedDisplay": null      
            }];

    To keep the billable time records, instead of overwriting the array, just push a new element on to the end of the array:

    // Add Action Log entry indicating Resolution/Conversion
    finalir.AppliesToWorkItem.push({
    "ActionType": {
    "Id": "5ca2cfee-6740-1576-540B-ce17222840b8",
    "Name": "Record Resolved"
    },
    "Description": "This Incident was converted to a Service Request.",
    "EnteredBy": displayname,
    "EnteredDate": new Date().toISOString().split(".")[0],
    "LastModified": new Date().toISOString().split(".")[0],
    "Title": "Record Resolved",
            "Image": "/Content/Images/Icons/ActionLogIcons/recordresolved.png",
            "BillableTime": {
    "BaseId": null,
    "DisplayName": null
    },
            "LastUpdatedDisplay": null
    });

    It looks like the array is initialized even on Incidents with no billable time records, so it should be safe to call ".push(...)" on it without initializing it first.
  • Justin_ClarkeJustin_Clarke Customer Advanced IT Monkey ✭✭✭
    Hi Guys,

    has anyone been able to autoclosed or cancel a request ones a new one has been created and copied?

    This is a great solution and would love to implement.

    Thanks for your help and advise

    Justin
  • Justin_ClarkeJustin_Clarke Customer Advanced IT Monkey ✭✭✭
    Hi Guys,

    Please ignore last post. Redownloaded ZIp and it works now.

    Much appreciated Thanks
  • Tim_ShackletonTim_Shackleton Customer IT Monkey ✭
    Hi Michael,

    File attachments are currently handled a bit differently in the Portal than other relationship types; unfortunately it is not possible to use the API to create/copy a work item with an attachment at this time. I know some folks have requested this internally and in the community, so hopefully it is supported soon. When we have more info on this we will absolutely pass it along. 

    Thanks,
    Nick
    A workaround to this would be to extend the Incident Class with a "Converted" Boolean property that isn't displayed in the form.  The portal function could be updated to set the Converted property to "true", then you could have it trigger either an authored workflow with a PowerShell activity embedded in it or an Orchestrator Runbook, that finds the attachments related to the Incident and attaches them to your PR or SR.
  • Allain_WoodsfordAllain_Woodsford Premier Partner IT Monkey ✭
    To get this working this at the top of the code went well for me:

    app.custom.formTasks.add('Incident', "Convert to Problem", function (formObj, viewModel) {
    $.when(kendo.ui.ExtYesNoDialog.show({ 
    title: "Convert to Problem", 
    message: "Are you sure you want to convert this to a Problem?" }) 
    ).done(function (response) 
    { if (response.button === "yes") 
    {   
    convertIRtoPR();
    }
    });
    return;
    }); 
  • AJ_WittenbrinkAJ_Wittenbrink Customer Adept IT Monkey ✭✭
    Great script.  I altered it to bring in affected items, not just related items.

    Code added:
    (Paste around line:137)
    <div>,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Name: "HasRelatedWorkItems",</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RelationshipId: "B73A6094-C64C-B0FF-9706-1822DF5C2E82"</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div>
    Then paste after 141
    <div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* Work through all CI affected by IR and attach them to PR */</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data.HasRelatedWorkItems = [];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (var i=0; i < vm_Incident.HasRelatedWorkItems.length; i++) {&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(vm_Incident.HasRelatedWorkItems[i].BaseId)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data.HasRelatedWorkItems.push({</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ClassTypeId: vm_Incident.HasRelatedWorkItems[i].ClassTypeId,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BaseId: vm_Incident.HasRelatedWorkItems[i].BaseId,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Name: vm_Incident.HasRelatedWorkItems[i].Name</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };</div>


Sign In or Register to comment.