Contract Disbursements: Run the formular on Contract to sum all related Disbursements

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Marcel
    Member
    • Jul 2025
    • 33

    #1

    Contract Disbursements: Run the formular on Contract to sum all related Disbursements

    Hi all,

    After creating a new Contract Disbursements I want to run the formular on the Contract again to sum the amount from all related Disbursements. I created a AfterSaveHook.php for that but somehow (Because it´s a collection / array) I can´t use the saveEntity directly on the $contract. What did I wrong?



    PHP Code:
    
    <?php
    
    namespace Espo\Custom\Hooks\CContractDisbursement;
    
    use Espo\Core\Hook\Hook\AfterSave;
    use Espo\Core\Hook\Hook\AfterRemove;
    use Espo\ORM\Repository\Option\SaveOptions;
    use Espo\ORM\Repository\Option\RemoveOptions;
    use Espo\ORM\Entity;
    use Espo\Core\ORM\EntityManager;
    use Espo\Core\ORM\Repository\Option\SaveOption;
    use Espo\Core\Utils\Log;
    
    class AfterSaveHook implements AfterSave, AfterRemove
    {
        protected EntityManager $entityManager;
        protected ?Log $log = null;
        
        // --- CONFIG ---
        public static int $order = 10;
        private const ENABLE_LOGGING = true;    // set to false to disable logging
    
        public function __construct(EntityManager $entityManager, ?Log $log = null)
        {
            $this->entityManager = $entityManager;
            $this->log = (self::ENABLE_LOGGING && $log !== null) ? $log : null;
        }
    
        // --- PROTECTED FUNCTIONS ---
        protected function updateLinkedContract(Entity $disbursement): void
        {
            // --- CONFIG: change this to the entity type you want to recalc ---
            $entityType = 'CContract';
    
            // Get linked contract
            $contractId = $disbursement->get('contractId');
            if (!$contractId) {
                return;
            }
            $repo = $this->entityManager->getRepository($entityType);
            //$repo = $this->entityManager->getRDBRepository($entityType);
            $contract = $repo->find($contractId);
            if (!$contract) {
                return;
            }
    
            foreach ($contract as $entity) {
                $this->entityManager->saveEntity(
                    $entity,
                    [ SaveOption::SILENT => false ] // silent save to avoid triggering user notifications
                );
            }
    
            // $this->entityManager->saveEntity(
            //     $contract,
            //     [ SaveOption::SILENT => false ] // silent save to avoid triggering user notifications
            // );
        }
    
        // --- PUBLIC FUNCTIONS ---
        public function afterSave(Entity $entity, SaveOptions $options): void
        {
            $this->updateLinkedContract($entity);
        }
    
        public function afterRemove(Entity $entity, RemoveOptions $options): void
        {
            $this->updateLinkedContract($entity);
        }
    }

    Is there maybe also another way to sum all amounts from the disbursements and write them onto the contract itself? Maybe via Formula?


    Thanks!
  • lazovic
    Super Moderator
    • Jan 2022
    • 1224

    #2
    Hi Marcel,

    Try using the following formula script function: https://docs.espocrm.com/administrat...titysumrelated.

    Comment

    • Marcel
      Member
      • Jul 2025
      • 33

      #3
      Originally posted by lazovic
      Hi Marcel,

      Try using the following formula script function: https://docs.espocrm.com/administrat...titysumrelated.
      Hi lazovic ,
      that formula is working but only from the contract object itself and not when I am relating and creating a new disbursement.

      Comment

      • lazovic
        Super Moderator
        • Jan 2022
        • 1224

        #4
        Marcel,

        You can try using this formula script in the Contract Disbursement entity:
        Code:
        $disbIds = record\findMany('CContractDisbursement', 10000, 'createdAt', 'desc', 'contractId', contractId);
        
        $i = 0;
        
        while ($i < array\length($disbIds)) {
        
          $disbId = array\at($disbIds, $i);
          $disbAmount = record\attribute('CContractDisbursement', $disbId, 'amount');
        
          $sumAmount = $sumAmount + $disbAmount;
        
          $i = $i + 1;
        }
        
        record\update('CContract', contractId, 'sumAmount', $sumAmount);

        Comment

        Working...