cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - New to the community? Learn how to post a question and get help from PTC and industry experts! X

How to create a baseline in a promotion request workflow?

Loic_Badoual
6-Contributor

How to create a baseline in a promotion request workflow?

Version: Windchill 12.0.2.18

 

Hi,

 

We are looking to create a Managed Baseline in our promotion request workflow for all mechanical assembly with the name  *-01-g.asm

 

I have found the Article - CS371627 - How to create a baseline in a (promotion request) workflow? and the Article - CS25967 - How to programmatically create a managed baseline in Windchill PDMLink which give some ideas, but I am having some difficulty going deeper into the development.

 

The small step I have already succeed is the following :

 

Add an "Execute Expression" robot after the "Set State Approved" method Robot and the Notify By E-mail robot :

Loic_Badoual_0-1727354644368.png

The code to execute to the expression call a custom class :

 

 

ext.sce.workflow.CreateBaseline.createBaseline(baselineName);

 

 

 

The content of the class is the following :

 

 

package ext.sce.workflow;

import wt.vc.baseline.ManagedBaseline;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.fc.PersistenceHelper;


public class CreateBaseline {
	
    public static void createBaseline(String name) throws WTException {
        try {
            System.out.println("Start....");
            ManagedBaseline myManagedBaseline = ManagedBaseline.newManagedBaseline();
            myManagedBaseline.setName("test");
            myManagedBaseline.setDescription("this is a test baseline");
            myManagedBaseline = (ManagedBaseline) PersistenceHelper.manager.save(myManagedBaseline);
            System.out.println("===> myManagedBaseline " + myManagedBaseline);
        } catch (WTPropertyVetoException e) {
            e.printStackTrace();
        } catch (WTException e) {
            e.printStackTrace();
        }
    }
}

 

 

When a CAD assembly is approved, a Managed Baseline is created in the Default folder of the Site.

Loic_Badoual_1-1727354993789.png

 

Now the expectation is to  create the ManagedBaseline in the folder of the primary object and  add the collection of Baselineable CAD model to the baseline.

 

If I follow the example in the CS25967 in order to create the ManagedBaseline in the correct folder :

 

 

package ext.sce.workflow;

import wt.vc.baseline.ManagedBaseline;
import wt.part.WTPart;
import wt.fc.WTObject;
import wt.folder.Folder;
import wt.folder.FolderEntry;
import wt.folder.FolderHelper;
import wt.inf.container.WTContainer;
import wt.inf.container.WTContainerRef;

public class CreateBaseline_1 {

public static void createBaseline(WTPart part,String ContainerName) throws Exception {
System.out.println("Start....");
ManagedBaseline baselineObj = ManagedBaseline.newManagedBaseline(); 
baselineObj.setName("test"); 
baselineObj.setDescription("this is a test baseline"); 
baselineObj.setContainerReference((WTPart)primaryBusinessObject.getContainerReference()); 

WTContainerRef containerRef = WTContainerRef.newWTContainerRef(containerRef);
Folder folder = FolderHelper.service.getFolder("/Default/Baseline", containerRef);
FolderHelper.assignLocation((FolderEntry)baselineObj, folder);

baselineObj=(ManagedBaseline)wt.fc.PersistenceHelper.manager.save(baselineObj);
System.out.println("===> myManagedBaseline " +baselineObj);
}
}

 

 

There is an issue with the setContainerReference

 

Any idea how to solve this ?

 

Best regards,

Loïc

ACCEPTED SOLUTION

Accepted Solutions

@Loic_Badoual ,

 

I looked at your code.  There's more than setting the container reference that's wrong.

As is this code should not compile.

  • You are using variables that are not defined.
  • You are calling methods from objects that do not have access to the called method.

 

Is it correct to say primaryBusinessObject is the OOTB workflow variable?  For now, I'll assume yes to that question.

primaryBusinessObject is a WTObject.  There is no method getContainerReference() for a WTObject.

 

