IT Process Automation

  • 1.  Load an array in particular sequence

    Posted May 15, 2015 10:25 AM


    I would like to load the workflow tasks in a particular sequence into my array along with Property values so I can pull the values out of the arrays to update certain work tasks.

     

    Example:

     

    Seq     Description              

    10     Initiate Change Order

    40      Peer Review

    205      Cab Assessment

    210      Testing Validated

    250     Release Board Review

    280     Group Start Task

    300      Deploy in Production

    305     Deploy in Production

    310      Deploy in Production

     

    Pam is Loading my Array:

     

    10     Initiate Change Order

     

    205      Cab Assessment

    210      Testing Validated

    250     Release Board Review

    280     Group Start Task

    300 Deploy in Production

    305     Deploy in Production

    310      Deploy in Production

    40      Peer Review

     

    Any Help would be appreciated.



  • 2.  Re: Load an array in particular sequence

    Posted May 15, 2015 11:43 AM

    here's a nice little solution from w3s:

     

    Process.a = [10, 205, 210, 250, 280, 300, 305, 310, 40]; // your current sequence PAM is loading

    Process.b = Process.a.sort(function(a, b){return a - b});

     

    I just tested it in a run javascript operator and it seems to work, you can omit the process.b part  and it will simply reorder process.a for you.



  • 3.  Re: Load an array in particular sequence

    Posted May 15, 2015 02:05 PM
    I am pulling these fields from the Change Order work tasks into seperate Arrays.
    Select Fields List
    0
    id
    1
    description
    2
    persistent_id
    3
    status
    4
    sequence

     

    The fields I believe are in text format.  Is there a way to convert the sequence array into an integer?  From there I believe I know how to sort them.

     

    Java Code:

    Process.wfid = new Array();

    Process.wfdescription = new Array();

    Process.wfpersid = new Array();

    Process.wfstatus= new Array();

    Process.wfseq= new Array();

     

    for ( i = 0; i < Process[OpName].SelectDataResponse.UDSObject.length; i++ )
    {
      Process.wfid[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[0].AttrValue[0].text_;
      Process.wfdescription[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[1].AttrValue[0].text_;
      Process.wfpersid[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[2].AttrValue[0].text_;
      Process.wfstatus[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[3].AttrValue[0].text_;
      Process.wfseq[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[4].AttrValue[0].text_;
    }



  • 4.  Re: Load an array in particular sequence

    Posted May 15, 2015 02:54 PM

    Granted that you're using JavaScript in PAM(which I would assume based on your code above) you shouldn't have to convert the sequence array to integer to be able to sort since JS isn't a strongly typed language. Unless I'm misunderstanding your code, that should be handled automatically for you

     

    I would love to see your code that sorts the sequence array and keeps the other 4 in sync also!



  • 5.  Re: Load an array in particular sequence

    Posted May 15, 2015 03:39 PM

    Java Code in Post-execution Code:

    Process.wfid = new Array();

    Process.wfdescription = new Array();

    Process.wfpersid = new Array();

    Process.wfstatus= new Array();

    Process.wfseq= new Array();

    Process.Tom = new Array();

    //Process.iwfcount is the actual number of the Deploy in Production work tasks that is being processed in PAM.

    Process.iwfcount = 0;

    //Process.Icount is the total number of Deploy in Production tasks (Normally is only 2 by default)

    Process.Icount = 0;

    //Bubble sort variables

    var k2 = 0;
    var temp;
    var temptoo;

    for ( i = 0; i < Process[OpName].SelectDataResponse.UDSObject.length; i++ )
    {
      Process.wfid[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[0].AttrValue[0].text_;
      Process.wfdescription[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[1].AttrValue[0].text_;
      Process.wfpersid[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[2].AttrValue[0].text_;
      Process.wfstatus[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[3].AttrValue[0].text_;
      Process.wfseq[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[4].AttrValue[0].text_;
      var n2 = i;
      Process.Tom[i]=Process.wfseq[i].length;
    }

    //I added Process.Linda to see if the value was an Integer and it appears that it isn't.
    Process.Linda=Process.wfseq[1] + 500;
    // Bubble Sort workflow tasks
    var n3 = n2-1;
    for (var m2 = n2; m2 >= 0; m2--) {
      for (var i2 = 0; i2 <= n3; i2++) {
    k2 = i2 + 1;

     

    //used these Process variables to check the numbers in the Bubble sort.
    Process.Melissa=k2;
    Process.Foster=i2;
    Process.Gary=m2;
    Process.Waltermire=n2;
    Process.Thursday=n3;

    if (Process.wfseq[i2] > Process.wfseq[k2]) {
       temptoo = Process.wfid [i2];
       Process.wfpersid [i2] = Process.wfpersid [k2];
       Process.wfpersid [k2] = temptoo;
      
       temp = Process.wfseq [i2];
       Process.wfseq [i2] = Process.wfseq [k2];
       Process.wfseq [k2] = temp;
      
       temp = Process.wfid [i2];
       Process.wfid [i2] = Process.wfid [k2];
       Process.wfid [k2] = temp;
      
       temptoo = Process.wfdescription [i2];
       Process.wfdescription [i2] = Process.wfdescription [k2];
       Process.wfdescription [k2] = temptoo;
      
       temptoo = Process.wfstatus [i2];
       Process.wfstatus [i2] = Process.wfstatus [k2];
       Process.wfstatus [k2] = temptoo;
    }
      }
    }
    for ( i = 0; i < n2; i++ ){
     
      // Variables for used to count the number of Deploy in Production work tasks are needed
     
      var a = Process.wfdescription[i];
      var b = a.indexOf("Deploy");
      var c = a.indexOf("Production");
      var d = a.indexOf("Additional");
      var f = a.indexOf("Initiate Change Order Process");
      var g = a.indexOf("Release Change Order");
      var h = a.indexOf("Release Transport to QA");
     
     
      // Resets the Deploy in Production work tasks if the category is restarted.
     
      if (f > -1){ 
    Process.Icount = 0;}
      if (g > -1){ 
    Process.Icount = 0;}
      if (h > -1){ 
    Process.Icount = 0;}
     
      //Counts the number of Deploy in Productions tasks in the Change Order
     
      if(b > -1 || d > -1) {
       if (c > -1) {
      
       Process.Icount++;
      
       if(Process.wfpersid[i] == "wf:"+Process.wf_data['id']) {
     
      Process.iwfcount = Process.Icount;
       }
    }
      }
    }

     

    Results in Pam:

    //I added Process.Linda to see if the value was an Integer and it appears that it isn't.

    Process.Linda=Process.wfseq[1] + 500;

    Linda was 40500

     

    If integer Linda should have been 540.



  • 6.  Re: Load an array in particular sequence

    Posted May 18, 2015 09:07 AM

    The logic is impressive!

     

    I was doing some reading and found an article that helped me understand the nature of converting strings to numbers, I found that the ~~ operator works in PAM. The good part about it being that it will return 0 if it encounters a character.

     

    here's the article:

    https://coderwall.com/p/5tlhmw/converting-strings-to-number-in-javascript-pitfalls

     

    here's the code i was experimenting with:

    Process.a = new String([10, 205, 210, 250, 280, 300, 305, 310, 40]);

    Process.E = Process.a.split(',');

    Process.C = Process.E[1];

    Process.D = 5 + ~~C;



  • 7.  Re: Load an array in particular sequence

    Posted May 18, 2015 04:42 PM

    You could also use the Number method:

     

    a = "10"; // a is a string

    b = Number(a); // b is an integer



  • 8.  Re: Load an array in particular sequence
    Best Answer

    Posted Jul 08, 2015 07:38 AM

    I ended up using this logic for this problem:

     

     

    //Array for Integer for Sequence number

        var seqleng = new Array();

     

    // read all of the workflow tasks for the change order into
    arrays

     

    for ( i = 0; i <
    Process[OpName].SelectDataResponse.UDSObject.length; i++ )

     

    {

     

    Process.wfid[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[0].AttrValue[0].text_;

     

    Process.wfdescription[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[1].AttrValue[0].text_;


    Process.wfpersid[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[2].AttrValue[0].text_;


    Process.wfstatus[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[3].AttrValue[0].text_


    Process.wfseq[i]=Process[OpName].SelectDataResponse.UDSObject[i].Attributes[0].Attribute[4].AttrValue[0].text_;

     

      var n2 = i;

     

      //seqleng will be
    used to convert the string value to an integer so it can be sorted in the
    Bubble sort


    seqleng[i]=parseInt(Process.wfseq[i], 10);

      }



  • 9.  Re: Load an array in particular sequence

    Posted Jul 09, 2015 12:10 AM

    A couple of little refinements to suggest here:

     

    1. Using 'applyXPath' can simplify the process of extracting objects and attributes, and protects you against unexpected data being returned due to later edits - e.g. if you ever add an attribute, or change the order of the attribute list in the 'select'.

     

    2. The Javascript 'sort' facility makes sorting arrays - including arrays of objects - easy.

     

    Here's an example where 'applyXPath' first extracts out the 'UDSObject' elements, and then from each UDSObject extracts the 'sequence' and 'handle' attributes, builds a 'Task' object for each pair and adds it to an array, then uses the sort function to sort the array of Task objects into sequence number order.  This is the Post-execution code for a 'doSelect' that pulls all of the 'Group Start' tasks for a change.

     

    //

    // Find the insertion point for implementation tasks in the new change.

    // The insertion point is the last GRPSTART in the change.

    //

    var myUDSOs = [];

    var myGRPSTARTh = "";

    var myGRPSTARTs = 0;

     

    //

    // Task 'object' declaration

    //

    function Task(sequence, handle)

    {

      this.sequence = sequence;

      this.handle = handle;

    }

     

    if (typeof Process[OpName].SoapResponseData.doSelectReturn == "undefined")

    {

      // No GRPSTARTs.  This would be very surprising!

      Process.myTrace.unshift("New change has no GRPSTARTS");

    }

    else

    {

      // Extract the GRPSTART task details:

      var myText = Process[OpName].SoapResponseData.doSelectReturn[0].text_;

     

    myUDSOs = applyXPath(myText, "//UDSObject", false, true);

      Process.myTrace.unshift("myUDSOs length " + myUDSOs.length);

      if (myUDSOs.length > 0)

      {

      // Sort them in sequence order

      var sortTasks = [];

      var mySeq = 0;

      var myHandle = "";

     

      // Extract sequence and handle from each UDSO.

      for (i=0; i < myUDSOs.length; i++)

      {

       // Within the UDSO, 'sequence' is formatted as

       // an <AttrName>sequence</AttrName><AttrValue>4055</AttrValue> pair,

       // but Handle is an element in its own right: <Handle>wf:401005</Handle>

       //

       mySeq = applyXPath(myUDSOs[i], "//AttrName[text() = 'sequence']/../AttrValue/text()" );

       myHandle = applyXPath(myUDSOs[i], "//Handle/text()" );

       Process.myTrace.unshift("GRPSTART sequence "+mySeq+", handle "+myHandle+" extracted.");

       sortTasks[i] = new Task(mySeq, myHandle);

      }

     

    // Sort the tasks by sequence, ascending.

      sortTasks.sort(function(a,b) { return a.sequence - b.sequence } );

     

      if (sortTasks.length > 1)

      {

       //

       // Insertion point for  Implementation tasks is the last GRPSTART.

       //

       myGRPSTARTh = sortTasks[sortTasks.length - 1].handle;

       myGRPSTARTs  = sortTasks[sortTasks.length - 1].sequence;

      }

      }

    }

     

    Process.impTaskGRPSTARTHandle = myGRPSTARTh;

    Process.impTaskGRPSTARTSeq = myGRPSTARTs;

    //

    // From this point, if impTaskGRPSTARTSeq is 0, can proceeed no further.

    //