Setting relations in a AfterSave Hook

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Andorxor
    Member
    • May 2019
    • 65

    Setting relations in a AfterSave Hook

    I have a Contract Entity and want to generate InvoiceItems when it is saved,with the following Hook,but it can not set the Relations to the Contract or Product.
    Code:
    class generateInvoiceItems extends \Espo\Core\Hooks\Base
    {
    public function afterSave( $entity, array $options = array())
    {
     $this->generateInvoiceItems($entity);
    }
    
    private function generateInvoiceItems($contract)
    {
    $interval_months = new \DateInterval('P'.$this->getIntervalMonths($contract->get('paymentinterval')).'M');
    $currentDueDate = new \DateTime($contract->get('datestart'));
    $enddate = new \DateTime($contract->get('dateend'));
    $first = true;
    do
    {
    $products = $this->getEntityManager()->getRepository('Contract')->findRelated($contract, 'contractitems');
    foreach($products as $product)
    {
    $this->generateInvoiceItem($contract,$currentDueDate,$pr oduct,$first);
    }
    $first = false;
    $currentDueDate->add($interval_months);
    }
    while($currentDueDate < $enddate && $contract->get('paymentinterval') != 'once');
    }
    
    public function getIntervalMonths($interval)
    {
    switch($interval)
    {
    case 'once': return 1;
    case 'monthly': return 1;
    case 'quarterly': return 3;
    case 'biannual': return 6;
    case 'yearly': return 12;
    }
    }
    
    private function getAdditionalContractItemColumns($contract_id,$ite m_id)
    {
    $sql = "SELECT count,discount FROM contract_contractitem WHERE contract_id= '$contract_id' AND contractitem_id = '$item_id'";
    $pdo = $this->getEntityManager()->getPDO();
    $sth = $pdo->prepare($sql);
    $sth->execute();
    $rows = $sth->fetchAll(\PDO::FETCH_ASSOC);
    return $rows[0];
    }
    
    public function calculatePrice( $contract,$product)
    {
    $extraData = $this->getAdditionalContractItemColumns($contract->get("id"),$product->get("id"));
    $price = $extraData["count"] * ($product->get('price') - (($product->get('price')/100)* $extraData['discount']));
    return $price * $this->getIntervalMonths($contract->get('paymentinterval'));
    }
    
    public function generateInvoiceItem( $contract, $dueDate, $product, $first)
    {
    if($product->get("once")== true && $first == false)
    {
    return;
    }
    $extraData = $this->getAdditionalContractItemColumns($contract->get("id"),$product->get("id"));
    $item = $this->getEntityManager()->getEntity('InvoiceItem');
    $item->set("contract",$contract);
    //$item->set("description",print_r($product,true));
    $this->getEntityManager()->getRepository('InvoiceItem')->relate($item,"contract",$contract);
    $this->getEntityManager()->getRepository('InvoiceItem')->relate($item,"contractitem",$product);
    $item->set("count",$extraData['count']);
    $item->set("price",$this->calculatePrice($contract, $product));
    $item->set("dueAt",$dueDate->format("y-m-d"));
    $this->getEntityManager()->saveEntity($item);
    }
    
    }
  • item
    Active Community Member
    • Mar 2017
    • 1476

    #2
    Hello,

    In my opinion, in your code : you try to relate for a not saved entity ($item)

    you must only relate after save entity $item so :


    PHP Code:
    $item->set("count",$extraData['count']); $item->set("price",$this->calculatePrice($contract, $product));
    $item->set("dueAt",$dueDate->format("y-m-d"));
    
    $this->getEntityManager()->saveEntity($item);
    
    $this->getEntityManager()->getRepository('InvoiceItem')->relate($item,"contract",$contract);
    $this->getEntityManager()->getRepository('InvoiceItem')->relate($item,"contractitem",$product); 
    
    If you could give the project a star on GitHub. EspoCrm believe our work truly deserves more recognition. Thanks.​

    Comment

    • Andorxor
      Member
      • May 2019
      • 65

      #3
      That did not work.But setting the relation from the other side worked.
      PHP Code:
      $this->getEntityManager()->getRepository('Contract')->relate($contract,"invoiceItems",$item);
      $this->getEntityManager()->getRepository('ContractItem')->relate($product,"invoiceItems",$item); 
      

      Comment

      Working...