This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DEVELOPERS FORUM - Validate properties on the relationship before moving item to the next workflow step.

Yelena - Thursday, May 21, 2009 12:33 PM:

I need to validate that properties are filled in on the item and it’s relationships before user approves it to the next workflow step.
I managed to validate fields on the item and verify that relationships have been added, but have difficulties getting properties from the relationship. Here is the method. Also please let me know if there is an easier way to get  item from the workflow other than with AML statement.
 
' HISTORY
' Yelena Kupershtok   05.14.2009      initial release
' ================================================================
'System.Diagnostics.Debugger.Break()
'This methods validates that the properties on RFQ Item are populated (not null) when the user attempts to
'set the RFQ's workflow state to 'Submitted'
'it also validates that Plant Feasibility has
 
Dim inno As Innovator = Me.newInnovator()
Dim activityID As String = Me.getID()
Dim AML As String
AML += "<AML>"
AML +=  "<Item type=" + """RFQ""" + " action=" + """get""" + ">"
AML +=  "     <Relationships>"
AML +=  "          <Item type=" + """Workflow""" + " action=" + """get""" + ">"
AML +=  "              <related_id>"
AML +=  "                   <Item type=" + """Workflow Process""" + " action=" + """get""" + ">"
AML +=  "                         <Relationships>"
AML +=  "                             <Item type=" + """Workflow Process Activity""" + " action=" + """get""" + ">"
AML +=  "                                 <related_id>"
AML +=  "                                     <Item type=" + """Activity""" + " id="+ """" + activityID+ """" + " action=" + """get""" +">"
AML +=  "                                     </Item>"
AML +=  "                                </related_id>"
AML +=  "                             </Item>"
AML +=  "                          </Relationships>"
AML +=  "                   </Item>"
AML +=  "             </related_id>"
AML +=  "          </Item>"
AML +=  "     </Relationships>"
AML +=  "  </Item>"
AML += "</AML>"
 
Dim q = inno.applyAML(AML)
If (q.isError()) Then
   Return inno.newError("Failed to get Action Log Item for this Activity")
Else
 
  If (IsNothing(q.getProperty("diameter"))) Then Return inno.newError("<b>Diameter</b> field is required.<br>You must provide a value for this field to submit the PAR.")    
  If (IsNothing(q.getProperty("width"))) Then Return inno.newError("<b>Width</b> field is required.<br>You must provide a value for this field to submit the PAR.") 
 
'=========================================
  
'=======more fileds validations here
'=========================================
 
'=======verify that Plant Feasibility has 1 or more records
 
'=========================================
 
Dim rpf As item = q.fetchRelationships("RFQ Plant Feas REL")
Dim ppf As item = rpf.getRelationships("RFQ Plant Feas REL")
 
If ppf.getItemCount() = 0 Then Return inno.newError("Initial data for <b>Plant Feasibility</b> tab is required.<br>You must provide required information to submit the PAR.")
 
'======verify that Customer Specifics has 1 or more
'======Customer locations
 
Dim rpc As item = q.fetchRelationships("RFQ Customer Specific REL")
Dim ppc As item = rpc.getRelationships("RFQ Customer Specific REL")
 
 
Thanks for your help
Yelena


tstickel - Sunday, May 24, 2009 11:02 AM:

Disclaimer: I just wrote this using Notepad, I did not have time to do a syntax check or to run a test.

In general, anything you can write in AML can also be written using the Innovator Object API

'First define items that will get each itemtype we must access
'For each item we will select just the id, so that Innovator will not
'return unnecessary fields
Dim rfqItem As Item = myInnov.newItem("rfq","get")
rfqItem.setProperty("select","id")

Dim wfItem As Item = myInnov.newItem("Workflow","get")
wfItem.setProperty("select","id")


Dim wfProcess As Item = myInnov.newItem("Workflow Process","get")
wfProcess.setProperty("select","id")

Dim wfProcAct As Item = myInnov.newItem("Workflow Process Activity","get")
wfProcAct.setProperty("related_id",activityID) 'This will supply the SQL Where criteria
wfProcAct.setAttribute("select","id")

'No need to access the Activity, unless there is something we need from it

'So now add these 'get' items as Relationships

wfProcess.addRelationship(wfProcAct)

wfItem.addRelationship(wfProcess)

rfqITem.addRelationship(wfItem)


'Before executing the query, also add 'get' for the RFQ Plant Feas REL
Dim rfqPlantFeasRel As Item = myInnov.newItem("RFQ Plant Feas REL","get")
rfqPlantFeasRel.setAttribute("select","id, related_id(field1, field2)") 'I just assumed that field1 and field2 are on the related record

rfqItem.addRelationship(rfqPlantFeasRel)

'Before executing the query, also add 'get'for the RFQ Customer Specific REL
Dim rfqCustSpecRel As Item = myInnov.newItem("RFQ Customer Specific REL","get")
rfqCustSpecRel.setAttribute("select","id, related_id(field3, field4)")  'I just assumed that field3 and field4 are on the related record

rfqItem.addRelationship(rfqCustSpecRel)


'Everything we need has been added to rfqItem
'Execute the Query
Dim rfqItemFind As Item = rfqItem.apply()

'No testing as to whether the query return any records, for this sample I will assume that it did

'Below reqPlantFeasItems and rfqCustSpecITems will be collections of items
'So you would have to loop through them to access properties from each item

'I assume RFQ Plant Feas is the child item type in the RFQ Plant Feas Rel
Dim rfqPlantFeasItems As Item = rfqItemFind.getItemsByXPath("//Item[@type='RFQ Plant Feas']")

Dim rfqCustSpecItems As Item = rfqItemFind.getItemsByXPath("//Item[@type='RFQ Customer Specific']")



Yelena - Wednesday, July 15, 2009 2:09 PM:

Hello Terry,

Here what I wrote based on your example


Dim myInnov As Innovator = Me.newInnovator()
Dim rfqItem As Item = myInnov.newItem("rfq","get")
rfqItem.setProperty("select","id")

Dim wfItem As Item = myInnov.newItem("Workflow","get")
wfItem.setProperty("select","id")


Dim wfProcess As Item = myInnov.newItem("Workflow Process","get")
wfProcess.setProperty("select","id")

Dim wfProcAct As Item = myInnov.newItem("Workflow Process Activity","get")
wfProcAct.setProperty("related_id","activityID") 'This will supply the SQL Where criteria
wfProcAct.setAttribute("select","id")

wfProcess.addRelationship(wfProcAct)

wfItem.addRelationship(wfProcess)

rfqITem.addRelationship(wfItem)

Dim rfqPlantFeasRel As Item = myInnov.newItem("RFQ Plant Feas REL","get")
rfqPlantFeasRel.setAttribute("select","id, related_id(state)")

rfqItem.addRelationship(rfqPlantFeasRel)

Dim rfqItemFind As Item = rfqItem.apply()


'RFQ Plant Feasibility is the child item type in the RFQ Plant Feas Rel
Dim rfqPlantFeasItems As Item = rfqItemFind.getItemsByXPath("//Item[@type='RFQ Plant Feasibility']")
Dim i As Integer
Dim pfs_state As String
Dim pfs_state_found As String
For i = 0 To rfqPlantFeasItems.getItemCount() - 1
pfs_state=rfqPlantFeasItems.getItemByIndex(i).getProperty("state","")
If pfs_state="Quote Review" Then pfs_state_found="yes"
Next
If pfs_state_found <> "yes"  Then Return myInnov.newError("At lease one <b>Plant Feasibility</B> must be in the <b>Quote Review</b>state<br>before RFQ can be sent to the Customer.")

This method executed as a Pre Method on the Workflow Map path an d I am getting error "Workflow Item type does not have is_relationship=1"

What did I do wrong?

Thanks for your help,

Yelena

 

 



tstickel - Saturday, July 18, 2009 1:15 PM:

Yelena,

There are a couple of issues:

1.  In your statement, wfProcAct.setProperty("related_id","activityID") , you put "activityID" instead of just activityID.

2. It turns out that the Workflow item is not a typical relationship item, even though it has a source_id and related_id.  So instead of the statement wfitem.setRelationship(wfProcess) that was in my code sample, you must use wflitem.setRelatedItem(wfProcess)

3.  Finally, in my code sample a couple of times I used setProperty("select","id"), but select is an attribute instead of a property.  So you must use setAttribute("select","id").  This did not cause the queries to fail, they would just return the value for many more properties than you would want

Hope that this helps

 



Yelena - Monday, July 20, 2009 10:53 AM:

Terry,

I changed the statement for wfProcAct.setProperty to

wfProcAct.setProperty("related_id",ActivityID)

 

 

 

 

I am getting

Exception in server-side method RFQ On Before Sent to Customer (Type is VB) :
Details in 7 temporary files
D:InnovatorInnovatorServerdllaulb7v20
Line number 18, Error Number: BC30451, Name 'ActivityID' is not declared.

Should it be wfProcAct.setProperty("related_id",wfProcAct)  instead?

Thanks again for your help



tstickel - Monday, July 20, 2009 1:12 PM:

In your original code (at the top of this Thread), you included the statement:

Dim activityID As String = Me.getID()

That statement is still required to provide the search value for activityID



Yelena - Tuesday, July 21, 2009 8:36 AM:

Thanks Terry. It works great now.