AnsweredAssumed Answered

logic hook to update multiple items in the same module that won't loop?

Question asked by Francesca Shiekh on Jun 10, 2016
Latest reply on Jun 13, 2016 by Roland Cadavos

I have a custom products module called wcont_WContractProducts.

Each Product has a quantity, an id (as all modules do), and a bundle_id_c which allows me to identify a group of products.

 

When any product belonging to a bundle is changed to have a new quantity, all the products in the bundle have to be updated to that same quantity.

 

Here comes the problem.

If I do a before or after save logic hook it will loop.

I can limit the number of loops by doing an after save and making sure I don't keep updating the quantity after it's set, but it still runs through too many times and doesn't feel like a clean solution.

For example, in my somewhat slow development environment, with 2 products in the bundle it loops 10 or so times before it finally meets the condition that will stop the looping.

 

My after_save logic hook:

 

class ContractProducts_Logic {
   protected static $fetchedRow = array(); //allows me to use fetchedRow in after save
   function update_bundle_quantities($bean, $event, $arguments){
      //we just saved a product, see if it's an update, if so check if it's a bundle and if quantity has changed.
      if(isset(self::$fetchedRow) && self::$fetchedRow['quantity']!= $bean->quantity && !empty($bean->bundle_id_c)){
        // loop trough the bundle items and update quantity if it's not the same
        require_once('include/SugarQuery/SugarQuery.php');
        $sugarQuery = new SugarQuery();
        $sugarQuery->select(array('id', 'quantity'));
        $bp = BeanFactory::newBean('wcont_WContractProducts');
        $sugarQuery->from($bp, array('team_security' => false));
        $sugarQuery->where()->equals('bundle_id_c', $bean->bundle_id_c);
        $result = $sugarQuery->execute();
        foreach($result as $bundle_product){
          if($bundle_producti['quantity'] != $bean->quantity && $bundle_product['id'] != $bean->id){
             $bpBean = BeanFactory::retrieveBean('wcont_WContractProducts', $bundle_product['id']);
             $bpBean->quantity = $bean->quantity;
             $bpBean->save(); //this triggers this same logic_hook again. 
          }
        }
      }
   }
}

 

I could do a direct update using sql and $db but there are other hooks on the the change in quantity that update a related module's entries so I would really like those logic_hooks to still execute.

 

Any thoughts on how to get out of this conundrum?

 

thank you,

FrancescaS

 

NOTE: the !emptyempty in line 05 is an artifact of the syntax highlighting it is actually !empty($bean->bundle_id_c)

Outcomes