Visual Builder

Get Involved. Join the Conversation.

Topic

    Stephen Bryant
    Object Trigger - create record in another BOAnswered
    Topic posted July 9, 2019 by Stephen BryantBronze Trophy: 5,000+ Points, last edited July 9, 2019, tagged Business Objects, Custom Code, Groovy, Validation 
    85 Views, 6 Comments
    Title:
    Object Trigger - create record in another BO
    Summary:
    Object Trigger - only create if the record does not exist in the target BO
    Content:

    Hello,

    I have two BOs.  One BO stores balances by various attributes.  I have an Object trigger on this BO that will create the record in another BO as long as certain fields are not present in the BO.  For example, the source BO has fields for Fund, Period and Balance.  If the combination of those fields does not exist in the target BO, then create the record.

    I cannot seem to programmatically access the fields in the target BO using object trigger.

    How can I check using an Object Trigger if fields exists in the target BO? There is no relationship between the two.

    However, if I were to relate the two, could I accomplish this?

    Any other suggestions?

    Thanks,

    Steve

    Version:
    19.1.3

    Best Comment

    David Konecny

    It's been a while since I wrote groovy code but looking at some older app of mine here are some code snippets which should help:

    I would create two Object Functions on SourceBO - checkInsertIsNeeded and performInsert. They both have single input param called sourceBO and its type is Object. In SourceBO trigger then call these functions like this:

    if ( checkInsertIsNeeded(adf.source) ) {
        performInsert(adf.source);
    }
    

    where "adf.source" is what in JS code would be "this", that is inside sourceBO trigger the adf.source will be Source record being changed.

    Then in checkInsertIsNeeded I'd do smth like this (im just pasting some my code but it should be enough for inspiration):

    def query = "category = ${sourceBO.category} AND requestType = ${sourceBO.requestType} AND organization = ${sourceBO.organization}";
    def paMatrix = newView('PrimaryAssigneeMatrix')  
    println("finding assignee using query: ${query}")
    paMatrix.appendViewCriteria(query)
    paMatrix.executeQuery()
    def found = 0
    if (paMatrix.hasNext()) {
        def pa = paMatrix.next()
        println("found Primary Assignee Matrix record: ${pa.id}")
        result = pa.primaryAssignee
        found = 1
    }
    if (found == 0) {
        println("no primary assignee in Primary Assignee Matrix for record: ${sourceBO.id}")
    }
    return found == 0;
    

     

    and for performInsert (which is defined on SourceBO but will create record in TargetBO) the code could be:

    def parentAttrs = new oracle.jbo.NameValuePairs()
    parentAttrs.setAttribute('purchaseRequest',sourceBO.something)
    
    def fin = newView('TargetBO')
    def row = fin.createAndInitRow(parentAttrs)
    fin.insertRow(row)
    

    HTH,
    -David

    Comment

     

    • Shay Shmeltzer

      I believe that you'll need to connect the two BOs - and then once you enable the accessor you'll be able to access one from the other.

      See for example - https://blogs.oracle.com/vbcs/creating-invoking-business-object-functions-from-visual-builder-ui

       

    • David Konecny

      It is possible to do this without BOs being related. You will have to write some Groovy script to do this though.

      When you say "If the combination of those fields does not exist in the target BO, then create the record." which sounds like you can turn this combination into query criteria. So in your object trigger simply create a new view for second BO and execute these query criteria to see how many records you get back. And if none then you execute insert into the second BO.

      -David

       

      • Stephen Bryant

        Thanks David.

        That is the approach I am working on.

        Appreciate the response.

        Steve

      • Stephen Bryant

        David,

        I am able to check if the combination exists but I am have a problem proceeding further.

        I would like use the result of the check function to drive whether or not I create the record.

        I've tried two ways to do this.

        1.  I created the trigger on the Source BO as follows:

        // checks if combination of Fund and Period exist in glStatusOfFunds

        def res;
        def vo = newView('glStatusOfFunds');
        def vc = vo.createViewCriteria(); 
        def vcr = vc.createRow(); 
        def vci1 = vcr.ensureCriteriaItem('fund'); 
        vci1.setOperator('='); 
        vci1.setValue(fund);
        def vci2 = vcr.ensureCriteriaItem('period'); 
        vci2.setOperator('='); 
        vci2.setValue(period);
        vci2.setConjunction(1);
        vc.insertRow(vcr);
        vo.appendViewCriteria(vc);
        vo.executeQuery();

        println('running');

        if (vo.hasNext()) {
          
          res = 'true';
          println(res);
          return res;
        } else {

          println('false');
          return false;
        }

        This works fine but if I try to add the create statement in the trigger along with the code above, it does not work due to the object instance already being set.  So I believe I need to create the checkFunction as a helper function instead.  That was the next thing I tried.

        2.  Created a Business Object Function on the Target BO that accepts two parameters (fund, period)

        I attempt to call the function from the Source BO trigger but I get a no signature of method error.  I know there is a specific way to call another function in this manner but cannot seem to get it right.

        Does this make sense or am I missing the boat here?

        Any help is appreciated and I appreciate your patience.

        Thanks,

        Steve

        • David Konecny

          It's been a while since I wrote groovy code but looking at some older app of mine here are some code snippets which should help:

          I would create two Object Functions on SourceBO - checkInsertIsNeeded and performInsert. They both have single input param called sourceBO and its type is Object. In SourceBO trigger then call these functions like this:

          if ( checkInsertIsNeeded(adf.source) ) {
              performInsert(adf.source);
          }
          

          where "adf.source" is what in JS code would be "this", that is inside sourceBO trigger the adf.source will be Source record being changed.

          Then in checkInsertIsNeeded I'd do smth like this (im just pasting some my code but it should be enough for inspiration):

          def query = "category = ${sourceBO.category} AND requestType = ${sourceBO.requestType} AND organization = ${sourceBO.organization}";
          def paMatrix = newView('PrimaryAssigneeMatrix')  
          println("finding assignee using query: ${query}")
          paMatrix.appendViewCriteria(query)
          paMatrix.executeQuery()
          def found = 0
          if (paMatrix.hasNext()) {
              def pa = paMatrix.next()
              println("found Primary Assignee Matrix record: ${pa.id}")
              result = pa.primaryAssignee
              found = 1
          }
          if (found == 0) {
              println("no primary assignee in Primary Assignee Matrix for record: ${sourceBO.id}")
          }
          return found == 0;
          

           

          and for performInsert (which is defined on SourceBO but will create record in TargetBO) the code could be:

          def parentAttrs = new oracle.jbo.NameValuePairs()
          parentAttrs.setAttribute('purchaseRequest',sourceBO.something)
          
          def fin = newView('TargetBO')
          def row = fin.createAndInitRow(parentAttrs)
          fin.insertRow(row)
          

          HTH,
          -David