diff --git a/.gitignore b/.gitignore
index a1150200..38506d83 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ composer.lock
tools/.env.local
tools/logs
tests/ApplicationBridge/auth.json
+tests/ApplicationBridge/*.log
/examples/*.log
/examples/**/*.log
/examples/**/*/*.log
diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
index ce2866f3..f6d39ce7 100644
--- a/.php-cs-fixer.php
+++ b/.php-cs-fixer.php
@@ -6,9 +6,7 @@
$finder = Finder::create()
->in(__DIR__ . '/src/Infrastructure/Console/Commands/')
- ->in(__DIR__ . '/src/Services/CRM/VatRates/')
- ->in(__DIR__ . '/src/Services/CRM/Contact/')
- ->in(__DIR__ . '/src/Services/CRM/Requisites/')
+ ->in(__DIR__ . '/src/Services/CRM/Automation/')
->name('*.php')
->exclude(['vendor', 'storage', 'docker', 'docs']) // Exclude directories
->ignoreDotFiles(true)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9722f228..80ede486 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,10 +6,14 @@
- Fixed error in arguments in service for method `placement.bind`, [see details](https://github.com/bitrix24/b24phpsdk/issues/151)
-## 1.3.0 – 2025.04.23
-
### Added
+- Added service `Services\CRM\Automation\Service\Trigger` with support methods,
+ see [add crm.automation.trigger* methods](https://github.com/bitrix24/b24phpsdk/issues/148):
+ - `add` add new trigger, with batch calls support
+ - `delete` delete trigger, with batch calls support
+ - `list` get list of triggers, with batch calls support
+ - `execute` execute trigger, with batch calls support
- Added **PHP 8.4** [support](https://github.com/bitrix24/b24phpsdk/issues/120) 🚀
- Added method `Bitrix24\SDK\Services\Main\Service::guardValidateCurrentAuthToken` for validate current auth token with
api-call `app.info` on vendor OAUTH server.
diff --git a/Makefile b/Makefile
index 03afc50c..b3aa734e 100644
--- a/Makefile
+++ b/Makefile
@@ -174,6 +174,10 @@ test-integration-scope-entity:
.PHONY: test-integration-scope-ai-admin
test-integration-scope-ai-admin:
docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_scope_ai_admin
+
+.PHONY: integration_tests_scope_automation
+integration_tests_scope_automation:
+ docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_scope_automation
# work dev environment
.PHONY: php-dev-server-up
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index d7b241df..78a7bcc0 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -11,6 +11,7 @@ parameters:
- tests/Integration/Services/IMOpenLines
- tests/Integration/Services/Main
- tests/Integration/Services/Placement
+ - tests/Integration/Services/CRM/Automation
bootstrapFiles:
- tests/bootstrap.php
parallel:
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 624b64f3..c3f87679 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -43,6 +43,9 @@
./tests/Integration/Services/AI/
+
+ ./tests/Integration/Services/CRM/Automation/
+
diff --git a/rector.php b/rector.php
index 402daf01..e9d13cdb 100644
--- a/rector.php
+++ b/rector.php
@@ -30,6 +30,8 @@
__DIR__ . '/tests/Integration/Services/IM',
__DIR__ . '/src/Services/IMOpenLines',
__DIR__ . '/tests/Integration/Services/IMOpenLines',
+ __DIR__ . '/src/Services/CRM/Automation',
+ __DIR__ . '/tests/Integration/Services/CRM/Automation',
__DIR__ . '/src/Services/Main',
__DIR__ . '/tests/Integration/Services/Main',
__DIR__ . '/src/Services/Placement',
diff --git a/src/Core/Batch.php b/src/Core/Batch.php
index 1dc7d46f..b5b59750 100644
--- a/src/Core/Batch.php
+++ b/src/Core/Batch.php
@@ -43,7 +43,7 @@ class Batch implements BatchOperationsInterface
/**
* Batch constructor.
*/
- public function __construct(private readonly CoreInterface $core, private readonly LoggerInterface $logger)
+ public function __construct(protected readonly CoreInterface $core, protected readonly LoggerInterface $logger)
{
$this->commands = new CommandCollection();
}
@@ -345,9 +345,9 @@ protected function getReverseOrder(array $order): array
*/
public function getTraversableList(
string $apiMethod,
- array $order,
- array $filter,
- array $select,
+ ?array $order = [],
+ ?array $filter = [],
+ ?array $select = [],
?int $limit = null,
?array $additionalParameters = null
): Generator {
diff --git a/src/Core/Contracts/BatchOperationsInterface.php b/src/Core/Contracts/BatchOperationsInterface.php
index 76bd8938..39af2248 100644
--- a/src/Core/Contracts/BatchOperationsInterface.php
+++ b/src/Core/Contracts/BatchOperationsInterface.php
@@ -71,7 +71,7 @@ public function addEntityItems(string $apiMethod, array $entityItems): Generator
/**
* Delete entity items with batch call
*
- * @param array $entityItemId
+ * @param array $entityItemId
*
* @return Generator|ResponseData[]
* @throws BaseException
diff --git a/src/Services/CRM/Automation/Batch.php b/src/Services/CRM/Automation/Batch.php
new file mode 100644
index 00000000..cdcf0f9e
--- /dev/null
+++ b/src/Services/CRM/Automation/Batch.php
@@ -0,0 +1,164 @@
+
+ *
+ * For the full copyright and license information, please view the MIT-LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Bitrix24\SDK\Services\CRM\Automation;
+
+use Bitrix24\SDK\Core\Commands\Command;
+use Bitrix24\SDK\Core\Commands\CommandCollection;
+use Bitrix24\SDK\Core\Contracts\CoreInterface;
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException;
+use Bitrix24\SDK\Core\Response\DTO\Pagination;
+use Bitrix24\SDK\Core\Response\DTO\ResponseData;
+use Bitrix24\SDK\Core\Response\DTO\Result;
+use Bitrix24\SDK\Core\Response\DTO\Time;
+use Bitrix24\SDK\Core\Response\Response;
+use Generator;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class Batch
+ *
+ * @package Bitrix24\SDK\Services\CRM\Automation
+ */
+class Batch extends \Bitrix24\SDK\Core\Batch
+{
+ /**
+ * Delete entity items with batch call
+ *
+ *
+ * @return Generator|ResponseData[]
+ * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
+ */
+ public function deleteEntityItems(
+ string $apiMethod,
+ array $entityItemId,
+ ?array $additionalParameters = null
+ ): Generator {
+ $this->logger->debug(
+ 'deleteEntityItems.start',
+ [
+ 'apiMethod' => $apiMethod,
+ 'entityItems' => $entityItemId,
+ 'additionalParameters' => $additionalParameters,
+ ]
+ );
+
+ try {
+ $this->clearCommands();
+ foreach ($entityItemId as $cnt => $code) {
+ if (!is_string($code)) {
+ throw new InvalidArgumentException(
+ sprintf(
+ 'invalid type «%s» of trigger code «%s» at position %s, code must be string type',
+ gettype($code),
+ $code,
+ $cnt
+ )
+ );
+ }
+
+ $parameters = ['CODE' => $code];
+ $this->registerCommand($apiMethod, $parameters);
+ }
+
+ foreach ($this->getTraversable(true) as $cnt => $deletedItemResult) {
+ yield $cnt => $deletedItemResult;
+ }
+ } catch (InvalidArgumentException $exception) {
+ $errorMessage = sprintf('batch delete entity items: %s', $exception->getMessage());
+ $this->logger->error(
+ $errorMessage,
+ [
+ 'trace' => $exception->getTrace(),
+ ]
+ );
+ throw $exception;
+ } catch (\Throwable $exception) {
+ $errorMessage = sprintf('batch delete entity items: %s', $exception->getMessage());
+ $this->logger->error(
+ $errorMessage,
+ [
+ 'trace' => $exception->getTrace(),
+ ]
+ );
+
+ throw new BaseException($errorMessage, $exception->getCode(), $exception);
+ }
+
+ $this->logger->debug('deleteEntityItems.finish');
+ }
+
+ /**
+ * Execute triggers with batch call
+ *
+ *
+ * @return Generator|ResponseData[]
+ * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
+ */
+ public function executeItems(
+ string $apiMethod,
+ array $triggers
+ ): Generator {
+ $this->logger->debug(
+ 'executeItems.start',
+ [
+ 'apiMethod' => $apiMethod,
+ 'triggers' => $triggers,
+ ]
+ );
+
+ try {
+ $this->clearCommands();
+ foreach ($triggers as $cnt => $fields) {
+ if (!is_array($fields)) {
+ throw new InvalidArgumentException(
+ sprintf(
+ 'invalid type «%s» of trigger params «%s» at position %s, params must be array type',
+ gettype($fields),
+ $fields,
+ $cnt
+ )
+ );
+ }
+
+ $this->registerCommand($apiMethod, $fields);
+ }
+
+ foreach ($this->getTraversable(true) as $cnt => $executeResult) {
+ yield $cnt => $executeResult;
+ }
+ } catch (InvalidArgumentException $exception) {
+ $errorMessage = sprintf('batch execute triggers: %s', $exception->getMessage());
+ $this->logger->error(
+ $errorMessage,
+ [
+ 'trace' => $exception->getTrace(),
+ ]
+ );
+ throw $exception;
+ } catch (\Throwable $exception) {
+ $errorMessage = sprintf('batch execute triggers: %s', $exception->getMessage());
+ $this->logger->error(
+ $errorMessage,
+ [
+ 'trace' => $exception->getTrace(),
+ ]
+ );
+
+ throw new BaseException($errorMessage, $exception->getCode(), $exception);
+ }
+
+ $this->logger->debug('executeItems.finish');
+ }
+}
diff --git a/src/Services/CRM/Automation/Result/TriggerItemResult.php b/src/Services/CRM/Automation/Result/TriggerItemResult.php
new file mode 100644
index 00000000..3776bf5b
--- /dev/null
+++ b/src/Services/CRM/Automation/Result/TriggerItemResult.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the MIT-LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Bitrix24\SDK\Services\CRM\Automation\Result;
+
+use Bitrix24\SDK\Services\CRM\Common\Result\AbstractCrmItem;
+
+/**
+ * Class TriggerItemResult
+ *
+ * @property-read string $CODE
+ * @property-read string|null $NAME
+ */
+class TriggerItemResult extends AbstractCrmItem
+{
+}
diff --git a/src/Services/CRM/Automation/Result/TriggerResult.php b/src/Services/CRM/Automation/Result/TriggerResult.php
new file mode 100644
index 00000000..d7cf45d6
--- /dev/null
+++ b/src/Services/CRM/Automation/Result/TriggerResult.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the MIT-LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+
+declare(strict_types=1);
+
+namespace Bitrix24\SDK\Services\CRM\Automation\Result;
+
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+/**
+ * Class TriggerResult
+ *
+ * @package Bitrix24\SDK\Services\CRM\Automation\Result
+ */
+class TriggerResult extends AbstractResult
+{
+ /**
+ * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
+ */
+ public function trigger(): TriggerItemResult
+ {
+ return new TriggerItemResult($this->getCoreResponse()->getResponseData()->getResult());
+ }
+}
diff --git a/src/Services/CRM/Automation/Result/TriggersResult.php b/src/Services/CRM/Automation/Result/TriggersResult.php
new file mode 100644
index 00000000..a917191d
--- /dev/null
+++ b/src/Services/CRM/Automation/Result/TriggersResult.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the MIT-LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+
+declare(strict_types=1);
+
+namespace Bitrix24\SDK\Services\CRM\Automation\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+/**
+ * Class TriggersResult
+ *
+ * @package Bitrix24\SDK\Services\CRM\Automation\Result
+ */
+class TriggersResult extends AbstractResult
+{
+ /**
+ * @return TriggerItemResult[]
+ * @throws BaseException
+ */
+ public function getTriggers(): array
+ {
+ $items = [];
+ foreach ($this->getCoreResponse()->getResponseData()->getResult() as $item) {
+ $items[] = new TriggerItemResult($item);
+ }
+
+ return $items;
+ }
+
+ /**
+ * @throws BaseException
+ */
+ public function getTriggersArray(): array
+ {
+ return $this->getCoreResponse()->getResponseData()->getResult();
+ }
+}
diff --git a/src/Services/CRM/Automation/Service/Batch.php b/src/Services/CRM/Automation/Service/Batch.php
new file mode 100644
index 00000000..cd5f8e54
--- /dev/null
+++ b/src/Services/CRM/Automation/Service/Batch.php
@@ -0,0 +1,123 @@
+
+ *
+ * For the full copyright and license information, please view the MIT-LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Bitrix24\SDK\Services\CRM\Automation\Service;
+
+use Bitrix24\SDK\Services\CRM\Automation;
+use Bitrix24\SDK\Attributes\ApiBatchMethodMetadata;
+use Bitrix24\SDK\Attributes\ApiBatchServiceMetadata;
+use Bitrix24\SDK\Core\Contracts\BatchOperationsInterface;
+use Bitrix24\SDK\Core\Credentials\Scope;
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AddedItemBatchResult;
+use Bitrix24\SDK\Core\Result\DeletedItemBatchResult;
+use Bitrix24\SDK\Services\CRM\Automation\Result\TriggerItemResult;
+use Generator;
+use Psr\Log\LoggerInterface;
+
+#[ApiBatchServiceMetadata(new Scope(['crm']))]
+class Batch
+{
+ /**
+ * Batch constructor.
+ */
+ public function __construct(protected Automation\Batch $batch, protected LoggerInterface $log)
+ {
+ }
+
+ /**
+ * Batch list method for triggers
+ *
+ *
+ * @return Generator
+ * @throws BaseException
+ */
+ #[ApiBatchMethodMetadata(
+ 'crm.automation.trigger.list',
+ 'https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-list.html',
+ 'Batch list method for triggers'
+ )]
+ public function list(): Generator
+ {
+ foreach ($this->batch->getTraversableList('crm.automation.trigger.list') as $key => $value) {
+ yield $key => new TriggerItemResult($value);
+ }
+ }
+
+ /**
+ * Batch adding triggers
+ *
+ * @param array $triggers
+ *
+ * @return Generator
+ * @throws BaseException
+ */
+ #[ApiBatchMethodMetadata(
+ 'crm.automation.trigger.add',
+ 'https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-add.html',
+ 'Batch adding triggers'
+ )]
+ public function add(array $triggers): Generator
+ {
+ foreach ($this->batch->addEntityItems('crm.automation.trigger.add', $triggers) as $key => $item) {
+ yield $key => new AddedItemBatchResult($item);
+ }
+ }
+
+ /**
+ * Batch delete triggers
+ *
+ * @param array $codes
+ *
+ * @return Generator
+ * @throws BaseException
+ */
+ #[ApiBatchMethodMetadata(
+ 'crm.automation.trigger.delete',
+ 'https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-delete.html',
+ 'Batch delete triggers'
+ )]
+ public function delete(array $codes): Generator
+ {
+ foreach ($this->batch->deleteEntityItems('crm.automation.trigger.delete', $codes) as $key => $item) {
+ yield $key => new DeletedItemBatchResult($item);
+ }
+ }
+
+ /**
+ * Batch execute triggers
+ *
+ * @param array $triggers
+ *
+ * @return Generator
+ * @throws BaseException
+ */
+ #[ApiBatchMethodMetadata(
+ 'crm.automation.trigger.execute',
+ 'https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-delete.html',
+ 'Batch execute triggers'
+ )]
+ public function execute(array $triggers): Generator
+ {
+ foreach ($this->batch->executeItems('crm.automation.trigger.execute', $triggers) as $key => $item) {
+ yield $key => new DeletedItemBatchResult($item);
+ }
+ }
+}
diff --git a/src/Services/CRM/Automation/Service/Trigger.php b/src/Services/CRM/Automation/Service/Trigger.php
new file mode 100644
index 00000000..958d9142
--- /dev/null
+++ b/src/Services/CRM/Automation/Service/Trigger.php
@@ -0,0 +1,146 @@
+
+ *
+ * For the full copyright and license information, please view the MIT-LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Bitrix24\SDK\Services\CRM\Automation\Service;
+
+use Bitrix24\SDK\Attributes\ApiEndpointMetadata;
+use Bitrix24\SDK\Attributes\ApiServiceMetadata;
+use Bitrix24\SDK\Core\Contracts\CoreInterface;
+use Bitrix24\SDK\Core\Credentials\Scope;
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Core\Result\AddedItemResult;
+use Bitrix24\SDK\Core\Result\DeletedItemResult;
+use Bitrix24\SDK\Core\Result\FieldsResult;
+use Bitrix24\SDK\Core\Result\UpdatedItemResult;
+use Bitrix24\SDK\Services\AbstractService;
+use Bitrix24\SDK\Services\CRM\Automation\Result\TriggerResult;
+use Bitrix24\SDK\Services\CRM\Automation\Result\TriggersResult;
+use Psr\Log\LoggerInterface;
+
+#[ApiServiceMetadata(new Scope(['crm']))]
+class Trigger extends AbstractService
+{
+ /**
+ * Lead constructor.
+ */
+ public function __construct(public Batch $batch, CoreInterface $core, LoggerInterface $logger)
+ {
+ parent::__construct($core, $logger);
+ }
+
+ /**
+ * add new trigger
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-add.html
+ *
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'crm.automation.trigger.add',
+ 'https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-add.html',
+ 'Method adds new trigger'
+ )]
+ public function add(string $code, string $name): AddedItemResult
+ {
+ return new AddedItemResult(
+ $this->core->call(
+ 'crm.automation.trigger.add',
+ [
+ 'CODE' => $code,
+ 'NAME' => $name,
+ ]
+ )
+ );
+ }
+
+ /**
+ * Deletes the specified trigger
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-delete.html
+ *
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'crm.automation.trigger.delete',
+ 'https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-delete.html',
+ 'Deletes the specified trigger.'
+ )]
+ public function delete(string $code): DeletedItemResult
+ {
+ return new DeletedItemResult(
+ $this->core->call(
+ 'crm.automation.trigger.delete',
+ [
+ 'CODE' => $code,
+ ]
+ )
+ );
+ }
+
+ /**
+ * Get list of trigger items.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-list.html
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'crm.automation.trigger.list',
+ 'https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-list.html',
+ 'Get list of trigger items.'
+ )]
+ public function list(): TriggersResult
+ {
+ return new TriggersResult(
+ $this->core->call(
+ 'crm.automation.trigger.list',
+ []
+ )
+ );
+ }
+
+ /**
+ * Execute trigger
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-execute.html
+ *
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'crm.automation.trigger.execute',
+ 'https://apidocs.bitrix24.com/api-reference/crm/automation/triggers/crm-automation-trigger-execute.html',
+ 'Method adds new trigger'
+ )]
+ public function execute(string $code, int $ownerTypeId, int $ownerId): AddedItemResult
+ {
+ return new AddedItemResult(
+ $this->core->call(
+ 'crm.automation.trigger.execute',
+ [
+ 'CODE' => $code,
+ 'OWNER_TYPE_ID' => $ownerTypeId,
+ 'OWNER_ID' => $ownerId,
+ ]
+ )
+ );
+ }
+
+}
diff --git a/src/Services/CRM/CRMServiceBuilder.php b/src/Services/CRM/CRMServiceBuilder.php
index 40856782..664de5ab 100644
--- a/src/Services/CRM/CRMServiceBuilder.php
+++ b/src/Services/CRM/CRMServiceBuilder.php
@@ -281,6 +281,23 @@ public function activity(): Activity\Service\Activity
return $this->serviceCache[__METHOD__];
}
+
+ public function trigger(): Automation\Service\Trigger
+ {
+ if (!isset($this->serviceCache[__METHOD__])) {
+ $batch = new Automation\Batch(
+ $this->core,
+ $this->log
+ );
+ $this->serviceCache[__METHOD__] = new Automation\Service\Trigger(
+ new Automation\Service\Batch($batch, $this->log),
+ $this->core,
+ $this->log
+ );
+ }
+
+ return $this->serviceCache[__METHOD__];
+ }
public function activityFetcher(): Activity\ActivityFetcherBuilder
{
diff --git a/tests/Integration/Services/CRM/Automation/Service/BatchTest.php b/tests/Integration/Services/CRM/Automation/Service/BatchTest.php
new file mode 100644
index 00000000..94b2be7e
--- /dev/null
+++ b/tests/Integration/Services/CRM/Automation/Service/BatchTest.php
@@ -0,0 +1,113 @@
+
+ *
+ * For the full copyright and license information, please view the MIT-LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Bitrix24\SDK\Tests\Integration\Services\CRM\Automation\Service;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\CRM\Automation\Service\Trigger;
+use Bitrix24\SDK\Tests\Integration\Fabric;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * Class BatchTest
+ *
+ * @package Bitrix24\SDK\Tests\Integration\Services\CRM\Automation\Service
+ */
+#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\CRM\Automation\Service\Batch::class)]
+#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\CRM\Lead\Service\Batch::class)]
+#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\CRM\Deal\Service\Batch::class)]
+class BatchTest extends TestCase
+{
+ public const TRIGGER_CODE = 'b24phpsdk';
+
+ protected Trigger $triggerService;
+
+ protected function setUp(): void
+ {
+ $this->triggerService = Fabric::getServiceBuilder(true)->getCRMScope()->trigger();
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[\PHPUnit\Framework\Attributes\TestDox('Batch list triggers')]
+ public function testBatchList(): void
+ {
+ $this->triggerService->add(self::TRIGGER_CODE, 'B24phpsdk trigger');
+ $cnt = 0;
+
+ foreach ($this->triggerService->batch->list() as $item) {
+ $cnt++;
+ }
+
+ self::assertGreaterThanOrEqual(1, $cnt);
+ $this->triggerService->delete(self::TRIGGER_CODE);
+ }
+
+ /**
+ * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
+ */
+ #[\PHPUnit\Framework\Attributes\TestDox('Batch add lead')]
+ public function testBatchAdd(): void
+ {
+ $items = [];
+ $max = 5;
+ for ($i = 0; $i < $max; $i++) {
+ $items[] = ['CODE' => self::TRIGGER_CODE . $i, 'NAME' => 'B24phpsdk trigger ' . $i];
+ }
+
+ $cnt = 0;
+ foreach ($this->triggerService->batch->add($items) as $item) {
+ $cnt++;
+ }
+
+ self::assertEquals(count($items), $cnt);
+
+ for ($i = 0; $i < $max; $i++) {
+ $this->triggerService->delete(self::TRIGGER_CODE . $i);
+ }
+ }
+
+ /**
+ * @throws \Bitrix24\SDK\Core\Exceptions\BaseException
+ */
+ #[\PHPUnit\Framework\Attributes\TestDox('Batch delete deals')]
+ public function testBatchDelete(): void
+ {
+ $items = [];
+ $max = 5;
+ for ($i = 0; $i < $max; $i++) {
+ $items[] = ['CODE' => self::TRIGGER_CODE . $i, 'NAME' => 'B24phpsdk trigger ' . $i];
+ }
+
+ $cnt = 0;
+ foreach ($this->triggerService->batch->add($items) as $item) {
+ $cnt++;
+ }
+
+ $items = [];
+ for ($i = 0; $i < $max; $i++) {
+ $items[] = self::TRIGGER_CODE . $i;
+ }
+
+ $cnt = 0;
+ foreach ($this->triggerService->batch->delete($items) as $deleteResult) {
+ $cnt++;
+ }
+
+ self::assertEquals(count($items), $cnt);
+ }
+
+}
\ No newline at end of file
diff --git a/tests/Integration/Services/CRM/Automation/Service/TriggerTest.php b/tests/Integration/Services/CRM/Automation/Service/TriggerTest.php
new file mode 100644
index 00000000..8a40743b
--- /dev/null
+++ b/tests/Integration/Services/CRM/Automation/Service/TriggerTest.php
@@ -0,0 +1,151 @@
+
+ *
+ * For the full copyright and license information, please view the MIT-LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+declare(strict_types=1);
+
+namespace Bitrix24\SDK\Tests\Integration\Services\CRM\Automation\Service;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Core;
+use Bitrix24\SDK\Services\CRM\Contact\Result\ContactItemResult;
+use Bitrix24\SDK\Services\CRM\Automation\Result\TriggerItemResult;
+use Bitrix24\SDK\Services\CRM\Automation\Service\Trigger;
+use Bitrix24\SDK\Tests\CustomAssertions\CustomBitrix24Assertions;
+use Bitrix24\SDK\Tests\Integration\Fabric;
+use PHPUnit\Framework\Attributes\CoversFunction;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * Class LeadTest
+ *
+ * @package Bitrix24\SDK\Tests\Integration\Services\CRM\Automation\Service
+ */
+#[CoversMethod(Trigger::class,'add')]
+#[CoversMethod(Trigger::class,'delete')]
+#[CoversMethod(Trigger::class,'list')]
+#[CoversMethod(Trigger::class,'execute')]
+class TriggerTest extends TestCase
+{
+ public const TRIGGER_CODE = 'b24phpsdk';
+
+ use CustomBitrix24Assertions;
+ protected Trigger $triggerService;
+
+ protected function setUp(): void
+ {
+ $this->triggerService = Fabric::getServiceBuilder(true)->getCRMScope()->trigger();
+ }
+
+ public function testAllSystemFieldsAnnotated(): void
+ {
+ $fields = $this->getFields();
+ $propListFromApi = (new Core\Fields\FieldsFilter())->filterSystemFields($fields);
+ $this->assertBitrix24AllResultItemFieldsAnnotated($propListFromApi, TriggerItemResult::class);
+ }
+
+ public function testAllSystemFieldsHasValidTypeAnnotation():void
+ {
+ $allFields = $this->getFieldsDescription();
+ $systemFieldsCodes = (new Core\Fields\FieldsFilter())->filterSystemFields(array_keys($allFields));
+ $systemFields = array_filter($allFields, static fn($code): bool => in_array($code, $systemFieldsCodes, true), ARRAY_FILTER_USE_KEY);
+
+ $this->assertBitrix24AllResultItemFieldsHasValidTypeAnnotation(
+ $systemFields,
+ TriggerItemResult::class);
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testAdd(): void
+ {
+ self::assertEquals(
+ 1,
+ $this->triggerService->add(
+ self::TRIGGER_CODE,
+ 'B24phpsdk trigger')
+ ->getCoreResponse()->getResponseData()->getResult()[0]
+ );
+ $this->triggerService->delete(self::TRIGGER_CODE);
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testDelete(): void
+ {
+ $this->triggerService->add(self::TRIGGER_CODE, 'B24phpsdk trigger');
+ self::assertTrue($this->triggerService->delete(self::TRIGGER_CODE)->isSuccess());
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testList(): void
+ {
+ $this->triggerService->add(self::TRIGGER_CODE, 'B24phpsdk trigger');
+ self::assertGreaterThanOrEqual(1, $this->triggerService->list()->getTriggers());
+ $this->triggerService->delete(self::TRIGGER_CODE);
+ }
+
+ /**
+ * Get Activity type fields from list response
+ */
+ protected function getFields(): array
+ {
+ // add trigger
+ $this->triggerService->add(self::TRIGGER_CODE, 'B24phpsdk trigger');
+ $list = $this->triggerService->list()->getTriggersArray();
+ // delete trigger
+ $this->triggerService->delete(self::TRIGGER_CODE);
+ //$res = $list[0]->getIterator()->getArrayCopy();
+ $res = $list[0];
+
+ return array_keys($res);
+ }
+
+ /**
+ * Get Activity type fields description from list response
+ */
+ protected function getFieldsDescription(): array
+ {
+ // add trigger
+ $this->triggerService->add(self::TRIGGER_CODE, 'B24phpsdk trigger');
+ $list = $this->triggerService->list()->getTriggersArray();
+ // delete trigger
+ $this->triggerService->delete(self::TRIGGER_CODE);
+ $res = $list[0];
+
+ $fields = [];
+ foreach ($res as $key => $value) {
+ $type = '';
+
+ if (is_string($value)) {
+ $type = 'string';
+ } elseif (is_int($value)) {
+ $type = 'int';
+ } elseif (is_bool($value)) {
+ $type = 'bool';
+ } elseif (is_array($value)) {
+ $type = 'array';
+ }
+
+ $fields[$key] = ['type' => $type];
+ }
+
+ return $fields;
+ }
+}
\ No newline at end of file