Skip to content

Commit

Permalink
countRelated subRelated functions
Browse files Browse the repository at this point in the history
  • Loading branch information
yurikuzn committed Jun 11, 2018
1 parent a4c1599 commit 16c9f46
Show file tree
Hide file tree
Showing 3 changed files with 305 additions and 0 deletions.
@@ -0,0 +1,89 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2018 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/

namespace Espo\Core\Formula\Functions\EntityGroup;

use \Espo\ORM\Entity;
use \Espo\Core\Exceptions\Error;

class CountRelatedType extends \Espo\Core\Formula\Functions\Base
{
protected function init()
{
$this->addDependency('entityManager');
$this->addDependency('selectManagerFactory');
}

public function process(\StdClass $item)
{
if (!property_exists($item, 'value')) {
throw new Error();
}

if (!is_array($item->value)) {
throw new Error();
}

if (count($item->value) < 1) {
throw new Error();
}

$link = $this->evaluate($item->value[0]);

if (empty($link)) {
throw new Error("No link passed to countRelated function.");
}

$filter = null;
if (count($item->value) > 1) {
$filter = $this->evaluate($item->value[1]);
}

$entity = $this->getEntity();

$entityManager = $this->getInjection('entityManager');

$foreignEntityType = $entity->getRelationParam($link, 'entity');

if (empty($foreignEntityType)) {
throw new Error();
}

$foreignSelectManager = $this->getInjection('selectManagerFactory')->create($foreignEntityType);

$selectParams = $foreignSelectManager->getEmptySelectParams();

if ($filter) {
$foreignSelectManager->applyFilter($filter, $selectParams);
}

return $entityManager->getRepository($entity->getEntityType())->countRelated($entity, $link, $selectParams);
}

}
119 changes: 119 additions & 0 deletions application/Espo/Core/Formula/Functions/EntityGroup/SumRelatedType.php
@@ -0,0 +1,119 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2018 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/

namespace Espo\Core\Formula\Functions\EntityGroup;

use \Espo\ORM\Entity;
use \Espo\Core\Exceptions\Error;

class SumRelatedType extends \Espo\Core\Formula\Functions\Base
{
protected function init()
{
$this->addDependency('entityManager');
$this->addDependency('selectManagerFactory');
}

public function process(\StdClass $item)
{
if (!property_exists($item, 'value')) {
throw new Error();
}

if (!is_array($item->value)) {
throw new Error();
}

if (count($item->value) < 2) {
throw new Error();
}

$link = $this->evaluate($item->value[0]);

if (empty($link)) {
throw new Error("No link passed to sumRelated function.");
}

$field = $this->evaluate($item->value[1]);

if (empty($field)) {
throw new Error("No field passed to sumRelated function.");
}

$filter = null;
if (count($item->value) > 2) {
$filter = $this->evaluate($item->value[2]);
}

$entity = $this->getEntity();

$entityManager = $this->getInjection('entityManager');

$foreignEntityType = $entity->getRelationParam($link, 'entity');

if (empty($foreignEntityType)) {
throw new Error();
}

$foreignSelectManager = $this->getInjection('selectManagerFactory')->create($foreignEntityType);

$foreignLink = $entity->getRelationParam($link, 'foreign');

if (empty($foreignLink)) {
throw new Error("No foreign link for link {$link}.");
}

$selectParams = $foreignSelectManager->getEmptySelectParams();

if ($filter) {
$foreignSelectManager->applyFilter($filter, $selectParams);
}

$selectParams['select'] = [[$foreignLink . '.id', 'foreignId'], 'SUM:' . $field];

$foreignSelectManager->addJoin($foreignLink, $selectParams);

$selectParams['groupBy'] = [$foreignLink . '.id'];

$entityManager->getRepository($foreignEntityType)->handleSelectParams($selectParams);

$sql = $entityManager->getQuery()->createSelectQuery($foreignEntityType, $selectParams);

$pdo = $entityManager->getPDO();
$sth = $pdo->prepare($sql);
$sth->execute();
$rowList = $sth->fetchAll(\PDO::FETCH_ASSOC);

if (empty($rowList)) {
return 0;
}

return $rowList[0]['SUM:' . $field];
}
}
97 changes: 97 additions & 0 deletions tests/integration/Espo/Core/Formula/FormulaTest.php
@@ -0,0 +1,97 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2018 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/

namespace tests\integration\Espo\Core\Formula;

class FormulaTest extends \tests\integration\Core\BaseTestCase
{

public function testCountRelatedAndSumRelated()
{
$entityManager = $this->getContainer()->get('entityManager');

$account = $entityManager->getEntity('Account');
$account->set('name', 'test');
$entityManager->saveEntity($account);

$contact = $entityManager->getEntity('Contact');
$contact->set('name', 'test');
$entityManager->saveEntity($contact);

$opportunity = $entityManager->getEntity('Opportunity');
$opportunity->set([
'name' => '1',
'amount' => 10,
'stage' => 'Closed Won',
'accountId' => $account->id
]);
$entityManager->saveEntity($opportunity);

$opportunity = $entityManager->getEntity('Opportunity');
$opportunity->set([
'name' => '2',
'amount' => 20,
'stage' => 'Prospecting',
'accountId' => $account->id
]);
$entityManager->saveEntity($opportunity);

$opportunity = $entityManager->getEntity('Opportunity');
$opportunity->set([
'name' => '3',
'amount' => 40,
'stage' => 'Closed Won'
]);
$entityManager->saveEntity($opportunity);

$entityManager->getRepository('Contact')->relate($contact, 'opportunities', $opportunity);

$formulaManager = $this->getContainer()->get('formulaManager');

$script = "entity\countRelated('opportunities')";
$result = $formulaManager->run($script, $account);
$this->assertEquals(2, $result);

$script = "entity\countRelated('opportunities', 'won')";
$result = $formulaManager->run($script, $account);
$this->assertEquals(1, $result);

$script = "entity\sumRelated('opportunities', 'amountConverted')";
$result = $formulaManager->run($script, $account);
$this->assertEquals(30, $result);

$script = "entity\sumRelated('opportunities', 'amountConverted', 'won')";
$result = $formulaManager->run($script, $account);
$this->assertEquals(10, $result);

$script = "entity\sumRelated('opportunities', 'amountConverted', 'won')";
$result = $formulaManager->run($script, $contact);
$this->assertEquals(40, $result);
}
}

0 comments on commit 16c9f46

Please sign in to comment.