Nick - Thursday, March 24, 2011 2:42 PM:
So I've (hopefully) managed to teach myself how to form relationships to get to the item information at the end based off methods already in Innovator and the API. The problem I'm having now is actually saving a change made to a Property or Attribute.
Here's the code I have so far, with what I understand is going on, just to make sure I am doing it right; (http://min.us/mvboovh or http://pastebin.com/aHwwH0y7 for syntax highlighting!) . This is being run when an ECR is submitted. Once it works I'll also have it show the ECR name. It DOES find the right item id, and makes the change needed, but it doesn't seem to save that change. Commented out lines were to check what was being found.
From what I understand, this is getting ECR Affected Item, setting the related_id to what the select query returns, source_id to this.id. Then creating a relationship with Affected Item, and getting the attributes for action, interchangeable, affected_id (id, item_number, pending_change), and new_item_id (id, item_number, pending_change).
Then it sets the array of items under new_item_id to flaggedItems, going through each one and setting the image to pending_change. Then doing the same thing for affected_id.
I'm wondering if I need action or interchangeable at all in the select for affItem, if this will even need to check if the item is a part or document, if I need to create tmpItem or if I can just do flaggedItems.getItemByIndex(i).setProperty(bla) and how it's supposed to commit the change, since it doesn't seem to be doing it right now. I was also wondering what the difference between Property and Attribute was.
Like I said earlier, I'm just using what I've seen done in other methods and on the API. retrieving the affected items was also just copy/pasted from another method until I understood what it was fully doing. (no comments in now since it doesn't fully work, those come once it works or when I understand fully what I'm doing)
Can I suggest Innovator support Chrome? It has such a nice debugger built in... (I know it won't happen, you don't have to tell me =P)
Brian - Sunday, April 3, 2011 8:19 AM:
Hi Nick,
You have a few questions in there. I'll try to answer at least a couple of them.
When you ceaate an Item (say Item prt = this.newItem("Part", "add") )
the "add", "edit", "get" action determines what will happen when you call "prt.apply();")
If you set the action to "add, edit, merge" then it will save the changes as appropriate. A "get" will simply get the information from the server.
Once you have an Item you can change the "action" to be performed using "prt.setAttribute("action","edit");" for example.
What's the difference between a property and an attribute. For a proper explanation you should read up on XML since this is all that AML is. Simply you may have a data structure like this:
<Item type="Part">
<item_number>000-0009</item_number>
<description>Capacitor, 0805, 100uf, 50V, XR7</description>
</Item>
In this example the main Tag we are dealing with is an "Item". It has two Properties (item_number and description) and one Attribute (type="Part")
So if you had an Item you could use the "setProperty" to change the value of "item_number" or "description" and the "setAttribute" to change/or read the "type".
To retrieve a part using AML we might write:
<Item type="Part" action="get" select="item_number,config_id,name,description,state" where="[part].item_number = '000-0009'"/>
in this: type, action, select and where are all attributes of the "Item" tag.
the properties that are being retrieved by the AML are listed in the "select" attribute.
You could create the same AML using the IOM code:
Item prt = this.newItem("Part","get");
prt.setAttribute("select","item_number,config_id,name,description,state");
prt.setAttribute("where","[part].item_number = '000-0009'");
Item result = prt.apply();
To set the value of some properties for a new part you might use:
Item prt = this.newItem("Part","add");
prt.setProperty("item_number","333-0125");
prt.setProperty("description","Resistor, 125R, 0805, 1%");
Item result = prt.apply():
Merge and Edit require that you supply either an ID or a "where" clause that resolves to valid items to perform the operation on.
Hope this helps.
Brian.
Nick - Monday, April 4, 2011 10:56 AM:
Hey Brian, thanks for answering, again was starting to think this place was kind of a ghost town >_<.
Yea I actually picked up on how apply() worked over the past week when I randomly got the idea that it should have some overloaded alternatives, ended up looking into it more and found that out.
What confuses me still then is not the difference between attribute and property, but how they are defined that way (so that I know when I create my own). Also, how is it that their code seems to work but mine doing the same thing never does >_< all I could figure out is that (maybe?) apply() will set attributes, but when using it to set properties you need to use edit, which won't work in my situation because I can't have the revision bumped up when adding a simple flag so that the users know the part/document is in an ecr/ecn. I managed to get it working by going in and adding/removing the information directly on the SQL server itself, but it'd be nice if there was a way to do it through innovator instead.
Brian - Tuesday, April 5, 2011 7:10 AM:
Hi Nick,
Attributes and Properties confused me for a while.
If you have data like:
<Author sex="male">
<Name>John James</Name>
<Book>
<Title>This good book</Title>
<Cost>25</Cost>
</Book>
<Book>
<Title>My Three Kings</Title>
<Cost>55</Cost>
</Book>
</Author>
Name and Book are Properties of Author.
Title and Cost are Properties of Book.
Sex is an attribute of Author
Does that help?
If you are trying to show to users that an item (Part) is on an ECR/ECN you are probably better off using a Server Event triggered on an "onAfterGet" to set a client side only flag that you display to the user. That way you are not messing with the data directly in SQL and are not having to save a flag that you will need to remember to clear later.
Hope this helps.
Brian.
Nick - Tuesday, April 5, 2011 9:11 AM:
That would only half work for what we're trying to do actually. We want to have an item show "Pending" until the ECR/ECN has been submitted, then show the number. Right now we have a field called pending_change in parts/documents that we change to show that, but like I said I'm doing it through sql, and there has to be a better way to handle that without going directly to the server. As far as an onAfterGet event goes, how would you remove the flag if the user removes an item from an ECR? Would that be the same, and just have the function check if the user is removing the item? Or would it be something to put on an onDeleteRow event?
Also, thanks for explaining the attributes vs properties thing. It makes a little more sense now.
Brian - Tuesday, April 5, 2011 6:14 PM:
Hi Nick,
Whenever the client side requests information on Items from the Server it first calls "onBeforeGet" methods, then runs the standard "onGet" method and then calls "onAfterGet" methods.
You can use onBeforeGet methods to validate data before it gets to the server and gets saved.
You can use onAfterGet methods to add data that isn't specifically associated with the normal "get" for the Item. This information is not saved in the database and is useful for displaying information to the user that doesn't need to be cleared/reset.
In your situation I would have an onAfterGet method that checks if the Part/Document is on an ECR/ECN AND what state the ECR/ECN is in. If it comes back on an ECR and the ECR is "In Review" then you can display this information easily to the user. You don't have to clear any flags because they only exist on the client side. It is information for the user but isn't a saved state.
So everytime someone requested information on the Part they would see this "Changes Pending" status evaluated in real time and shown to them. If the ECR moves on and they look at the part again then they will see the change reflected in their user interface.
I hope this explains it more clearly.
Cheers.
Brian.
Nick - Tuesday, April 5, 2011 7:08 PM:
Ah, that does explain things better. One issue with this though is that we want the user to be able to see if an item is on an ECR when they look up documents or parts, so it has to show as a field in innovator. Ron (the one on the forums) came up with the idea that if it's in a preliminary state we can just use apply('edit') without an issue, because it will just bump the generation number (which is a good thing too, it creates a history for the item), whereas if the part is released we promote it to a new state called Pending Change where it can be edited without bumping up the revision number, and them push it back to being released.
The question that comes up now (because my brain immediately goes into error checking mode) is what happens if the user opens up an ECR and deletes an item off the list, is there a way to change only items removed (or even added? right now I'm using OnAfterUpdate)? I did notice there are grid events, but is that really the best choice?
Brian - Tuesday, April 5, 2011 7:54 PM:
Hi Nick,
I musn't be being very clear with my explanation.
Put the "onAfterGet" methods on the Parts and Documents. When the user looks up the Part or Document it goes and queries the Open ECR/ECN and gives you information that you can display to the user. Add a Property to Part and Document that is of Type Federated and populate it with the results of the onAfterGet query. Say - in_change, type=Federated.
onAfterGet:
...code that checks to see if the part is on an ECR/ECN.....
this.setProperty("in_change", results of query );
return this;
When someone removes something from the ECR/ECN and the user gets the Part or Document again the query will not find it on an open ECR/ECN and will not be shown information that it is currently "in change" or whatever.
The only issue you will have here is if someone removes the part or document from the ECR/ECN when the user still has the part/document open and they don't see the changed status until they close/open the part/document again.
I really don't think you need to actually store a value in Innovator.
Cheers,
Brian.
Nick - Tuesday, April 5, 2011 9:49 PM:
So THAT's how you work a Federated type! I was actually thinking of doing something like this but I wasn't sure how that type's data was shown. One question though, if the user is looking under design/parts, there wouldn't be an open ecr/ecn, so how would it get the information then? Would I have to code it in a way that it looks through Affected Items and if the item number is listed in there it displays what it's in? Or can I use the same general code to step backwards through a relationship to get the information that way?
Thanks for the information either way, I'll be playing with the Federated type to figure out what kind of things I can do with it tomorrow morning.
Nick - Monday, April 11, 2011 12:20 PM:
Thanks again for all the help Brian.
So I've gotten most of what I wanted working nicely, now I'd just like to add some 'user convenience' features(?). I tried using the ID of the ECR/ECN and setting the Federated datatype using setType("foobar"); but it didn't seem to work. I'd like this field to link to the ECR/ECN it's showing, do you know of another way to do this? I've already created and tested a poly itemtype that links to either.
Brian - Tuesday, April 12, 2011 8:26 AM:
Hi Nick,
Since you have the ECR/ECN Number you can set up an onClick field event for the form that looks for the ECR/ECN Item. You might want to save in another federated field the Item type (ECR/ECN) of the number being displayed.
Using these two fields you can find the ECR/ECN that is being referenced using a simple query and open the Item itself using top.aras.uiShowItemEx( )
/* * uiShowItemEx var inn = this.getInnovator(); var ecr = this.newItem("ECR","get"); top.aras.uiShowItemEx(ecr.node,"tab view", true); return; This code should find and display the ECR based on the number supplied. If you have captured the ECR/ECN type then you can select the appropriate type to "get" in the first place. cheers, Brian.
*
* parameters:
* 1) itemNd - item to be shown
* 2) viewMode - 'tab view', 'tree view', 'print view', 'where used' or 'openFile'
* 3) isTearOff - true or false.
*/
ecr.setProperty("item_number","ECR-100003");
ecr = ecr.apply();