AML = SQL Where (IN)

Good day all.  I have a JavaScript Method that uses the following line to create a list.

tdpList.loadAML('<Item type="s_Document" orderBy="id" action="get" where="([s_DOCUMENT].id IN(SELECT RELATED_ID FROM innovator.s_TDP_DOCUMENT WHERE (SOURCE_ID = \'' + this.getID() + '\')))"><generation condition="gt">0</generation></Item>');
tdpList = tdpList.apply();

I need to reuse this Method for another ItemType.  I have discovered that using Where and In causes an error because of a security update in 11 SP9.  Aras 11.0 - AML Security Settings 2017-04-28 mentions that you can create an exception to allow specific statements, but recommends changing the code to something else.  I remember reading that this exception is supposed to be phased out in 12.  How can I change this statement to correctly return the list I need?  

I can get the information by using a Get and Relationships, but it will not create the proper list.  I think this is do to the information returned since it includes the ItemType and Relationship ItemType information.  Thank you for any help you can provide.

  • I assume it´s possible to rewrite this one, but I assume most people are not very good in reading SQL from others.

    Can you describe how your s_Document and s_TDP_Document ItemTypes are linked together?
    Are both of them independent ItemTypes or is a s_TDP_Document a relationship of your s_Document?
    Are additional ItemTypes involved?

    Which one of the two document itemTypes is linked to your "this.getID()"?

    Maybe you can provide a simple structure like

    Part       <--- I want to get this one
    --> Part AML 
    -----> Manufacturer Part <--- I start from here. this.getID() contains the id of this Item

  • Angela,

    Good day.  I guess a bit more information would be helpful.  Grin  s_TDP_Document is a Relationship tab to s_TDP (Technical Data Package).  s_Document is a Poly Source of six different document ItemTypes (previous caretakers didn't use any of the OOTB ItemTypes).  The TDP allows the gathering of documents and then the Method will search for the most current version of Released and download them into a zip file. 

  • So your structure is the following:

    s_TDP

    --- s_TDP_Document 

    ------ s_Document / Polysources

    And you have the id of s_TDP? Than it´s comparable to a regular Part/Part AML/Manufacturer Part ("let´s look downwards") query:

    <AML>
      <Item type='Part' action='get' select='item_number' id='" + myID + "'>
        <Relationships>
         <Item type='Part AML' action='get' select='related_id(item_number)'/>
           <related_id>
              <Item type='Manufacturer Part' select='item_number'>
              </Item>
           </related_id>
         </Relationships>
       </Item>
    </AML>;

    Not sure about the PolyItem. For testing you can also start with the upper levels and then add the additional levels downwards until the query works.

    I personally wouldn´t use loadAML. It´s possible to rewrite the Method so it basically does the same, but without having one large string. Check out the structure shown in these blog articles:

    https://community.aras.com/b/english/posts/server-side-best-practices-part-3 

    https://community.aras.com/b/english/posts/server-side-best-practices-part-2

  • I have tried that in the code, but it is not generating the list correctly.  The code I supplied creates a list of the s_Documents.  Using code like you stated creates a list using s_TDP.  Using the list the rest of the Method (written in JavaScript) looks at each entry and determines if there are attached documents.  Then it bundles everything up and downloads the documents.

  • My code sample was based on how I understood your description. :) 

    Does "bundle everything up" mean you use the "build a zip package" community project? This uses the file id´s of related files. I would try to get a proper list of these ids first before caring about the export.

    Some questions:

    1. Where do you start your Method (grid/form/cui)? From which item (s_TDP?)?
    2. Where are your files in the items? Do you use a File relationship grid or File property?
    3. What result do you want to use from the query. You don´t have a select filter so it´s hard to tell.

  • The method is called from an Action associated to s_TDP.  The TDP has a relationship to s_Documents (poly source of about six different "document" ItemTypes).  The idea is to add the items to the TDP in the relationship and have the the Method go through those items to get the attached documents (a File relationship), package them into a Zip file and download them to the desktop.

    Here are the first 40 lines from the code, there are a little over 250 lines.

    var inn = this.getInnovator();
    var dir = "";

    var userItem = top.aras.getLoggedUserItem();
    var workingDirNode = userItem.selectSingleNode('./working_directory');

    if (workingDirNode) {
    var logDir = workingDirNode.text;
    }

    var myTdp = inn.newItem("s_TDP", "get");
    myTdp.setID(this.getID());
    myTdp = myTdp.apply();
    var tdpNumber = myTdp.getProperty("item_number");
    var tdpList = new Item();

    tdpList.loadAML('<Item type="s_Document" orderBy="id" action="get" where="([s_DOCUMENT].id IN(SELECT RELATED_ID FROM innovator.s_TDP_DOCUMENT WHERE (SOURCE_ID = \'' + this.getID() + '\')))"><generation condition="gt">0</generation></Item>');
    tdpList = tdpList.apply();

    if (tdpList.isError() || tdpList.isEmpty()) {
    alert("There are no files attached to this TDP. This method will exit");
    //top.aras.AlertError(tdpList.ItemCount());
    return;
    }

    if (tdpList.getItemCount() < 1) {
    alert("There are no Files for this " + this.getProperty("item_number"));
    }

    var noVals = inn.newItem();
    var count = 0;
    for (var i = 0; i < tdpList.getItemCount(); i++) {
    var num = 0;
    var item = tdpList.getItemByIndex(i)
    if (itemHasFiles(item) == false) {
    count++;
    noVals.appendItem(item) //add it to the no vals list
    tdpList.removeItem(item) //remove it from the used list
    i--;
    }
    }

  • Which version of Aras are you using? Your code contains a couple of fragments that may not work in Innovator 12 (working directory). Did your code work it the past?

    I would extend the "myTdp" query by something like this that will do a full query including the files:

    var myTdp = inn.newItem("s_TDP","get");
    myTdp.setAttribute("select","id,classification,keyed_name");
    myTdp.setID(id); // <- target Part

    var bomItem = myTdp.createRelationship("s_TDP_Document ","get");
    bomItem.setAttribute("select","related_id"); 

    // not sure if you need the next block or if you need to directly search for the Polys

    var relatedItem = inn.newItem("s_Document","get");
    relatedItem.setAttribute("select","id,classification");
    bomItem.setRelatedItem(relatedItem);

    The above query now needs the additional levels for the PolyItems and their related files.

    For PolyItems you either have to add additional queries for each itemtype, or reuse the PolyItem query as seen in Method "Express ECO GetDataSource". 

    Search for the code were Aras gets the "Change Controlled Item" and "Change Controlled Relationship". The shown relationship would represent your files.

  • We are on v11 SP10, but are trying to upgrade to 12 (it has been a very slow process).  I want to make sure that this code will still work for 12.  s_Document is the poly source for the following ItemTypes; s_Delivered Documents, s_Drawing, s_Parts List, s_Manual, s_Specification, s_RefLibrary.  I am trying to get these into the OOTB Document ItemType, but again, slow process.  These are the ItemTypes that have the files that need to be packaged into a Zip file.  s_TDP_Document is the Relationship to s_Document.

  • Do you self-update or with help of Aras? If you are subscriber I really wouldn´t be scared about this one, Aras can do this very well, you just have to tell them what you expect (have a testplan!!!).

    Is this one your structure?

    s_TDP
    --- s_TDP_Document 
    ------ s_Document (polyitem)
    -------------s_Drawing (and others)
    -----------------FileRelationship (?????)
    ---------------------File

    Please let me know when this structure is wrong. What I don´t understand in your code sample is, that you search for files, but they are not searched for in your loadAML query. The query just checks if there are documents at all. Or do you never have documents without files?

    If your really just need to search for s_Documents, than my above sample could be a replacement for your mentioned SQL query.

    If you also want to have the file ids, the query also have to cover the real Files. The polysources makes this one a bit special. The problems are the file relationships of the poly sources. They all have their own names. Do you have a 2nd polysource for these relationships that contain source_id and related_id? This would probably make the query much easier, as you don´t have to search for s_Documents, but for "related files". 

    I you are a subscriber, ask Aras about how to get all related Files of Polyitems. All of my tips may be wrong!

  • I forgot to mention, we are going to have Aras do the upgrade, but things have been very slow on our side to get the data that Aras requires.  It is not helpful that I cannot do things on the servers that would expedite the process.