From 8941b38e4791d55a8dae7d7510547331af447f45 Mon Sep 17 00:00:00 2001 From: Dmitriy Ignatenko Date: Mon, 14 Sep 2026 19:32:56 +0400 Subject: [PATCH 1/3] Add userfieldconfig methods --- .php-cs-fixer.php | 2 + CHANGELOG.md | 17 ++ Makefile | 8 + phpstan.neon.dist | 2 + phpunit.xml.dist | 6 + rector.php | 4 + src/Services/CRM/CRMServiceBuilder.php | 17 ++ .../CRM/Type/Events/CrmTypeEventsFactory.php | 57 +++++ .../OnCrmTypeUserFieldAdd.php | 26 +++ .../OnCrmTypeUserFieldAddPayload.php | 25 +++ .../OnCrmTypeUserFieldDelete.php | 26 +++ .../OnCrmTypeUserFieldDeletePayload.php | 25 +++ .../OnCrmTypeUserFieldSetEnumValues.php | 26 +++ ...OnCrmTypeUserFieldSetEnumValuesPayload.php | 25 +++ .../OnCrmTypeUserFieldUpdate.php | 26 +++ .../OnCrmTypeUserFieldUpdatePayload.php | 25 +++ .../CRM/Type/Result/AddedTypeItemResult.php | 2 +- .../CRM/Type/Result/DeletedItemResult.php | 2 +- .../CRM/Type/Result/UpdatedTypeItemResult.php | 2 +- src/Services/CRM/Userfieldconfig/Batch.php | 138 ++++++++++++ .../AddedUserfieldConfigItemBatchResult.php | 40 ++++ .../Result/AddedUserfieldConfigItemResult.php | 28 +++ .../DeletedUserfieldConfigItemBatchResult.php | 39 ++++ .../DeletedUserfieldConfigItemResult.php | 31 +++ .../UpdatedUserfieldConfigItemBatchResult.php | 37 ++++ .../UpdatedUserfieldConfigItemResult.php | 31 +++ .../Result/UserfieldConfigEnumItemResult.php | 28 +++ .../Result/UserfieldConfigItemResult.php | 42 ++++ .../Result/UserfieldConfigResult.php | 30 +++ .../Result/UserfieldConfigTypeItemResult.php | 24 +++ .../Result/UserfieldConfigTypesResult.php | 34 +++ .../Result/UserfieldConfigsResult.php | 34 +++ .../CRM/Userfieldconfig/Service/Batch.php | 104 +++++++++ .../Service/Userfieldconfig.php | 201 ++++++++++++++++++ src/Services/RemoteEventsFactory.php | 2 + .../Result/UserfieldConfigItemResultTest.php | 97 +++++++++ .../CRM/Userfieldconfig/Service/BatchTest.php | 148 +++++++++++++ .../Service/UserfieldconfigTest.php | 129 +++++++++++ .../Type/Events/CrmTypeEventsFactoryTest.php | 148 +++++++++++++ .../Service/UserfieldconfigTest.php | 130 +++++++++++ 40 files changed, 1815 insertions(+), 3 deletions(-) create mode 100644 src/Services/CRM/Type/Events/CrmTypeEventsFactory.php create mode 100644 src/Services/CRM/Type/Events/OnCrmTypeUserFieldAdd/OnCrmTypeUserFieldAdd.php create mode 100644 src/Services/CRM/Type/Events/OnCrmTypeUserFieldAdd/OnCrmTypeUserFieldAddPayload.php create mode 100644 src/Services/CRM/Type/Events/OnCrmTypeUserFieldDelete/OnCrmTypeUserFieldDelete.php create mode 100644 src/Services/CRM/Type/Events/OnCrmTypeUserFieldDelete/OnCrmTypeUserFieldDeletePayload.php create mode 100644 src/Services/CRM/Type/Events/OnCrmTypeUserFieldSetEnumValues/OnCrmTypeUserFieldSetEnumValues.php create mode 100644 src/Services/CRM/Type/Events/OnCrmTypeUserFieldSetEnumValues/OnCrmTypeUserFieldSetEnumValuesPayload.php create mode 100644 src/Services/CRM/Type/Events/OnCrmTypeUserFieldUpdate/OnCrmTypeUserFieldUpdate.php create mode 100644 src/Services/CRM/Type/Events/OnCrmTypeUserFieldUpdate/OnCrmTypeUserFieldUpdatePayload.php create mode 100644 src/Services/CRM/Userfieldconfig/Batch.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemBatchResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/DeletedUserfieldConfigItemBatchResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/DeletedUserfieldConfigItemResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/UpdatedUserfieldConfigItemBatchResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/UpdatedUserfieldConfigItemResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/UserfieldConfigEnumItemResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/UserfieldConfigResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/UserfieldConfigTypeItemResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/UserfieldConfigTypesResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Result/UserfieldConfigsResult.php create mode 100644 src/Services/CRM/Userfieldconfig/Service/Batch.php create mode 100644 src/Services/CRM/Userfieldconfig/Service/Userfieldconfig.php create mode 100644 tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php create mode 100644 tests/Integration/Services/CRM/Userfieldconfig/Service/BatchTest.php create mode 100644 tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php create mode 100644 tests/Unit/Services/CRM/Type/Events/CrmTypeEventsFactoryTest.php create mode 100644 tests/Unit/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index e5c58cf21..60088a446 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -12,6 +12,8 @@ ->in(__DIR__ . '/src/Services/CRM/Quote/') ->in(__DIR__ . '/src/Services/CRM/Lead/') ->in(__DIR__ . '/src/Services/CRM/Currency/') + ->in(__DIR__ . '/src/Services/CRM/Type/') + ->in(__DIR__ . '/src/Services/CRM/Userfieldconfig/') ->in(__DIR__ . '/src/Services/Catalog/') ->in(__DIR__ . '/src/Services/CRM/Requisites/') ->in(__DIR__ . '/src/Services/CRM/Status/') diff --git a/CHANGELOG.md b/CHANGELOG.md index 30197e9c4..a71e05b19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ ## Unreleased +### Added + +- Added service `Services\CRM\Userfieldconfig` with support methods, + see [userfieldconfig.* methods](https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/index.html) ([#605](https://github.com/bitrix24/b24phpsdk/issues/605)): + - `add` adds a new custom field for a CRM smart-process type, the new invoice or the sign document entity, with batch calls support + - `update` updates the settings of an existing custom field, with batch calls support + - `get` returns the settings of a custom field by its identifier + - `list` returns a list of custom field settings matching the filter + - `delete` deletes a custom field, with batch calls support + - `getTypes` returns the set of custom field types available for the specified module +- Added support for events + see [userfieldconfig events](https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/events/index.html) ([#605](https://github.com/bitrix24/b24phpsdk/issues/605)): + - `onCrmTypeUserFieldAdd` + - `onCrmTypeUserFieldUpdate` + - `onCrmTypeUserFieldDelete` + - `onCrmTypeUserFieldSetEnumValues` + ## 1.11.0 - 2026.08.31 ### Added diff --git a/Makefile b/Makefile index 47ec23721..d2310a576 100644 --- a/Makefile +++ b/Makefile @@ -373,6 +373,14 @@ test-integration-sale-property-relation: .PHONY: test-integration-scope-crm test-integration-scope-crm: docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_scope_crm + +.PHONY: test-integration-crm-type +test-integration-crm-type: + docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_crm_type + +.PHONY: test-integration-crm-userfieldconfig +test-integration-crm-userfieldconfig: + docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_crm_userfieldconfig .PHONY: integration_tests_scope_crm_address integration_tests_scope_crm_address: diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 62605da91..5af1b78a5 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -28,6 +28,8 @@ parameters: - tests/Integration/Services/CRM/Quote/Service/QuoteProductRowsTest.php - tests/Integration/Services/CRM/Lead/Service/LeadUserfieldTest.php - tests/Integration/Services/CRM/Currency + - tests/Integration/Services/CRM/Type + - tests/Integration/Services/CRM/Userfieldconfig - tests/Integration/Services/CRM/Requisites - tests/Integration/Services/Task - tests/Integration/Services/Sale diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 91ba4642d..67ce5e6fc 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -118,6 +118,12 @@ ./tests/Integration/Services/CRM/Currency/ + + ./tests/Integration/Services/CRM/Type/ + + + ./tests/Integration/Services/CRM/Userfieldconfig/ + ./tests/Integration/Services/CRM/Deal/Service/DealRecurringTest.php diff --git a/rector.php b/rector.php index 867d06ff5..47dc21253 100644 --- a/rector.php +++ b/rector.php @@ -54,6 +54,10 @@ __DIR__ . '/tests/Integration/Services/CRM/Quote/Service', __DIR__ . '/src/Services/CRM/Currency', __DIR__ . '/tests/Integration/Services/CRM/Currency', + __DIR__ . '/src/Services/CRM/Type', + __DIR__ . '/tests/Integration/Services/CRM/Type', + __DIR__ . '/src/Services/CRM/Userfieldconfig', + __DIR__ . '/tests/Integration/Services/CRM/Userfieldconfig', __DIR__ . '/src/Services/CRM/Requisites', __DIR__ . '/tests/Integration/Services/CRM/Requisites', __DIR__ . '/src/Services/CRM/Timeline', diff --git a/src/Services/CRM/CRMServiceBuilder.php b/src/Services/CRM/CRMServiceBuilder.php index 429e0f4fb..3e8c502ce 100644 --- a/src/Services/CRM/CRMServiceBuilder.php +++ b/src/Services/CRM/CRMServiceBuilder.php @@ -719,4 +719,21 @@ public function type(): Type\Service\Type return $this->serviceCache[__METHOD__]; } + + public function userfieldConfig(): Userfieldconfig\Service\Userfieldconfig + { + if (!isset($this->serviceCache[__METHOD__])) { + $batch = new Userfieldconfig\Batch( + $this->core, + $this->log + ); + $this->serviceCache[__METHOD__] = new Userfieldconfig\Service\Userfieldconfig( + new Userfieldconfig\Service\Batch($batch, $this->log), + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } } diff --git a/src/Services/CRM/Type/Events/CrmTypeEventsFactory.php b/src/Services/CRM/Type/Events/CrmTypeEventsFactory.php new file mode 100644 index 000000000..836007daa --- /dev/null +++ b/src/Services/CRM/Type/Events/CrmTypeEventsFactory.php @@ -0,0 +1,57 @@ + + * + * 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\Type\Events; + +use Bitrix24\SDK\Core\Contracts\Events\EventInterface; +use Bitrix24\SDK\Core\Contracts\Events\EventsFabricInterface; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; +use Bitrix24\SDK\Services\CRM\Type\Events\OnCrmTypeUserFieldAdd\OnCrmTypeUserFieldAdd; +use Bitrix24\SDK\Services\CRM\Type\Events\OnCrmTypeUserFieldDelete\OnCrmTypeUserFieldDelete; +use Bitrix24\SDK\Services\CRM\Type\Events\OnCrmTypeUserFieldSetEnumValues\OnCrmTypeUserFieldSetEnumValues; +use Bitrix24\SDK\Services\CRM\Type\Events\OnCrmTypeUserFieldUpdate\OnCrmTypeUserFieldUpdate; +use Symfony\Component\HttpFoundation\Request; + +readonly class CrmTypeEventsFactory implements EventsFabricInterface +{ + public function isSupport(string $eventCode): bool + { + return in_array(strtoupper($eventCode), [ + OnCrmTypeUserFieldAdd::CODE, + OnCrmTypeUserFieldUpdate::CODE, + OnCrmTypeUserFieldDelete::CODE, + OnCrmTypeUserFieldSetEnumValues::CODE, + ], true); + } + + /** + * @throws InvalidArgumentException + */ + public function create(Request $eventRequest): EventInterface + { + $eventPayload = $eventRequest->request->all(); + if (!array_key_exists('event', $eventPayload)) { + throw new InvalidArgumentException('«event» key not found in event payload'); + } + + return match ($eventPayload['event']) { + OnCrmTypeUserFieldAdd::CODE => new OnCrmTypeUserFieldAdd($eventRequest), + OnCrmTypeUserFieldUpdate::CODE => new OnCrmTypeUserFieldUpdate($eventRequest), + OnCrmTypeUserFieldDelete::CODE => new OnCrmTypeUserFieldDelete($eventRequest), + OnCrmTypeUserFieldSetEnumValues::CODE => new OnCrmTypeUserFieldSetEnumValues($eventRequest), + default => throw new InvalidArgumentException( + sprintf('Unexpected event code «%s»', $eventPayload['event']) + ), + }; + } +} diff --git a/src/Services/CRM/Type/Events/OnCrmTypeUserFieldAdd/OnCrmTypeUserFieldAdd.php b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldAdd/OnCrmTypeUserFieldAdd.php new file mode 100644 index 000000000..b6b7a6e3d --- /dev/null +++ b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldAdd/OnCrmTypeUserFieldAdd.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\Type\Events\OnCrmTypeUserFieldAdd; + +use Bitrix24\SDK\Application\Requests\Events\AbstractEventRequest; + +class OnCrmTypeUserFieldAdd extends AbstractEventRequest +{ + public const CODE = 'ONCRMTYPEUSERFIELDADD'; + + public function getPayload(): OnCrmTypeUserFieldAddPayload + { + return new OnCrmTypeUserFieldAddPayload($this->eventPayload['data']); + } +} diff --git a/src/Services/CRM/Type/Events/OnCrmTypeUserFieldAdd/OnCrmTypeUserFieldAddPayload.php b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldAdd/OnCrmTypeUserFieldAddPayload.php new file mode 100644 index 000000000..627399d98 --- /dev/null +++ b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldAdd/OnCrmTypeUserFieldAddPayload.php @@ -0,0 +1,25 @@ + + * + * 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\Type\Events\OnCrmTypeUserFieldAdd; + +use Bitrix24\SDK\Core\Result\AbstractItem; + +/** + * @property-read positive-int $id + * @property-read non-empty-string $entityId + * @property-read non-empty-string $fieldName + */ +class OnCrmTypeUserFieldAddPayload extends AbstractItem +{ +} diff --git a/src/Services/CRM/Type/Events/OnCrmTypeUserFieldDelete/OnCrmTypeUserFieldDelete.php b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldDelete/OnCrmTypeUserFieldDelete.php new file mode 100644 index 000000000..49b1a0118 --- /dev/null +++ b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldDelete/OnCrmTypeUserFieldDelete.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\Type\Events\OnCrmTypeUserFieldDelete; + +use Bitrix24\SDK\Application\Requests\Events\AbstractEventRequest; + +class OnCrmTypeUserFieldDelete extends AbstractEventRequest +{ + public const CODE = 'ONCRMTYPEUSERFIELDDELETE'; + + public function getPayload(): OnCrmTypeUserFieldDeletePayload + { + return new OnCrmTypeUserFieldDeletePayload($this->eventPayload['data']); + } +} diff --git a/src/Services/CRM/Type/Events/OnCrmTypeUserFieldDelete/OnCrmTypeUserFieldDeletePayload.php b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldDelete/OnCrmTypeUserFieldDeletePayload.php new file mode 100644 index 000000000..a066b68d9 --- /dev/null +++ b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldDelete/OnCrmTypeUserFieldDeletePayload.php @@ -0,0 +1,25 @@ + + * + * 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\Type\Events\OnCrmTypeUserFieldDelete; + +use Bitrix24\SDK\Core\Result\AbstractItem; + +/** + * @property-read positive-int $id + * @property-read non-empty-string $entityId + * @property-read non-empty-string $fieldName + */ +class OnCrmTypeUserFieldDeletePayload extends AbstractItem +{ +} diff --git a/src/Services/CRM/Type/Events/OnCrmTypeUserFieldSetEnumValues/OnCrmTypeUserFieldSetEnumValues.php b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldSetEnumValues/OnCrmTypeUserFieldSetEnumValues.php new file mode 100644 index 000000000..fe3cf65d9 --- /dev/null +++ b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldSetEnumValues/OnCrmTypeUserFieldSetEnumValues.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\Type\Events\OnCrmTypeUserFieldSetEnumValues; + +use Bitrix24\SDK\Application\Requests\Events\AbstractEventRequest; + +class OnCrmTypeUserFieldSetEnumValues extends AbstractEventRequest +{ + public const CODE = 'ONCRMTYPEUSERFIELDSETENUMVALUES'; + + public function getPayload(): OnCrmTypeUserFieldSetEnumValuesPayload + { + return new OnCrmTypeUserFieldSetEnumValuesPayload($this->eventPayload['data']); + } +} diff --git a/src/Services/CRM/Type/Events/OnCrmTypeUserFieldSetEnumValues/OnCrmTypeUserFieldSetEnumValuesPayload.php b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldSetEnumValues/OnCrmTypeUserFieldSetEnumValuesPayload.php new file mode 100644 index 000000000..f5f9b7039 --- /dev/null +++ b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldSetEnumValues/OnCrmTypeUserFieldSetEnumValuesPayload.php @@ -0,0 +1,25 @@ + + * + * 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\Type\Events\OnCrmTypeUserFieldSetEnumValues; + +use Bitrix24\SDK\Core\Result\AbstractItem; + +/** + * @property-read positive-int $id + * @property-read non-empty-string $entityId + * @property-read non-empty-string $fieldName + */ +class OnCrmTypeUserFieldSetEnumValuesPayload extends AbstractItem +{ +} diff --git a/src/Services/CRM/Type/Events/OnCrmTypeUserFieldUpdate/OnCrmTypeUserFieldUpdate.php b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldUpdate/OnCrmTypeUserFieldUpdate.php new file mode 100644 index 000000000..a5a4ae08d --- /dev/null +++ b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldUpdate/OnCrmTypeUserFieldUpdate.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\Type\Events\OnCrmTypeUserFieldUpdate; + +use Bitrix24\SDK\Application\Requests\Events\AbstractEventRequest; + +class OnCrmTypeUserFieldUpdate extends AbstractEventRequest +{ + public const CODE = 'ONCRMTYPEUSERFIELDUPDATE'; + + public function getPayload(): OnCrmTypeUserFieldUpdatePayload + { + return new OnCrmTypeUserFieldUpdatePayload($this->eventPayload['data']); + } +} diff --git a/src/Services/CRM/Type/Events/OnCrmTypeUserFieldUpdate/OnCrmTypeUserFieldUpdatePayload.php b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldUpdate/OnCrmTypeUserFieldUpdatePayload.php new file mode 100644 index 000000000..423a47c71 --- /dev/null +++ b/src/Services/CRM/Type/Events/OnCrmTypeUserFieldUpdate/OnCrmTypeUserFieldUpdatePayload.php @@ -0,0 +1,25 @@ + + * + * 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\Type\Events\OnCrmTypeUserFieldUpdate; + +use Bitrix24\SDK\Core\Result\AbstractItem; + +/** + * @property-read positive-int $id + * @property-read non-empty-string $entityId + * @property-read non-empty-string $fieldName + */ +class OnCrmTypeUserFieldUpdatePayload extends AbstractItem +{ +} diff --git a/src/Services/CRM/Type/Result/AddedTypeItemResult.php b/src/Services/CRM/Type/Result/AddedTypeItemResult.php index 7f54edefa..6f7b07482 100644 --- a/src/Services/CRM/Type/Result/AddedTypeItemResult.php +++ b/src/Services/CRM/Type/Result/AddedTypeItemResult.php @@ -31,4 +31,4 @@ public function getId(): int { return (int)$this->getCoreResponse()->getResponseData()->getResult()['type']['id']; } -} \ No newline at end of file +} diff --git a/src/Services/CRM/Type/Result/DeletedItemResult.php b/src/Services/CRM/Type/Result/DeletedItemResult.php index 944fc0d88..8f8e0aea0 100644 --- a/src/Services/CRM/Type/Result/DeletedItemResult.php +++ b/src/Services/CRM/Type/Result/DeletedItemResult.php @@ -23,4 +23,4 @@ public function isSuccess(): bool { return true; } -} \ No newline at end of file +} diff --git a/src/Services/CRM/Type/Result/UpdatedTypeItemResult.php b/src/Services/CRM/Type/Result/UpdatedTypeItemResult.php index 939c802fd..a729ee0e1 100644 --- a/src/Services/CRM/Type/Result/UpdatedTypeItemResult.php +++ b/src/Services/CRM/Type/Result/UpdatedTypeItemResult.php @@ -26,4 +26,4 @@ public function isSuccess(): bool { return true; } -} \ No newline at end of file +} diff --git a/src/Services/CRM/Userfieldconfig/Batch.php b/src/Services/CRM/Userfieldconfig/Batch.php new file mode 100644 index 000000000..0f957ad59 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Batch.php @@ -0,0 +1,138 @@ + + * + * 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\Userfieldconfig; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException; +use Bitrix24\SDK\Core\Response\DTO\ResponseData; +use Generator; + +/** + * userfieldconfig.update and userfieldconfig.delete require a lowercase `id` key and a + * top-level `moduleId` key that the base \Bitrix24\SDK\Core\Batch does not build + * (it defaults to an uppercase `ID` key for deletes and has no concept of `moduleId`), + * so this scope needs its own batch command builder. + */ +class Batch extends \Bitrix24\SDK\Core\Batch +{ + /** + * Update entity items with batch call + * + * @param array> $entityItems keyed by userfieldconfig id + * + * @return Generator|ResponseData[] + * @throws BaseException + */ + public function updateUserfieldConfigItems(string $apiMethod, string $moduleId, array $entityItems): Generator + { + $this->logger->debug( + 'updateUserfieldConfigItems.start', + [ + 'apiMethod' => $apiMethod, + 'moduleId' => $moduleId, + 'entityItems' => $entityItems, + ] + ); + + try { + $this->clearCommands(); + foreach ($entityItems as $entityItemId => $field) { + if (!is_int($entityItemId)) { + throw new InvalidArgumentException( + sprintf( + 'invalid type «%s» of userfieldconfig id «%s», id must be integer type', + gettype($entityItemId), + $entityItemId + ) + ); + } + + $this->registerCommand($apiMethod, [ + 'moduleId' => $moduleId, + 'id' => $entityItemId, + 'field' => $field, + ]); + } + + foreach ($this->getTraversable(true) as $cnt => $updatedItemResult) { + yield $cnt => $updatedItemResult; + } + } catch (InvalidArgumentException $exception) { + $errorMessage = sprintf('batch update userfieldconfig items: %s', $exception->getMessage()); + $this->logger->error($errorMessage, ['trace' => $exception->getTrace()]); + throw $exception; + } catch (\Throwable $exception) { + $errorMessage = sprintf('batch update userfieldconfig items: %s', $exception->getMessage()); + $this->logger->error($errorMessage, ['trace' => $exception->getTrace()]); + throw new BaseException($errorMessage, $exception->getCode(), $exception); + } + + $this->logger->debug('updateUserfieldConfigItems.finish'); + } + + /** + * Delete entity items with batch call + * + * @param array $entityItemIds + * + * @return Generator|ResponseData[] + * @throws BaseException + */ + public function deleteUserfieldConfigItems(string $apiMethod, string $moduleId, array $entityItemIds): Generator + { + $this->logger->debug( + 'deleteUserfieldConfigItems.start', + [ + 'apiMethod' => $apiMethod, + 'moduleId' => $moduleId, + 'entityItemIds' => $entityItemIds, + ] + ); + + try { + $this->clearCommands(); + foreach ($entityItemIds as $cnt => $entityItemId) { + if (!is_int($entityItemId)) { + throw new InvalidArgumentException( + sprintf( + 'invalid type «%s» of userfieldconfig id «%s» at position %s, id must be integer type', + gettype($entityItemId), + $entityItemId, + $cnt + ) + ); + } + + $this->registerCommand($apiMethod, [ + 'moduleId' => $moduleId, + 'id' => $entityItemId, + ]); + } + + foreach ($this->getTraversable(true) as $cnt => $deletedItemResult) { + yield $cnt => $deletedItemResult; + } + } catch (InvalidArgumentException $exception) { + $errorMessage = sprintf('batch delete userfieldconfig items: %s', $exception->getMessage()); + $this->logger->error($errorMessage, ['trace' => $exception->getTrace()]); + throw $exception; + } catch (\Throwable $exception) { + $errorMessage = sprintf('batch delete userfieldconfig items: %s', $exception->getMessage()); + $this->logger->error($errorMessage, ['trace' => $exception->getTrace()]); + throw new BaseException($errorMessage, $exception->getCode(), $exception); + } + + $this->logger->debug('deleteUserfieldConfigItems.finish'); + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemBatchResult.php b/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemBatchResult.php new file mode 100644 index 000000000..aa11e124b --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemBatchResult.php @@ -0,0 +1,40 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Contracts\AddedItemIdResultInterface; +use Bitrix24\SDK\Core\Response\DTO\ResponseData; + +class AddedUserfieldConfigItemBatchResult implements AddedItemIdResultInterface +{ + public function __construct(private readonly ResponseData $responseData) + { + } + + public function getResponseData(): ResponseData + { + return $this->responseData; + } + + public function field(): UserfieldConfigItemResult + { + return new UserfieldConfigItemResult($this->responseData->getResult()['field']); + } + + #[\Override] + public function getId(): int + { + return $this->field()->id; + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemResult.php b/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemResult.php new file mode 100644 index 000000000..9e8a6d378 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemResult.php @@ -0,0 +1,28 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class AddedUserfieldConfigItemResult extends AbstractResult +{ + /** + * @throws BaseException + */ + public function field(): UserfieldConfigItemResult + { + return new UserfieldConfigItemResult($this->getCoreResponse()->getResponseData()->getResult()['field']); + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/DeletedUserfieldConfigItemBatchResult.php b/src/Services/CRM/Userfieldconfig/Result/DeletedUserfieldConfigItemBatchResult.php new file mode 100644 index 000000000..51e0e1bb6 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/DeletedUserfieldConfigItemBatchResult.php @@ -0,0 +1,39 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Contracts\DeletedItemResultInterface; +use Bitrix24\SDK\Core\Response\DTO\ResponseData; + +class DeletedUserfieldConfigItemBatchResult implements DeletedItemResultInterface +{ + public function __construct(private readonly ResponseData $responseData) + { + } + + public function getResponseData(): ResponseData + { + return $this->responseData; + } + + /** + * userfieldconfig.delete returns a null result on success, unlike the boolean + * `true` returned by most other *.delete methods. + */ + #[\Override] + public function isSuccess(): bool + { + return $this->responseData->getResult()[0] === null; + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/DeletedUserfieldConfigItemResult.php b/src/Services/CRM/Userfieldconfig/Result/DeletedUserfieldConfigItemResult.php new file mode 100644 index 000000000..67d1a6de8 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/DeletedUserfieldConfigItemResult.php @@ -0,0 +1,31 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class DeletedUserfieldConfigItemResult extends AbstractResult +{ + /** + * userfieldconfig.delete returns a null result on success, unlike the boolean + * `true` returned by most other *.delete methods. + * + * @throws BaseException + */ + public function isSuccess(): bool + { + return $this->getCoreResponse()->getResponseData()->getResult()[0] === null; + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/UpdatedUserfieldConfigItemBatchResult.php b/src/Services/CRM/Userfieldconfig/Result/UpdatedUserfieldConfigItemBatchResult.php new file mode 100644 index 000000000..067a76124 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/UpdatedUserfieldConfigItemBatchResult.php @@ -0,0 +1,37 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Response\DTO\ResponseData; + +class UpdatedUserfieldConfigItemBatchResult +{ + public function __construct(private readonly ResponseData $responseData) + { + } + + public function getResponseData(): ResponseData + { + return $this->responseData; + } + + /** + * userfieldconfig.update returns the full updated field descriptor under the + * `field` key, same shape as userfieldconfig.add. + */ + public function field(): UserfieldConfigItemResult + { + return new UserfieldConfigItemResult($this->responseData->getResult()['field']); + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/UpdatedUserfieldConfigItemResult.php b/src/Services/CRM/Userfieldconfig/Result/UpdatedUserfieldConfigItemResult.php new file mode 100644 index 000000000..66fba28f1 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/UpdatedUserfieldConfigItemResult.php @@ -0,0 +1,31 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class UpdatedUserfieldConfigItemResult extends AbstractResult +{ + /** + * userfieldconfig.update returns the full updated field descriptor under the + * `field` key, same shape as userfieldconfig.add. + * + * @throws BaseException + */ + public function field(): UserfieldConfigItemResult + { + return new UserfieldConfigItemResult($this->getCoreResponse()->getResponseData()->getResult()['field']); + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigEnumItemResult.php b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigEnumItemResult.php new file mode 100644 index 000000000..eb54881e9 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigEnumItemResult.php @@ -0,0 +1,28 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Result\AbstractItem; + +/** + * @property-read positive-int $id + * @property-read positive-int $userFieldId + * @property-read string $value + * @property-read bool $def + * @property-read int $sort + * @property-read string|null $xmlId + */ +class UserfieldConfigEnumItemResult extends AbstractItem +{ +} diff --git a/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResult.php b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResult.php new file mode 100644 index 000000000..88e431fa8 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResult.php @@ -0,0 +1,42 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Result\AbstractItem; + +/** + * @property-read positive-int $id + * @property-read non-empty-string $entityId + * @property-read non-empty-string $fieldName + * @property-read non-empty-string $userTypeId + * @property-read string|null $xmlId + * @property-read int $sort + * @property-read bool $multiple + * @property-read bool $mandatory + * @property-read string $showFilter + * @property-read bool $showInList + * @property-read bool $editInList + * @property-read bool $isSearchable + * @property-read array $settings + * @property-read array $languageId + * @property-read array $editFormLabel + * @property-read array $listColumnLabel + * @property-read array $listFilterLabel + * @property-read array $errorMessage + * @property-read array $helpMessage + * @property-read array|null $enum + */ +class UserfieldConfigItemResult extends AbstractItem +{ +} diff --git a/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigResult.php b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigResult.php new file mode 100644 index 000000000..f15b12c23 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigResult.php @@ -0,0 +1,30 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class UserfieldConfigResult extends AbstractResult +{ + /** + * @throws BaseException + */ + public function field(): ?UserfieldConfigItemResult + { + $field = $this->getCoreResponse()->getResponseData()->getResult()['field']; + + return $field === null ? null : new UserfieldConfigItemResult($field); + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigTypeItemResult.php b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigTypeItemResult.php new file mode 100644 index 000000000..5af86bbf2 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigTypeItemResult.php @@ -0,0 +1,24 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Result\AbstractItem; + +/** + * @property-read non-empty-string $userTypeId + * @property-read string $description + */ +class UserfieldConfigTypeItemResult extends AbstractItem +{ +} diff --git a/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigTypesResult.php b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigTypesResult.php new file mode 100644 index 000000000..a59c01211 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigTypesResult.php @@ -0,0 +1,34 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class UserfieldConfigTypesResult extends AbstractResult +{ + /** + * @return array keyed by user field type code + * @throws BaseException + */ + public function getTypes(): array + { + $items = []; + foreach ($this->getCoreResponse()->getResponseData()->getResult()['types'] as $typeCode => $item) { + $items[$typeCode] = new UserfieldConfigTypeItemResult($item); + } + + return $items; + } +} diff --git a/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigsResult.php b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigsResult.php new file mode 100644 index 000000000..cd49040b2 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigsResult.php @@ -0,0 +1,34 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +class UserfieldConfigsResult extends AbstractResult +{ + /** + * @return UserfieldConfigItemResult[] + * @throws BaseException + */ + public function getUserfieldConfigs(): array + { + $items = []; + foreach ($this->getCoreResponse()->getResponseData()->getResult()['fields'] as $item) { + $items[] = new UserfieldConfigItemResult($item); + } + + return $items; + } +} diff --git a/src/Services/CRM/Userfieldconfig/Service/Batch.php b/src/Services/CRM/Userfieldconfig/Service/Batch.php new file mode 100644 index 000000000..df6e04a6b --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Service/Batch.php @@ -0,0 +1,104 @@ + + * + * 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\Userfieldconfig\Service; + +use Bitrix24\SDK\Attributes\ApiBatchMethodMetadata; +use Bitrix24\SDK\Attributes\ApiBatchServiceMetadata; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Services\CRM\Userfieldconfig; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\AddedUserfieldConfigItemBatchResult; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\DeletedUserfieldConfigItemBatchResult; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\UpdatedUserfieldConfigItemBatchResult; +use Generator; +use Psr\Log\LoggerInterface; + +#[ApiBatchServiceMetadata(new Scope(['crm', 'userfieldconfig']))] +class Batch +{ + public function __construct(protected Userfieldconfig\Batch $batch, protected LoggerInterface $log) + { + } + + /** + * Batch adding custom fields + * + * @param non-empty-string $moduleId + * @param array> $fields + * + * @return Generator + * @throws BaseException + */ + #[ApiBatchMethodMetadata( + 'userfieldconfig.add', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-add.html', + 'Batch adding custom fields' + )] + public function add(string $moduleId, array $fields): Generator + { + $items = []; + foreach ($fields as $field) { + $items[] = [ + 'moduleId' => $moduleId, + 'field' => $field, + ]; + } + + foreach ($this->batch->addEntityItems('userfieldconfig.add', $items) as $key => $item) { + yield $key => new AddedUserfieldConfigItemBatchResult($item); + } + } + + /** + * Batch updating custom fields + * + * @param non-empty-string $moduleId + * @param array> $fields keyed by userfieldconfig id + * + * @return Generator + * @throws BaseException + */ + #[ApiBatchMethodMetadata( + 'userfieldconfig.update', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-update.html', + 'Batch updating custom fields' + )] + public function update(string $moduleId, array $fields): Generator + { + foreach ($this->batch->updateUserfieldConfigItems('userfieldconfig.update', $moduleId, $fields) as $key => $item) { + yield $key => new UpdatedUserfieldConfigItemBatchResult($item); + } + } + + /** + * Batch deleting custom fields + * + * @param non-empty-string $moduleId + * @param positive-int[] $ids + * + * @return Generator + * @throws BaseException + */ + #[ApiBatchMethodMetadata( + 'userfieldconfig.delete', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-delete.html', + 'Batch deleting custom fields' + )] + public function delete(string $moduleId, array $ids): Generator + { + foreach ($this->batch->deleteUserfieldConfigItems('userfieldconfig.delete', $moduleId, $ids) as $key => $item) { + yield $key => new DeletedUserfieldConfigItemBatchResult($item); + } + } +} diff --git a/src/Services/CRM/Userfieldconfig/Service/Userfieldconfig.php b/src/Services/CRM/Userfieldconfig/Service/Userfieldconfig.php new file mode 100644 index 000000000..4b086a335 --- /dev/null +++ b/src/Services/CRM/Userfieldconfig/Service/Userfieldconfig.php @@ -0,0 +1,201 @@ + + * + * 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\Userfieldconfig\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\Services\AbstractService; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\AddedUserfieldConfigItemResult; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\DeletedUserfieldConfigItemResult; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\UpdatedUserfieldConfigItemResult; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\UserfieldConfigResult; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\UserfieldConfigsResult; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\UserfieldConfigTypesResult; +use Psr\Log\LoggerInterface; + +#[ApiServiceMetadata(new Scope(['crm', 'userfieldconfig']))] +class Userfieldconfig extends AbstractService +{ + public function __construct(public Batch $batch, CoreInterface $core, LoggerInterface $logger) + { + parent::__construct($core, $logger); + } + + /** + * Adds a new custom field for a CRM smart-process type, the new invoice or the sign document entity. + * + * @link https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-add.html + * + * @param non-empty-string $moduleId + * @param array $field + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'userfieldconfig.add', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-add.html', + 'Adds a new custom field for a CRM smart-process type, the new invoice or the sign document entity.' + )] + public function add(string $moduleId, array $field): AddedUserfieldConfigItemResult + { + return new AddedUserfieldConfigItemResult( + $this->core->call('userfieldconfig.add', [ + 'moduleId' => $moduleId, + 'field' => $field, + ]) + ); + } + + /** + * Updates the settings of an existing custom field. + * + * @link https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-update.html + * + * @param non-empty-string $moduleId + * @param positive-int $id + * @param array $field + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'userfieldconfig.update', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-update.html', + 'Updates the settings of an existing custom field.' + )] + public function update(string $moduleId, int $id, array $field): UpdatedUserfieldConfigItemResult + { + return new UpdatedUserfieldConfigItemResult( + $this->core->call('userfieldconfig.update', [ + 'moduleId' => $moduleId, + 'id' => $id, + 'field' => $field, + ]) + ); + } + + /** + * Returns the settings of a custom field by its identifier. + * + * @link https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-get.html + * + * @param non-empty-string $moduleId + * @param positive-int $id + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'userfieldconfig.get', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-get.html', + 'Returns the settings of a custom field by its identifier.' + )] + public function get(string $moduleId, int $id): UserfieldConfigResult + { + return new UserfieldConfigResult( + $this->core->call('userfieldconfig.get', [ + 'moduleId' => $moduleId, + 'id' => $id, + ]) + ); + } + + /** + * Returns a list of custom field settings matching the filter. + * + * @link https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-list.html + * + * @param non-empty-string $moduleId + * @param array $select defaults to `['*']` because the API returns only a minimal, + * largely useless field set (e.g. `{"1":"1","settings":null}`) when select is empty + * @param array $order + * @param array $filter + * @param int $start + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'userfieldconfig.list', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-list.html', + 'Returns a list of custom field settings matching the filter.' + )] + public function list(string $moduleId, array $select = ['*'], array $order = [], array $filter = [], int $start = 0): UserfieldConfigsResult + { + return new UserfieldConfigsResult( + $this->core->call('userfieldconfig.list', [ + 'moduleId' => $moduleId, + 'select' => $select, + 'order' => $order, + 'filter' => $filter, + 'start' => $start, + ]) + ); + } + + /** + * Deletes a custom field. + * + * @link https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-delete.html + * + * @param non-empty-string $moduleId + * @param positive-int $id + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'userfieldconfig.delete', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-delete.html', + 'Deletes a custom field.' + )] + public function delete(string $moduleId, int $id): DeletedUserfieldConfigItemResult + { + return new DeletedUserfieldConfigItemResult( + $this->core->call('userfieldconfig.delete', [ + 'moduleId' => $moduleId, + 'id' => $id, + ]) + ); + } + + /** + * Returns the set of custom field types available for the specified module. + * + * @link https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-get-types.html + * + * @param non-empty-string $moduleId + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'userfieldconfig.getTypes', + 'https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-get-types.html', + 'Returns the set of custom field types available for the specified module.' + )] + public function getTypes(string $moduleId): UserfieldConfigTypesResult + { + return new UserfieldConfigTypesResult( + $this->core->call('userfieldconfig.getTypes', [ + 'moduleId' => $moduleId, + ]) + ); + } +} diff --git a/src/Services/RemoteEventsFactory.php b/src/Services/RemoteEventsFactory.php index 94ed4ddd1..bf6edc155 100644 --- a/src/Services/RemoteEventsFactory.php +++ b/src/Services/RemoteEventsFactory.php @@ -25,6 +25,7 @@ use Bitrix24\SDK\Services\CRM\Company\Events\CrmCompanyEventsFactory; use Bitrix24\SDK\Services\CRM\Contact\Events\CrmContactEventsFactory; use Bitrix24\SDK\Services\CRM\Documentgenerator\Document\Events\CrmDocumentGeneratorDocumentEventsFactory; +use Bitrix24\SDK\Services\CRM\Type\Events\CrmTypeEventsFactory; use Bitrix24\SDK\Services\SonetGroup\Events\SonetGroupEventsFactory; use Bitrix24\SDK\Services\Telephony\Events\TelephonyEventsFactory; use Bitrix24\SDK\Services\IMOpenLines\Connector\Events\ImConnectorEventsFactory; @@ -227,6 +228,7 @@ public static function init(LoggerInterface $logger): self new CalendarEventsFactory(), new CrmCompanyEventsFactory(), new CrmContactEventsFactory(), + new CrmTypeEventsFactory(), new CrmDocumentGeneratorDocumentEventsFactory(), new SonetGroupEventsFactory(), new SaleEventsFactory(), diff --git a/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php b/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php new file mode 100644 index 000000000..4a482cb6a --- /dev/null +++ b/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php @@ -0,0 +1,97 @@ + + * + * 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\Userfieldconfig\Result; + +use Bitrix24\SDK\Services\CRM\Type\Service\Type; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Result\UserfieldConfigItemResult; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Service\Userfieldconfig; +use Bitrix24\SDK\Tests\CustomAssertions\CustomBitrix24Assertions; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\TestCase; + +#[CoversClass(UserfieldConfigItemResult::class)] +class UserfieldConfigItemResultTest extends TestCase +{ + use CustomBitrix24Assertions; + + private Userfieldconfig $userfieldConfigService; + + private Type $typeService; + + private int $scratchTypeId; + + private int $scratchFieldId; + + #[\Override] + protected function setUp(): void + { + $this->userfieldConfigService = Fabric::getServiceBuilder()->getCRMScope()->userfieldConfig(); + $this->typeService = Fabric::getServiceBuilder()->getCRMScope()->type(); + + // entityId for userfieldconfig is CRM_{id} built from the SPA type's own `id`, + // not from `entityTypeId` (see docs for onCrmTypeUserFieldAdd, section "ENTITY_ID") + $addedType = $this->typeService->add(sprintf('%s userfieldconfig annotations test SPA type', time())); + $this->scratchTypeId = $addedType->getId(); + $entityId = sprintf('CRM_%d', $this->scratchTypeId); + + // uses userTypeId "enumeration" with a non-empty `enum` list so that the raw API + // response includes the `enum` key, matching the class annotation below + $added = $this->userfieldConfigService->add('crm', [ + 'entityId' => $entityId, + 'fieldName' => sprintf('UF_%s_%d', $entityId, time()), + 'userTypeId' => 'enumeration', + 'enum' => [ + ['value' => 'A', 'def' => 'N', 'sort' => 100], + ['value' => 'B', 'def' => 'Y', 'sort' => 200], + ], + ]); + $this->scratchFieldId = $added->field()->id; + } + + #[\Override] + protected function tearDown(): void + { + // deleting the SPA type also removes its custom fields + $this->typeService->delete($this->scratchTypeId); + } + + #[Test] + #[TestDox('all fields in UserfieldConfigItemResult are annotated in phpdoc and match with raw api response')] + public function testAllFieldsAreAnnotated(): void + { + $rawItem = $this->userfieldConfigService->get('crm', $this->scratchFieldId) + ->getCoreResponse() + ->getResponseData() + ->getResult()['field']; + + $this->assertBitrix24AllResultItemFieldsAnnotated( + array_keys($rawItem), + UserfieldConfigItemResult::class + ); + } + + #[Test] + #[TestDox('all fields in UserfieldConfigItemResult have valid type casting in magic getters')] + public function testAllFieldsHasValidTypeCastingInMagicGetters(): void + { + $item = $this->userfieldConfigService->get('crm', $this->scratchFieldId)->field(); + $this->assertBitrix24ResultItemFieldsTypeCastMatchAnnotations( + $item, + UserfieldConfigItemResult::class + ); + } +} diff --git a/tests/Integration/Services/CRM/Userfieldconfig/Service/BatchTest.php b/tests/Integration/Services/CRM/Userfieldconfig/Service/BatchTest.php new file mode 100644 index 000000000..6f9b210de --- /dev/null +++ b/tests/Integration/Services/CRM/Userfieldconfig/Service/BatchTest.php @@ -0,0 +1,148 @@ + + * + * 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\Userfieldconfig\Service; + +use Bitrix24\SDK\Services\CRM\Type\Service\Type; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Service\Batch; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Service\Userfieldconfig; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\TestCase; + +#[CoversClass(Batch::class)] +class BatchTest extends TestCase +{ + public const FIELD_LETTERS = ['A', 'B', 'C']; + + private Userfieldconfig $userfieldConfigService; + + private Type $typeService; + + private int $scratchTypeId; + + private string $entityId; + + #[\Override] + protected function setUp(): void + { + $this->userfieldConfigService = Fabric::getServiceBuilder()->getCRMScope()->userfieldConfig(); + $this->typeService = Fabric::getServiceBuilder()->getCRMScope()->type(); + + // entityId for userfieldconfig is CRM_{id} built from the SPA type's own `id`, + // not from `entityTypeId` (see docs for onCrmTypeUserFieldAdd, section "ENTITY_ID") + $addedType = $this->typeService->add(sprintf('%s userfieldconfig batch test SPA type', time())); + $this->scratchTypeId = $addedType->getId(); + $this->entityId = sprintf('CRM_%d', $this->scratchTypeId); + } + + #[\Override] + protected function tearDown(): void + { + // deleting the SPA type also removes its custom fields + $this->typeService->delete($this->scratchTypeId); + } + + public function testBatchAdd(): void + { + $fieldNames = $this->buildFieldNames(); + $items = []; + foreach ($fieldNames as $fieldName) { + $items[] = [ + 'entityId' => $this->entityId, + 'fieldName' => $fieldName, + 'userTypeId' => 'string', + ]; + } + + $cnt = 0; + $addedFieldNames = []; + foreach ($this->userfieldConfigService->batch->add('crm', $items) as $result) { + $addedFieldNames[] = $result->field()->fieldName; + $cnt++; + } + + $this->assertEquals(count($items), $cnt); + $this->assertEqualsCanonicalizing($fieldNames, $addedFieldNames); + } + + public function testBatchUpdate(): void + { + $fieldNames = $this->buildFieldNames(); + $itemsToAdd = []; + foreach ($fieldNames as $fieldName) { + $itemsToAdd[] = [ + 'entityId' => $this->entityId, + 'fieldName' => $fieldName, + 'userTypeId' => 'string', + ]; + } + + $ids = []; + foreach ($this->userfieldConfigService->batch->add('crm', $itemsToAdd) as $result) { + $ids[] = $result->getId(); + } + + $itemsToUpdate = []; + foreach ($ids as $id) { + $itemsToUpdate[$id] = ['mandatory' => 'Y']; + } + + $cnt = 0; + foreach ($this->userfieldConfigService->batch->update('crm', $itemsToUpdate) as $updateResult) { + $this->assertTrue($updateResult->field()->mandatory); + $cnt++; + } + + $this->assertEquals(count($ids), $cnt); + } + + public function testBatchDelete(): void + { + $fieldNames = $this->buildFieldNames(); + $itemsToAdd = []; + foreach ($fieldNames as $fieldName) { + $itemsToAdd[] = [ + 'entityId' => $this->entityId, + 'fieldName' => $fieldName, + 'userTypeId' => 'string', + ]; + } + + $ids = []; + foreach ($this->userfieldConfigService->batch->add('crm', $itemsToAdd) as $result) { + $ids[] = $result->getId(); + } + + $cnt = 0; + foreach ($this->userfieldConfigService->batch->delete('crm', $ids) as $deleteResult) { + $this->assertTrue($deleteResult->isSuccess()); + $cnt++; + } + + $this->assertEquals(count($ids), $cnt); + } + + /** + * @return non-empty-string[] + */ + private function buildFieldNames(): array + { + $fieldNames = []; + foreach (self::FIELD_LETTERS as $letter) { + $fieldNames[] = sprintf('UF_%s_%d%s', $this->entityId, time(), $letter); + } + + return $fieldNames; + } +} diff --git a/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php b/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php new file mode 100644 index 000000000..c730a7a31 --- /dev/null +++ b/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php @@ -0,0 +1,129 @@ + + * + * 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\Userfieldconfig\Service; + +use Bitrix24\SDK\Services\CRM\Type\Service\Type; +use Bitrix24\SDK\Services\CRM\Userfieldconfig\Service\Userfieldconfig; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\TestCase; + +#[CoversClass(Userfieldconfig::class)] +class UserfieldconfigTest extends TestCase +{ + private Userfieldconfig $userfieldConfigService; + + private Type $typeService; + + private int $scratchTypeId; + + private string $entityId; + + #[\Override] + protected function setUp(): void + { + $this->userfieldConfigService = Fabric::getServiceBuilder()->getCRMScope()->userfieldConfig(); + $this->typeService = Fabric::getServiceBuilder()->getCRMScope()->type(); + + // entityId for userfieldconfig is CRM_{id} built from the SPA type's own `id`, + // not from `entityTypeId` (see docs for onCrmTypeUserFieldAdd, section "ENTITY_ID") + $addedType = $this->typeService->add(sprintf('%s userfieldconfig test SPA type', time())); + $this->scratchTypeId = $addedType->getId(); + $this->entityId = sprintf('CRM_%d', $this->scratchTypeId); + } + + #[\Override] + protected function tearDown(): void + { + // deleting the SPA type also removes its custom fields + $this->typeService->delete($this->scratchTypeId); + } + + public function testAdd(): void + { + $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); + $result = $this->userfieldConfigService->add('crm', [ + 'entityId' => $this->entityId, + 'fieldName' => $fieldName, + 'userTypeId' => 'string', + ]); + + $this->assertEquals($fieldName, $result->field()->fieldName); + $this->assertEquals($this->entityId, $result->field()->entityId); + $this->assertEquals('string', $result->field()->userTypeId); + } + + public function testUpdate(): void + { + $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); + $added = $this->userfieldConfigService->add('crm', [ + 'entityId' => $this->entityId, + 'fieldName' => $fieldName, + 'userTypeId' => 'string', + ]); + + $updated = $this->userfieldConfigService->update('crm', $added->field()->id, ['mandatory' => 'Y']); + $this->assertTrue($updated->field()->mandatory); + $this->assertEquals($added->field()->id, $updated->field()->id); + } + + public function testGet(): void + { + $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); + $added = $this->userfieldConfigService->add('crm', [ + 'entityId' => $this->entityId, + 'fieldName' => $fieldName, + 'userTypeId' => 'string', + ]); + + $result = $this->userfieldConfigService->get('crm', $added->field()->id); + $this->assertEquals($fieldName, $result->field()?->fieldName); + $this->assertEquals($added->field()->id, $result->field()?->id); + } + + public function testList(): void + { + $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); + $added = $this->userfieldConfigService->add('crm', [ + 'entityId' => $this->entityId, + 'fieldName' => $fieldName, + 'userTypeId' => 'string', + ]); + + $items = $this->userfieldConfigService->list('crm', ['*'], [], ['entityId' => $this->entityId])->getUserfieldConfigs(); + $this->assertNotEmpty($items); + $this->assertEquals($fieldName, $items[0]->fieldName); + $this->assertEquals($added->field()->id, $items[0]->id); + } + + public function testDelete(): void + { + $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); + $added = $this->userfieldConfigService->add('crm', [ + 'entityId' => $this->entityId, + 'fieldName' => $fieldName, + 'userTypeId' => 'string', + ]); + + $this->assertTrue($this->userfieldConfigService->delete('crm', $added->field()->id)->isSuccess()); + } + + public function testGetTypes(): void + { + $types = $this->userfieldConfigService->getTypes('crm')->getTypes(); + $this->assertArrayHasKey('string', $types); + $this->assertEquals('string', $types['string']->userTypeId); + $this->assertNotEmpty($types['string']->description); + } +} diff --git a/tests/Unit/Services/CRM/Type/Events/CrmTypeEventsFactoryTest.php b/tests/Unit/Services/CRM/Type/Events/CrmTypeEventsFactoryTest.php new file mode 100644 index 000000000..ae39e31b3 --- /dev/null +++ b/tests/Unit/Services/CRM/Type/Events/CrmTypeEventsFactoryTest.php @@ -0,0 +1,148 @@ +factory = new CrmTypeEventsFactory(); + } + + #[Test] + #[TestDox('isSupport() recognizes all onCrmType user field event codes')] + #[DataProvider('supportedEventCodeProvider')] + public function testIsSupport(string $eventCode, string $expectedClass): void + { + self::assertNotEmpty($expectedClass); + self::assertTrue($this->factory->isSupport($eventCode)); + self::assertTrue($this->factory->isSupport(strtolower($eventCode))); + } + + #[Test] + #[TestDox('isSupport() rejects unrelated event codes')] + public function testIsSupportRejectsUnknownCode(): void + { + self::assertFalse($this->factory->isSupport('ONCRMCOMPANYUSERFIELDADD')); + } + + #[Test] + #[TestDox('create() builds OnCrmTypeUserFieldAdd and exposes payload fields')] + public function testCreateBuildsOnCrmTypeUserFieldAdd(): void + { + $event = $this->factory->create($this->createRequest(OnCrmTypeUserFieldAdd::CODE)); + + self::assertInstanceOf(OnCrmTypeUserFieldAdd::class, $event); + self::assertSame(OnCrmTypeUserFieldAdd::CODE, $event->getEventCode()); + + $payload = $event->getPayload(); + self::assertSame('6977', $payload->id); + self::assertSame('CRM_13', $payload->entityId); + self::assertSame('UF_CRM_13_1742999523', $payload->fieldName); + } + + #[Test] + #[TestDox('create() builds OnCrmTypeUserFieldUpdate and exposes payload fields')] + public function testCreateBuildsOnCrmTypeUserFieldUpdate(): void + { + $event = $this->factory->create($this->createRequest(OnCrmTypeUserFieldUpdate::CODE)); + + self::assertInstanceOf(OnCrmTypeUserFieldUpdate::class, $event); + self::assertSame(OnCrmTypeUserFieldUpdate::CODE, $event->getEventCode()); + + $payload = $event->getPayload(); + self::assertSame('6977', $payload->id); + self::assertSame('CRM_13', $payload->entityId); + self::assertSame('UF_CRM_13_1742999523', $payload->fieldName); + } + + #[Test] + #[TestDox('create() builds OnCrmTypeUserFieldDelete and exposes payload fields')] + public function testCreateBuildsOnCrmTypeUserFieldDelete(): void + { + $event = $this->factory->create($this->createRequest(OnCrmTypeUserFieldDelete::CODE)); + + self::assertInstanceOf(OnCrmTypeUserFieldDelete::class, $event); + self::assertSame(OnCrmTypeUserFieldDelete::CODE, $event->getEventCode()); + + $payload = $event->getPayload(); + self::assertSame('6977', $payload->id); + self::assertSame('CRM_13', $payload->entityId); + self::assertSame('UF_CRM_13_1742999523', $payload->fieldName); + } + + #[Test] + #[TestDox('create() builds OnCrmTypeUserFieldSetEnumValues and exposes payload fields')] + public function testCreateBuildsOnCrmTypeUserFieldSetEnumValues(): void + { + $event = $this->factory->create($this->createRequest(OnCrmTypeUserFieldSetEnumValues::CODE)); + + self::assertInstanceOf(OnCrmTypeUserFieldSetEnumValues::class, $event); + self::assertSame(OnCrmTypeUserFieldSetEnumValues::CODE, $event->getEventCode()); + + $payload = $event->getPayload(); + self::assertSame('6977', $payload->id); + self::assertSame('CRM_13', $payload->entityId); + self::assertSame('UF_CRM_13_1742999523', $payload->fieldName); + } + + #[Test] + #[TestDox('create() throws for an event code it does not support')] + public function testCreateThrowsForUnsupportedEvent(): void + { + $request = $this->createRequest('ONCRMCOMPANYUSERFIELDADD'); + + $this->expectException(InvalidArgumentException::class); + $this->factory->create($request); + } + + public static function supportedEventCodeProvider(): Generator + { + yield 'add' => [OnCrmTypeUserFieldAdd::CODE, OnCrmTypeUserFieldAdd::class]; + yield 'update' => [OnCrmTypeUserFieldUpdate::CODE, OnCrmTypeUserFieldUpdate::class]; + yield 'delete' => [OnCrmTypeUserFieldDelete::CODE, OnCrmTypeUserFieldDelete::class]; + yield 'setEnumValues' => [OnCrmTypeUserFieldSetEnumValues::CODE, OnCrmTypeUserFieldSetEnumValues::class]; + } + + private function createRequest(string $eventCode): Request + { + $payload = [ + 'event' => $eventCode, + 'event_handler_id' => '713', + 'data' => [ + 'id' => '6977', + 'entityId' => 'CRM_13', + 'fieldName' => 'UF_CRM_13_1742999523', + ], + 'ts' => '1742999523', + 'auth' => [ + 'application_token' => 'test_app_token', + ], + ]; + + $request = new Request([], $payload, [], [], [], [], ''); + $request->setMethod('POST'); + + return $request; + } +} diff --git a/tests/Unit/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php b/tests/Unit/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php new file mode 100644 index 000000000..ddf1856bd --- /dev/null +++ b/tests/Unit/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php @@ -0,0 +1,130 @@ +mockCore('userfieldconfig.add', [ + 'moduleId' => 'crm', + 'field' => ['entityId' => 'CRM_7', 'fieldName' => 'UF_CRM_7_TEST', 'userTypeId' => 'string'], + ]); + + self::assertInstanceOf( + AddedUserfieldConfigItemResult::class, + $this->makeService($core)->add('crm', [ + 'entityId' => 'CRM_7', + 'fieldName' => 'UF_CRM_7_TEST', + 'userTypeId' => 'string', + ]) + ); + } + + public function testUpdateBuildsParameters(): void + { + $core = $this->mockCore('userfieldconfig.update', [ + 'moduleId' => 'crm', + 'id' => 7095, + 'field' => ['mandatory' => 'Y'], + ]); + + self::assertInstanceOf( + UpdatedUserfieldConfigItemResult::class, + $this->makeService($core)->update('crm', 7095, ['mandatory' => 'Y']) + ); + } + + public function testGetBuildsParameters(): void + { + $core = $this->mockCore('userfieldconfig.get', [ + 'moduleId' => 'crm', + 'id' => 7095, + ]); + + self::assertInstanceOf(UserfieldConfigResult::class, $this->makeService($core)->get('crm', 7095)); + } + + public function testListBuildsParameters(): void + { + $core = $this->mockCore('userfieldconfig.list', [ + 'moduleId' => 'crm', + 'select' => ['*'], + 'order' => ['id' => 'DESC'], + 'filter' => ['multiple' => 'Y'], + 'start' => 0, + ]); + + self::assertInstanceOf( + UserfieldConfigsResult::class, + $this->makeService($core)->list('crm', ['*'], ['id' => 'DESC'], ['multiple' => 'Y']) + ); + } + + public function testListDefaultsToWildcardSelect(): void + { + $core = $this->mockCore('userfieldconfig.list', [ + 'moduleId' => 'crm', + 'select' => ['*'], + 'order' => [], + 'filter' => [], + 'start' => 0, + ]); + + self::assertInstanceOf(UserfieldConfigsResult::class, $this->makeService($core)->list('crm')); + } + + public function testDeleteBuildsParameters(): void + { + $core = $this->mockCore('userfieldconfig.delete', [ + 'moduleId' => 'crm', + 'id' => 7095, + ]); + + self::assertInstanceOf(DeletedUserfieldConfigItemResult::class, $this->makeService($core)->delete('crm', 7095)); + } + + public function testGetTypesBuildsParameters(): void + { + $core = $this->mockCore('userfieldconfig.getTypes', [ + 'moduleId' => 'crm', + ]); + + self::assertInstanceOf(UserfieldConfigTypesResult::class, $this->makeService($core)->getTypes('crm')); + } + + private function makeService(CoreInterface $core): Userfieldconfig + { + return new Userfieldconfig(new Batch(new UserfieldconfigBatch($core, new NullLogger()), new NullLogger()), $core, new NullLogger()); + } + + private function mockCore(string $method, array $parameters): CoreInterface + { + $response = $this->createStub(Response::class); + $core = $this->createMock(CoreInterface::class); + $core->expects($this->once()) + ->method('call') + ->with($method, $parameters) + ->willReturn($response); + + return $core; + } +} From e141ef50943155097854fce325022ca14cf9855f Mon Sep 17 00:00:00 2001 From: Dmitriy Ignatenko Date: Mon, 14 Sep 2026 20:12:05 +0400 Subject: [PATCH 2/3] Fix on liter results --- src/Services/CRM/Type/Service/Type.php | 14 ----- .../Service/Userfieldconfig.php | 5 -- .../Services/CRM/Type/Service/TypeTest.php | 54 +++++++++---------- .../Result/UserfieldConfigItemResultTest.php | 8 +-- .../CRM/Userfieldconfig/Service/BatchTest.php | 4 +- .../Service/UserfieldconfigTest.php | 36 ++++++------- .../Type/Events/CrmTypeEventsFactoryTest.php | 37 +++++++------ 7 files changed, 71 insertions(+), 87 deletions(-) diff --git a/src/Services/CRM/Type/Service/Type.php b/src/Services/CRM/Type/Service/Type.php index 66a27de3f..6af3e0580 100644 --- a/src/Services/CRM/Type/Service/Type.php +++ b/src/Services/CRM/Type/Service/Type.php @@ -35,7 +35,6 @@ class Type extends AbstractService * * @link https://apidocs.bitrix24.com/api-reference/crm/universal/user-defined-object-types/crm-type-fields.html * - * @return FieldsResult * @throws BaseException * @throws TransportException */ @@ -54,10 +53,6 @@ public function fields(): FieldsResult * * @link https://apidocs.bitrix24.com/api-reference/crm/universal/user-defined-object-types/crm-type-add.html * - * @param string $title - * @param int|null $entityTypeId - * @param array $parameters - * @return AddedTypeItemResult * @throws BaseException * @throws TransportException */ @@ -104,7 +99,6 @@ public function update(int $id, array $fields): UpdatedTypeItemResult * * @link https://apidocs.bitrix24.com/api-reference/crm/universal/user-defined-object-types/crm-type-get.html * - * @return TypeResult * @throws BaseException * @throws TransportException */ @@ -123,8 +117,6 @@ public function get(int $id): TypeResult * * @link https://apidocs.bitrix24.com/api-reference/crm/universal/user-defined-object-types/crm-type-get-by-entity-type-id.html * - * @param int $entityTypeId - * @return TypeResult * @throws BaseException * @throws TransportException */ @@ -143,10 +135,6 @@ public function getByEntityTypeId(int $entityTypeId): TypeResult * * @link https://apidocs.bitrix24.com/api-reference/crm/universal/user-defined-object-types/crm-type-get-by-entity-type-id.html * - * @param array $order - * @param array $filter - * @param int $start - * @return TypesResult * @throws BaseException * @throws TransportException */ @@ -169,8 +157,6 @@ public function list(array $order = [], array $filter = [], int $start = 0): Typ * * @link https://apidocs.bitrix24.com/api-reference/crm/universal/user-defined-object-types/crm-type-delete.html * - * @param int $entityTypeId - * @return DeletedItemResult * @throws BaseException * @throws TransportException */ diff --git a/src/Services/CRM/Userfieldconfig/Service/Userfieldconfig.php b/src/Services/CRM/Userfieldconfig/Service/Userfieldconfig.php index 4b086a335..c34287bcc 100644 --- a/src/Services/CRM/Userfieldconfig/Service/Userfieldconfig.php +++ b/src/Services/CRM/Userfieldconfig/Service/Userfieldconfig.php @@ -42,7 +42,6 @@ public function __construct(public Batch $batch, CoreInterface $core, LoggerInte * @link https://apidocs.bitrix24.com/api-reference/crm/universal/userfieldconfig/userfieldconfig-add.html * * @param non-empty-string $moduleId - * @param array $field * * @throws BaseException * @throws TransportException @@ -69,7 +68,6 @@ public function add(string $moduleId, array $field): AddedUserfieldConfigItemRes * * @param non-empty-string $moduleId * @param positive-int $id - * @param array $field * * @throws BaseException * @throws TransportException @@ -124,9 +122,6 @@ public function get(string $moduleId, int $id): UserfieldConfigResult * @param non-empty-string $moduleId * @param array $select defaults to `['*']` because the API returns only a minimal, * largely useless field set (e.g. `{"1":"1","settings":null}`) when select is empty - * @param array $order - * @param array $filter - * @param int $start * * @throws BaseException * @throws TransportException diff --git a/tests/Integration/Services/CRM/Type/Service/TypeTest.php b/tests/Integration/Services/CRM/Type/Service/TypeTest.php index 4a444367a..97356747f 100644 --- a/tests/Integration/Services/CRM/Type/Service/TypeTest.php +++ b/tests/Integration/Services/CRM/Type/Service/TypeTest.php @@ -38,63 +38,63 @@ class TypeTest extends TestCase public function testAdd(): void { $title = sprintf('%s test SPA type', time()); - $result = $this->typeService->add($title); - $this->assertEquals($title, $result->type()->title); - $this->assertTrue($this->typeService->delete($result->getId())->isSuccess()); + $addedTypeItemResult = $this->typeService->add($title); + $this->assertEquals($title, $addedTypeItemResult->type()->title); + $this->assertTrue($this->typeService->delete($addedTypeItemResult->getId())->isSuccess()); } public function testUpdate(): void { $title = sprintf('%s test SPA type', time()); - $result = $this->typeService->add($title); - $this->assertEquals($title, $result->type()->title); + $addedTypeItemResult = $this->typeService->add($title); + $this->assertEquals($title, $addedTypeItemResult->type()->title); $title = sprintf('%s updated SPA type', time()); - $updatedResult = $this->typeService->update($result->getId(), ['title' => $title]); - $this->assertEquals($title, $updatedResult->type()->title); + $updatedTypeItemResult = $this->typeService->update($addedTypeItemResult->getId(), ['title' => $title]); + $this->assertEquals($title, $updatedTypeItemResult->type()->title); - $this->assertTrue($this->typeService->delete($result->getId())->isSuccess()); + $this->assertTrue($this->typeService->delete($addedTypeItemResult->getId())->isSuccess()); } public function testGet(): void { $title = sprintf('%s test SPA type', time()); - $addResult = $this->typeService->add($title); + $addedTypeItemResult = $this->typeService->add($title); - $result = $this->typeService->get($addResult->getId()); - $this->assertEquals($title, $addResult->type()->title); - $this->assertEquals($result->type()->id, $addResult->type()->id); - $this->assertTrue($this->typeService->delete($addResult->getId())->isSuccess()); + $typeResult = $this->typeService->get($addedTypeItemResult->getId()); + $this->assertEquals($title, $addedTypeItemResult->type()->title); + $this->assertEquals($typeResult->type()->id, $addedTypeItemResult->type()->id); + $this->assertTrue($this->typeService->delete($addedTypeItemResult->getId())->isSuccess()); } public function testList(): void { $title = sprintf('%s test SPA type', time()); - $addResult = $this->typeService->add($title); - $result = $this->typeService->list([], ['id' => $addResult->getId()])->getTypes()[0]; - $this->assertEquals($title, $addResult->type()->title); - $this->assertEquals($result->id, $addResult->type()->id); - $this->assertTrue($this->typeService->delete($addResult->getId())->isSuccess()); + $addedTypeItemResult = $this->typeService->add($title); + $result = $this->typeService->list([], ['id' => $addedTypeItemResult->getId()])->getTypes()[0]; + $this->assertEquals($title, $addedTypeItemResult->type()->title); + $this->assertEquals($result->id, $addedTypeItemResult->type()->id); + $this->assertTrue($this->typeService->delete($addedTypeItemResult->getId())->isSuccess()); } public function testGetByEntityTypeId(): void { $title = sprintf('%s test SPA type', time()); - $result = $this->typeService->add($title); - $this->assertEquals($title, $result->type()->title); + $addedTypeItemResult = $this->typeService->add($title); + $this->assertEquals($title, $addedTypeItemResult->type()->title); - $resultTypeId = $this->typeService->getByEntityTypeId($result->type()->entityTypeId); - $this->assertEquals($title, $resultTypeId->type()->title); - $this->assertEquals($result->type()->id, $resultTypeId->type()->id); - $this->assertTrue($this->typeService->delete($result->getId())->isSuccess()); + $typeResult = $this->typeService->getByEntityTypeId($addedTypeItemResult->type()->entityTypeId); + $this->assertEquals($title, $typeResult->type()->title); + $this->assertEquals($addedTypeItemResult->type()->id, $typeResult->type()->id); + $this->assertTrue($this->typeService->delete($addedTypeItemResult->getId())->isSuccess()); } public function testDelete(): void { $title = sprintf('%s test SPA type', time()); - $result = $this->typeService->add($title); - $this->assertEquals($title, $result->type()->title); - $this->assertTrue($this->typeService->delete($result->getId())->isSuccess()); + $addedTypeItemResult = $this->typeService->add($title); + $this->assertEquals($title, $addedTypeItemResult->type()->title); + $this->assertTrue($this->typeService->delete($addedTypeItemResult->getId())->isSuccess()); } protected function setUp(): void diff --git a/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php b/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php index 4a482cb6a..5318ec75e 100644 --- a/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php +++ b/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php @@ -44,13 +44,13 @@ protected function setUp(): void // entityId for userfieldconfig is CRM_{id} built from the SPA type's own `id`, // not from `entityTypeId` (see docs for onCrmTypeUserFieldAdd, section "ENTITY_ID") - $addedType = $this->typeService->add(sprintf('%s userfieldconfig annotations test SPA type', time())); - $this->scratchTypeId = $addedType->getId(); + $addedTypeItemResult = $this->typeService->add(sprintf('%s userfieldconfig annotations test SPA type', time())); + $this->scratchTypeId = $addedTypeItemResult->getId(); $entityId = sprintf('CRM_%d', $this->scratchTypeId); // uses userTypeId "enumeration" with a non-empty `enum` list so that the raw API // response includes the `enum` key, matching the class annotation below - $added = $this->userfieldConfigService->add('crm', [ + $addedUserfieldConfigItemResult = $this->userfieldConfigService->add('crm', [ 'entityId' => $entityId, 'fieldName' => sprintf('UF_%s_%d', $entityId, time()), 'userTypeId' => 'enumeration', @@ -59,7 +59,7 @@ protected function setUp(): void ['value' => 'B', 'def' => 'Y', 'sort' => 200], ], ]); - $this->scratchFieldId = $added->field()->id; + $this->scratchFieldId = $addedUserfieldConfigItemResult->field()->id; } #[\Override] diff --git a/tests/Integration/Services/CRM/Userfieldconfig/Service/BatchTest.php b/tests/Integration/Services/CRM/Userfieldconfig/Service/BatchTest.php index 6f9b210de..51bf2a6c0 100644 --- a/tests/Integration/Services/CRM/Userfieldconfig/Service/BatchTest.php +++ b/tests/Integration/Services/CRM/Userfieldconfig/Service/BatchTest.php @@ -41,8 +41,8 @@ protected function setUp(): void // entityId for userfieldconfig is CRM_{id} built from the SPA type's own `id`, // not from `entityTypeId` (see docs for onCrmTypeUserFieldAdd, section "ENTITY_ID") - $addedType = $this->typeService->add(sprintf('%s userfieldconfig batch test SPA type', time())); - $this->scratchTypeId = $addedType->getId(); + $addedTypeItemResult = $this->typeService->add(sprintf('%s userfieldconfig batch test SPA type', time())); + $this->scratchTypeId = $addedTypeItemResult->getId(); $this->entityId = sprintf('CRM_%d', $this->scratchTypeId); } diff --git a/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php b/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php index c730a7a31..ead11a0b1 100644 --- a/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php +++ b/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php @@ -38,8 +38,8 @@ protected function setUp(): void // entityId for userfieldconfig is CRM_{id} built from the SPA type's own `id`, // not from `entityTypeId` (see docs for onCrmTypeUserFieldAdd, section "ENTITY_ID") - $addedType = $this->typeService->add(sprintf('%s userfieldconfig test SPA type', time())); - $this->scratchTypeId = $addedType->getId(); + $addedTypeItemResult = $this->typeService->add(sprintf('%s userfieldconfig test SPA type', time())); + $this->scratchTypeId = $addedTypeItemResult->getId(); $this->entityId = sprintf('CRM_%d', $this->scratchTypeId); } @@ -53,49 +53,49 @@ protected function tearDown(): void public function testAdd(): void { $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); - $result = $this->userfieldConfigService->add('crm', [ + $addedUserfieldConfigItemResult = $this->userfieldConfigService->add('crm', [ 'entityId' => $this->entityId, 'fieldName' => $fieldName, 'userTypeId' => 'string', ]); - $this->assertEquals($fieldName, $result->field()->fieldName); - $this->assertEquals($this->entityId, $result->field()->entityId); - $this->assertEquals('string', $result->field()->userTypeId); + $this->assertEquals($fieldName, $addedUserfieldConfigItemResult->field()->fieldName); + $this->assertEquals($this->entityId, $addedUserfieldConfigItemResult->field()->entityId); + $this->assertEquals('string', $addedUserfieldConfigItemResult->field()->userTypeId); } public function testUpdate(): void { $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); - $added = $this->userfieldConfigService->add('crm', [ + $addedUserfieldConfigItemResult = $this->userfieldConfigService->add('crm', [ 'entityId' => $this->entityId, 'fieldName' => $fieldName, 'userTypeId' => 'string', ]); - $updated = $this->userfieldConfigService->update('crm', $added->field()->id, ['mandatory' => 'Y']); - $this->assertTrue($updated->field()->mandatory); - $this->assertEquals($added->field()->id, $updated->field()->id); + $updatedUserfieldConfigItemResult = $this->userfieldConfigService->update('crm', $addedUserfieldConfigItemResult->field()->id, ['mandatory' => 'Y']); + $this->assertTrue($updatedUserfieldConfigItemResult->field()->mandatory); + $this->assertEquals($addedUserfieldConfigItemResult->field()->id, $updatedUserfieldConfigItemResult->field()->id); } public function testGet(): void { $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); - $added = $this->userfieldConfigService->add('crm', [ + $addedUserfieldConfigItemResult = $this->userfieldConfigService->add('crm', [ 'entityId' => $this->entityId, 'fieldName' => $fieldName, 'userTypeId' => 'string', ]); - $result = $this->userfieldConfigService->get('crm', $added->field()->id); - $this->assertEquals($fieldName, $result->field()?->fieldName); - $this->assertEquals($added->field()->id, $result->field()?->id); + $userfieldConfigResult = $this->userfieldConfigService->get('crm', $addedUserfieldConfigItemResult->field()->id); + $this->assertEquals($fieldName, $userfieldConfigResult->field()?->fieldName); + $this->assertEquals($addedUserfieldConfigItemResult->field()->id, $userfieldConfigResult->field()?->id); } public function testList(): void { $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); - $added = $this->userfieldConfigService->add('crm', [ + $addedUserfieldConfigItemResult = $this->userfieldConfigService->add('crm', [ 'entityId' => $this->entityId, 'fieldName' => $fieldName, 'userTypeId' => 'string', @@ -104,19 +104,19 @@ public function testList(): void $items = $this->userfieldConfigService->list('crm', ['*'], [], ['entityId' => $this->entityId])->getUserfieldConfigs(); $this->assertNotEmpty($items); $this->assertEquals($fieldName, $items[0]->fieldName); - $this->assertEquals($added->field()->id, $items[0]->id); + $this->assertEquals($addedUserfieldConfigItemResult->field()->id, $items[0]->id); } public function testDelete(): void { $fieldName = sprintf('UF_%s_%d', $this->entityId, time()); - $added = $this->userfieldConfigService->add('crm', [ + $addedUserfieldConfigItemResult = $this->userfieldConfigService->add('crm', [ 'entityId' => $this->entityId, 'fieldName' => $fieldName, 'userTypeId' => 'string', ]); - $this->assertTrue($this->userfieldConfigService->delete('crm', $added->field()->id)->isSuccess()); + $this->assertTrue($this->userfieldConfigService->delete('crm', $addedUserfieldConfigItemResult->field()->id)->isSuccess()); } public function testGetTypes(): void diff --git a/tests/Unit/Services/CRM/Type/Events/CrmTypeEventsFactoryTest.php b/tests/Unit/Services/CRM/Type/Events/CrmTypeEventsFactoryTest.php index ae39e31b3..43680db7c 100644 --- a/tests/Unit/Services/CRM/Type/Events/CrmTypeEventsFactoryTest.php +++ b/tests/Unit/Services/CRM/Type/Events/CrmTypeEventsFactoryTest.php @@ -55,10 +55,10 @@ public function testCreateBuildsOnCrmTypeUserFieldAdd(): void self::assertInstanceOf(OnCrmTypeUserFieldAdd::class, $event); self::assertSame(OnCrmTypeUserFieldAdd::CODE, $event->getEventCode()); - $payload = $event->getPayload(); - self::assertSame('6977', $payload->id); - self::assertSame('CRM_13', $payload->entityId); - self::assertSame('UF_CRM_13_1742999523', $payload->fieldName); + $onCrmTypeUserFieldAddPayload = $event->getPayload(); + self::assertSame('6977', $onCrmTypeUserFieldAddPayload->id); + self::assertSame('CRM_13', $onCrmTypeUserFieldAddPayload->entityId); + self::assertSame('UF_CRM_13_1742999523', $onCrmTypeUserFieldAddPayload->fieldName); } #[Test] @@ -70,10 +70,10 @@ public function testCreateBuildsOnCrmTypeUserFieldUpdate(): void self::assertInstanceOf(OnCrmTypeUserFieldUpdate::class, $event); self::assertSame(OnCrmTypeUserFieldUpdate::CODE, $event->getEventCode()); - $payload = $event->getPayload(); - self::assertSame('6977', $payload->id); - self::assertSame('CRM_13', $payload->entityId); - self::assertSame('UF_CRM_13_1742999523', $payload->fieldName); + $onCrmTypeUserFieldUpdatePayload = $event->getPayload(); + self::assertSame('6977', $onCrmTypeUserFieldUpdatePayload->id); + self::assertSame('CRM_13', $onCrmTypeUserFieldUpdatePayload->entityId); + self::assertSame('UF_CRM_13_1742999523', $onCrmTypeUserFieldUpdatePayload->fieldName); } #[Test] @@ -85,10 +85,10 @@ public function testCreateBuildsOnCrmTypeUserFieldDelete(): void self::assertInstanceOf(OnCrmTypeUserFieldDelete::class, $event); self::assertSame(OnCrmTypeUserFieldDelete::CODE, $event->getEventCode()); - $payload = $event->getPayload(); - self::assertSame('6977', $payload->id); - self::assertSame('CRM_13', $payload->entityId); - self::assertSame('UF_CRM_13_1742999523', $payload->fieldName); + $onCrmTypeUserFieldDeletePayload = $event->getPayload(); + self::assertSame('6977', $onCrmTypeUserFieldDeletePayload->id); + self::assertSame('CRM_13', $onCrmTypeUserFieldDeletePayload->entityId); + self::assertSame('UF_CRM_13_1742999523', $onCrmTypeUserFieldDeletePayload->fieldName); } #[Test] @@ -100,10 +100,10 @@ public function testCreateBuildsOnCrmTypeUserFieldSetEnumValues(): void self::assertInstanceOf(OnCrmTypeUserFieldSetEnumValues::class, $event); self::assertSame(OnCrmTypeUserFieldSetEnumValues::CODE, $event->getEventCode()); - $payload = $event->getPayload(); - self::assertSame('6977', $payload->id); - self::assertSame('CRM_13', $payload->entityId); - self::assertSame('UF_CRM_13_1742999523', $payload->fieldName); + $onCrmTypeUserFieldSetEnumValuesPayload = $event->getPayload(); + self::assertSame('6977', $onCrmTypeUserFieldSetEnumValuesPayload->id); + self::assertSame('CRM_13', $onCrmTypeUserFieldSetEnumValuesPayload->entityId); + self::assertSame('UF_CRM_13_1742999523', $onCrmTypeUserFieldSetEnumValuesPayload->fieldName); } #[Test] @@ -140,7 +140,10 @@ private function createRequest(string $eventCode): Request ], ]; - $request = new Request([], $payload, [], [], [], [], ''); + $rawRequest = http_build_query($payload); + parse_str($rawRequest, $requestContent); + + $request = new Request([], $requestContent, [], [], [], [], $rawRequest); $request->setMethod('POST'); return $request; From 4e7775598d1610cd572c53ca8958b2185c83a9b7 Mon Sep 17 00:00:00 2001 From: Dmitriy Ignatenko Date: Mon, 14 Sep 2026 20:27:39 +0400 Subject: [PATCH 3/3] Fix on test results --- .../Result/AddedUserfieldConfigItemBatchResult.php | 2 +- .../Result/UserfieldConfigItemResult.php | 13 +++++++++++++ .../Result/UserfieldConfigItemResultTest.php | 2 +- .../Userfieldconfig/Service/UserfieldconfigTest.php | 6 +++--- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemBatchResult.php b/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemBatchResult.php index aa11e124b..66c600c79 100644 --- a/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemBatchResult.php +++ b/src/Services/CRM/Userfieldconfig/Result/AddedUserfieldConfigItemBatchResult.php @@ -35,6 +35,6 @@ public function field(): UserfieldConfigItemResult #[\Override] public function getId(): int { - return $this->field()->id; + return (int)$this->field()->id; } } diff --git a/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResult.php b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResult.php index 88e431fa8..c118010ae 100644 --- a/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResult.php +++ b/src/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResult.php @@ -39,4 +39,17 @@ */ class UserfieldConfigItemResult extends AbstractItem { + /** + * @param int|string $offset + * + * @return mixed + */ + #[\Override] + public function __get($offset) + { + return match ($offset) { + 'multiple', 'mandatory', 'showInList', 'editInList', 'isSearchable' => $this->data[$offset] === 'Y', + default => parent::__get($offset), + }; + } } diff --git a/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php b/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php index 5318ec75e..b506d2f35 100644 --- a/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php +++ b/tests/Integration/Services/CRM/Userfieldconfig/Result/UserfieldConfigItemResultTest.php @@ -59,7 +59,7 @@ protected function setUp(): void ['value' => 'B', 'def' => 'Y', 'sort' => 200], ], ]); - $this->scratchFieldId = $addedUserfieldConfigItemResult->field()->id; + $this->scratchFieldId = (int)$addedUserfieldConfigItemResult->field()->id; } #[\Override] diff --git a/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php b/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php index ead11a0b1..b7237ebab 100644 --- a/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php +++ b/tests/Integration/Services/CRM/Userfieldconfig/Service/UserfieldconfigTest.php @@ -73,7 +73,7 @@ public function testUpdate(): void 'userTypeId' => 'string', ]); - $updatedUserfieldConfigItemResult = $this->userfieldConfigService->update('crm', $addedUserfieldConfigItemResult->field()->id, ['mandatory' => 'Y']); + $updatedUserfieldConfigItemResult = $this->userfieldConfigService->update('crm', (int)$addedUserfieldConfigItemResult->field()->id, ['mandatory' => 'Y']); $this->assertTrue($updatedUserfieldConfigItemResult->field()->mandatory); $this->assertEquals($addedUserfieldConfigItemResult->field()->id, $updatedUserfieldConfigItemResult->field()->id); } @@ -87,7 +87,7 @@ public function testGet(): void 'userTypeId' => 'string', ]); - $userfieldConfigResult = $this->userfieldConfigService->get('crm', $addedUserfieldConfigItemResult->field()->id); + $userfieldConfigResult = $this->userfieldConfigService->get('crm', (int)$addedUserfieldConfigItemResult->field()->id); $this->assertEquals($fieldName, $userfieldConfigResult->field()?->fieldName); $this->assertEquals($addedUserfieldConfigItemResult->field()->id, $userfieldConfigResult->field()?->id); } @@ -116,7 +116,7 @@ public function testDelete(): void 'userTypeId' => 'string', ]); - $this->assertTrue($this->userfieldConfigService->delete('crm', $addedUserfieldConfigItemResult->field()->id)->isSuccess()); + $this->assertTrue($this->userfieldConfigService->delete('crm', (int)$addedUserfieldConfigItemResult->field()->id)->isSuccess()); } public function testGetTypes(): void