diff --git a/application/Espo/Core/Formula/Exceptions/TooFewArguments.php b/application/Espo/Core/Formula/Exceptions/TooFewArguments.php index 60c811e8ce..d0dd5c34d2 100644 --- a/application/Espo/Core/Formula/Exceptions/TooFewArguments.php +++ b/application/Espo/Core/Formula/Exceptions/TooFewArguments.php @@ -30,7 +30,7 @@ namespace Espo\Core\Formula\Exceptions; /** - * Too few function arguments passsed. + * Too few function arguments passed. */ class TooFewArguments extends Error { diff --git a/application/Espo/Core/Formula/Functions/RecordGroup/FindManyType.php b/application/Espo/Core/Formula/Functions/RecordGroup/FindManyType.php new file mode 100644 index 0000000000..4a926f55d3 --- /dev/null +++ b/application/Espo/Core/Formula/Functions/RecordGroup/FindManyType.php @@ -0,0 +1,146 @@ +selectBuilderFactory + ->create() + ->from($entityType); + + $whereClause = []; + + if (count($arguments) <= 5) { + $filter = null; + + if (count($arguments) === 5) { + $filter = $arguments[4]; + } + + if ($filter && !is_string($filter)) { + throw BadArgumentType::create(5, 'string'); + } + + if ($filter) { + $builder->withPrimaryFilter($filter); + } + } + else { + $i = 4; + + while ($i < count($arguments) - 1) { + $key = $arguments[$i]; + $value = $arguments[$i + 1]; + + $whereClause[] = [$key => $value]; + + $i = $i + 2; + } + } + + try { + $queryBuilder = $builder->buildQueryBuilder(); + } + catch (BadRequest|Error|Forbidden $e) { + throw new FormulaError($e->getMessage(), $e->getCode(), $e); + } + + if (!empty($whereClause)) { + $queryBuilder->where($whereClause); + } + + if ($orderBy) { + $queryBuilder->order($orderBy, $order); + } + + $queryBuilder + ->select(['id']) + ->limit(0, $limit); + + $collection = $this->entityManager + ->getRDBRepository($entityType) + ->clone($queryBuilder->build()) + ->find(); + + return array_map( + fn (Entity $entity) => $entity->getId(), + iterator_to_array($collection) + ); + } +} diff --git a/application/Espo/Resources/metadata/app/formula.json b/application/Espo/Resources/metadata/app/formula.json index e1a89dc8be..2cf772f48d 100644 --- a/application/Espo/Resources/metadata/app/formula.json +++ b/application/Espo/Resources/metadata/app/formula.json @@ -298,6 +298,11 @@ "insertText": "record\\findOne(ENTITY_TYPE, ORDER_BY, ORDER, KEY1, VALUE1, KEY2, VALUE2)", "returnType": "string" }, + { + "name": "record\\findMany", + "insertText": "record\\findMany(ENTITY_TYPE, LIMIT, ORDER_BY, ORDER, KEY1, VALUE1, KEY2, VALUE2)", + "returnType": "string" + }, { "name": "record\\findRelatedOne", "insertText": "record\\findRelatedOne(ENTITY_TYPE, ID, LINK, ORDER_BY, ORDER, KEY1, VALUE1, KEY2, VALUE2)", diff --git a/tests/integration/Espo/Core/Formula/FormulaTest.php b/tests/integration/Espo/Core/Formula/FormulaTest.php index e4787224ee..cf68db79a1 100644 --- a/tests/integration/Espo/Core/Formula/FormulaTest.php +++ b/tests/integration/Espo/Core/Formula/FormulaTest.php @@ -203,7 +203,7 @@ class FormulaTest extends \tests\integration\Core\BaseTestCase $fm = $this->getContainer()->get('formulaManager'); $em = $this->getContainer()->get('entityManager'); - $m1 =$em->createEntity('Meeting', [ + $m1 = $em->createEntity('Meeting', [ 'name' => '1', 'status' => 'Held', ]); @@ -246,6 +246,49 @@ class FormulaTest extends \tests\integration\Core\BaseTestCase $this->assertEquals(null, $result); } + public function testFindMany(): void + { + $fm = $this->getContainer()->getByClass(Manager::class); + $em = $this->getContainer()->getByClass(EntityManager::class); + + $m1 = $em->createEntity('Meeting', [ + 'name' => '1', + 'status' => 'Held', + ]); + + $m2 = $em->createEntity('Meeting', [ + 'name' => '2', + 'status' => 'Planned', + ]); + + $m3 = $em->createEntity('Meeting', [ + 'name' => '3', + 'status' => 'Held', + ]); + + $m4 = $em->createEntity('Meeting', [ + 'name' => '4', + 'status' => 'Planned', + 'assignedUserId' => '1', + ]); + + $script = "record\\findMany('Meeting', 2, 'name', null, 'status=', 'Held')"; + $result = $fm->run($script); + $this->assertEquals([$m1->getId(), $m3->getId()], $result); + + $script = "record\\findMany('Meeting', 2, 'name', true, 'status=', 'Held')"; + $result = $fm->run($script); + $this->assertEquals([$m3->getId(), $m1->getId()], $result); + + $script = "record\\findMany('Meeting', 1, 'name', 'desc', 'status=', 'Held')"; + $result = $fm->run($script); + $this->assertEquals([$m3->getId()], $result); + + $script = "record\\findMany('Meeting', 2, 'name', 'ASC', 'planned')"; + $result = $fm->run($script); + $this->assertEquals([$m2->getId(), $m4->getId()], $result); + } + public function testRecordFindRelatedOne1() { $fm = $this->getContainer()->get('formulaManager');