What you have now is this

 

baselineObj.setContainerReference((WTPart)primaryBusinessObject.getContainerReference()); 

 

There are four problems with this line ofcode.

  1. primaryBusinessObject is not defined.
  2. primaryBusinessObject is a WTObject.  There is no getContinerReference() method for object WTObject.
  3. Even if item 2 was not a problem, you are still casting the container reference returned from the getContainerReference() method to a WTPart.  This would throw a cast exception as a container ref cannot be cast to a WTPart.
  4. the method setContainerReference method requires, well, a container reference not a WTPart. You are casting a container ref to a WTPart and then passing that WTPart to te setContainerReference method.  That's not going to fly.

 

Code should be as shown below.

Note, I simply went straight for the WTPart that you are passing to your method to get the container reference.

 

baselineObj.setContainerReference(part.getContainerReference()); 

 

 

Once you get past that part of your code the line of code below will be a problem.

Your method contains the following:

WTContainerRef containerRef = WTContainerRef.newWTContainerRef(containerRef);

However, the variable containerRef is never defined. And if it were why use it to create another WTContainerRef.

Why not use the same containerRef object in multiple places.

 

Also, public static void createBaseline(WTPart part,String ContainerName) throws Exception {

String ContainerName is never used in your method.  Why have it?

Is String ContainerName the name of the container for the Baseline, which is not the same as the WTPart's container?

 

BTW, in Java, the convention to naming method arguments is that they always start with lowercase.  Not critical of course but that's the convention. So, String ContainerName would be String containerName. But again, your method never uses it so why not remove this argument?

 

 

If your Baseline folder is in the same container as the WTPart (maybe it is, but maybe it's not). The following method should work for you.

 

    public static void createBaseline(WTPart part) throws Exception {
        System.out.println("Start....");
        ManagedBaseline baselineObj = ManagedBaseline.newManagedBaseline();
        baselineObj.setName("test");
        baselineObj.setDescription("this is a test baseline");

        WTContainerRef containerRef = WTContainerRef.newWTContainerRef(part.getContainerReference());
        baselineObj.setContainerReference(containerRef);

        Folder folder = FolderHelper.service.getFolder("/Default/Baseline", containerRef);
        FolderHelper.assignLocation((FolderEntry) baselineObj, folder);

        baselineObj = (ManagedBaseline) wt.fc.PersistenceHelper.manager.save(baselineObj);
        System.out.println("===> myManagedBaseline " + baselineObj);
    }

 


David

View solution in original post

3 REPLIES 3

@Loic_Badoual ,

 

I looked at your code.  There's more than setting the container reference that's wrong.

As is this code should not compile.

  • You are using variables that are not defined.
  • You are calling methods from objects that do not have access to the called method.

 

Is it correct to say primaryBusinessObject is the OOTB workflow variable?  For now, I'll assume yes to that question.

primaryBusinessObject is a WTObject.  There is no method getContainerReference() for a WTObject.

 

What you have now is this

 

baselineObj.setContainerReference((WTPart)primaryBusinessObject.getContainerReference()); 

 

There are four problems with this line ofcode.

  1. primaryBusinessObject is not defined.
  2. primaryBusinessObject is a WTObject.  There is no getContinerReference() method for object WTObject.
  3. Even if item 2 was not a problem, you are still casting the container reference returned from the getContainerReference() method to a WTPart.  This would throw a cast exception as a container ref cannot be cast to a WTPart.
  4. the method setContainerReference method requires, well, a container reference not a WTPart. You are casting a container ref to a WTPart and then passing that WTPart to te setContainerReference method.  That's not going to fly.

 

Code should be as shown below.

Note, I simply went straight for the WTPart that you are passing to your method to get the container reference.

 

baselineObj.setContainerReference(part.getContainerReference()); 

 

 

Once you get past that part of your code the line of code below will be a problem.

Your method contains the following:

WTContainerRef containerRef = WTContainerRef.newWTContainerRef(containerRef);

However, the variable containerRef is never defined. And if it were why use it to create another WTContainerRef.

Why not use the same containerRef object in multiple places.

 

Also, public static void createBaseline(WTPart part,String ContainerName) throws Exception {

String ContainerName is never used in your method.  Why have it?

Is String ContainerName the name of the container for the Baseline, which is not the same as the WTPart's container?

 

BTW, in Java, the convention to naming method arguments is that they always start with lowercase.  Not critical of course but that's the convention. So, String ContainerName would be String containerName. But again, your method never uses it so why not remove this argument?

 

 

If your Baseline folder is in the same container as the WTPart (maybe it is, but maybe it's not). The following method should work for you.

 

    public static void createBaseline(WTPart part) throws Exception {
        System.out.println("Start....");
        ManagedBaseline baselineObj = ManagedBaseline.newManagedBaseline();
        baselineObj.setName("test");
        baselineObj.setDescription("this is a test baseline");

        WTContainerRef containerRef = WTContainerRef.newWTContainerRef(part.getContainerReference());
        baselineObj.setContainerReference(containerRef);

        Folder folder = FolderHelper.service.getFolder("/Default/Baseline", containerRef);
        FolderHelper.assignLocation((FolderEntry) baselineObj, folder);

        baselineObj = (ManagedBaseline) wt.fc.PersistenceHelper.manager.save(baselineObj);
        System.out.println("===> myManagedBaseline " + baselineObj);
    }

 


David

Loic_Badoual
6-Contributor
(To:d_graham)

@d_graham,

 

Thank you for your time and for the detailed answer. It helps me a lot to progress.

However, I try to launch the method via an "Execute Expression" robot but without success.

I can't find the solution to assign the value of the WTPart...

 

I try several expression like this :

 

wt.part.WTPart part = (wt.part.WTPart) primaryBusinessObject;
ext.sce.workflow.CreateBaseline.createBaseline(part);

 

The Syntax check is complete but when running the workflow,

 

the error is the following :

 

wt.util.WTException: java.lang.ClassCastException: class wt.maturity.PromotionNotice cannot be cast to class wt.part.WTPart (wt.maturity.PromotionNotice and wt.part.WTPart are in unnamed module of loader 'app')

 

 

I also tried another method by creating another robot "Execute Expression" to extract the list of objects related to the promotion request which I know works:

 

wt.fc.QueryResult promotables = wt.maturity.MaturityHelper.service.getPromotionTargets((wt.maturity.PromotionNotice)primaryBusinessObject);
promObjList = new ArrayList<String>();

while(promotables.hasMoreElements()){
	wt.fc.WTObject promotable = (wt.fc.WTObject) promotables.nextElement();
	promObjList.add(promotable.getDisplayIdentity());
}

 

 The promObjList is define as a java.util.ArrayList and the content of the value in my example is the following : [Assembly - sc-test-01-g.asm, Q.1]

 

The syntax check of the following expression give an error: incompatible types: ArrayList cannot be converted to WTPart

 

ext.sce.workflow.CreateBaseline.createBaseline(promObjList);

 

 

I realize that it is not so simple. A tip would be welcome!

Kind regards,

Loïc

 

 

Hi @Loic_Badoual 

In your case the promaryBusinessObject is the PromotionNotice 

You need to get the target objects getPromotionTargets .

 

But your code use ArrayList with a String and you probably try to put the ArrayList to the Part type that is not possible.

 

You need to get the object from the  promotables list where the WTPart is return by the getPromotionTargets . 

 

while (promotables.hasMoreElements())
{
 Object obj = promotables.nextElement();
  if (obj instanceof WTPart)
   {
     WTPart wtp = (WTPart) obj;
   }
}

 

in your case you need to just add the full class definition. WTPart = wt.part.WTPart .... PetrH

Announcements

Top Tags