diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 47f69958..ee2ef05e 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -17,6 +17,7 @@ ->in(__DIR__ . '/src/Services/CRM/Timeline/') ->in(__DIR__ . '/src/Services/Entity/Section/') ->in(__DIR__ . '/src/Services/Department/') + ->in(__DIR__ . '/src/Services/Sale/') ->in(__DIR__ . '/src/Services/Task/') ->in(__DIR__ . '/src/Services/Sale/') ->name('*.php') diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..be621a7b --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,16 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Run integration tests for Sale scope", + "type": "shell", + "command": "make test-integration-scope-sale", + "args": [], + "isBackground": false, + "problemMatcher": [ + "$gcc" + ], + "group": "build" + } + ] +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c742a0d..b8526458 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ ### Added +- Added service `Services\Sale\PersonTypeStatus\Service\PersonTypeStatus` with support methods, + see [sale.businessValuePersonDomain.* methods](https://github.com/bitrix24/b24phpsdk/issues/228): + - `add` adds business value for person domain + - `list` retrieves list of business values for person domain + - `delete` deletes business values by filter + - `getFields` gets fields description for business value person domain - Added service `Services\Task\Service\Task` with support methods, see [tasks.task.* methods](https://github.com/bitrix24/b24phpsdk/issues/214): - `add` creates a task, with batch calls support diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 31b30e31..a69a81f2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -106,6 +106,9 @@ ./tests/Integration/Services/Department/ + + ./tests/Integration/Services/Sale/ + ./tests/Integration/Services/Task/ diff --git a/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusAddResult.php b/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusAddResult.php new file mode 100644 index 00000000..391ee13b --- /dev/null +++ b/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusAddResult.php @@ -0,0 +1,29 @@ + + * + * 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\Sale\PersonTypeStatus\Result; + +use Bitrix24\SDK\Core\Result\AddedItemResult; +use Bitrix24\SDK\Core\Exceptions\BaseException; + +class PersonTypeStatusAddResult extends AddedItemResult +{ + /** + * @throws BaseException + */ + public function isSuccess(): bool + { + $result = $this->getCoreResponse()->getResponseData()->getResult(); + return isset($result['businessValuePersonDomain']); + } +} diff --git a/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusFieldsResult.php b/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusFieldsResult.php new file mode 100644 index 00000000..a370caf5 --- /dev/null +++ b/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusFieldsResult.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\Sale\PersonTypeStatus\Result; + +use Bitrix24\SDK\Core\Result\FieldsResult; +use Bitrix24\SDK\Core\Exceptions\BaseException; + +class PersonTypeStatusFieldsResult extends FieldsResult +{ + /** + * @throws BaseException + */ + public function getFieldsDescription(): array + { + return $this->getCoreResponse()->getResponseData()->getResult()['businessValuePersonDomain']; + } +} diff --git a/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusItemResult.php b/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusItemResult.php new file mode 100644 index 00000000..3aefb6d3 --- /dev/null +++ b/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusItemResult.php @@ -0,0 +1,27 @@ + + * + * 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\Sale\PersonTypeStatus\Result; + +use Bitrix24\SDK\Core\Result\AbstractItem; + +/** + * Class PersonTypeStatusItemResult + * + * @property-read string|null $domain + * @property-read int|null $personTypeId + */ +class PersonTypeStatusItemResult extends AbstractItem +{ + // Access individual fields via magic getters, e.g. $item->domain, $item->personTypeId +} diff --git a/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusesResult.php b/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusesResult.php new file mode 100644 index 00000000..726c3809 --- /dev/null +++ b/src/Services/Sale/PersonTypeStatus/Result/PersonTypeStatusesResult.php @@ -0,0 +1,32 @@ + + * + * 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\Sale\PersonTypeStatus\Result; + +use Bitrix24\SDK\Core\Result\AbstractResult; + +class PersonTypeStatusesResult extends AbstractResult +{ + /** + * @return PersonTypeStatusItemResult[] + */ + public function getPersonTypeStatuses(): array + { + $items = []; + foreach ($this->getCoreResponse()->getResponseData()->getResult()['businessValuePersonDomains'] as $item) { + $items[] = new PersonTypeStatusItemResult($item); + } + + return $items; + } +} diff --git a/src/Services/Sale/PersonTypeStatus/Service/PersonTypeStatus.php b/src/Services/Sale/PersonTypeStatus/Service/PersonTypeStatus.php new file mode 100644 index 00000000..70aed0e4 --- /dev/null +++ b/src/Services/Sale/PersonTypeStatus/Service/PersonTypeStatus.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\Sale\PersonTypeStatus\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\Sale\PersonTypeStatus\Result\PersonTypeStatusesResult; +use Bitrix24\SDK\Services\Sale\PersonTypeStatus\Result\PersonTypeStatusFieldsResult; +use Bitrix24\SDK\Services\Sale\PersonTypeStatus\Result\PersonTypeStatusAddResult; +use Bitrix24\SDK\Core\Result\DeletedItemResult; +use Psr\Log\LoggerInterface; + +class PersonTypeStatus extends AbstractService +{ + public function __construct(CoreInterface $core, LoggerInterface $logger) + { + parent::__construct($core, $logger); + } + + /** + * Add business value for person domain. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/business-value-person-domain/sale-business-value-person-domain-add.html + * + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + * @throws \Bitrix24\SDK\Core\Exceptions\TransportException + */ + #[ApiEndpointMetadata( + 'sale.businessValuePersonDomain.add', + 'https://apidocs.bitrix24.com/api-reference/sale/business-value-person-domain/sale-business-value-person-domain-add.html', + 'Add business value for person domain' + )] + public function add(int $personTypeId, string $domain): PersonTypeStatusAddResult + { + return new PersonTypeStatusAddResult( + $this->core->call( + 'sale.businessValuePersonDomain.add', + [ + 'fields' => [ + 'personTypeId' => $personTypeId, + 'domain' => $domain + ] + ] + ) + ); + } + + /** + * Retrieves list of business values for person domain. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/business-value-person-domain/sale-business-value-person-domain-list.html + * + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + * @throws \Bitrix24\SDK\Core\Exceptions\TransportException + */ + #[ApiEndpointMetadata( + 'sale.businessValuePersonDomain.list', + 'https://apidocs.bitrix24.com/api-reference/sale/business-value-person-domain/sale-business-value-person-domain-list.html', + 'List business values for person domain' + )] + public function list(array $filter = [], array $order = [], array $select = [], ?int $start = null): PersonTypeStatusesResult + { + $params = ['filter' => $filter, 'order' => $order, 'select' => $select]; + if ($start !== null) { + $params['start'] = $start; + } + + return new PersonTypeStatusesResult( + $this->core->call( + 'sale.businessValuePersonDomain.list', + $params + ) + ); + } + + /** + * Delete business values matching filter. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/business-value-person-domain/sale-business-value-person-domain-delete-by-filter.html + * + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + * @throws \Bitrix24\SDK\Core\Exceptions\TransportException + */ + #[ApiEndpointMetadata( + 'sale.businessValuePersonDomain.deleteByFilter', + 'https://apidocs.bitrix24.com/api-reference/sale/business-value-person-domain/sale-business-value-person-domain-delete-by-filter.html', + 'Delete business values by filter' + )] + public function delete(int $personTypeId, string $domain): DeletedItemResult + { + return new DeletedItemResult( + $this->core->call( + 'sale.businessValuePersonDomain.deleteByFilter', + ['fields' => + [ + 'personTypeId' => $personTypeId, + 'domain' => $domain + ] + ] + ) + ); + } + + /** + * Get fields description for business value person domain. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/business-value-person-domain/sale-business-value-person-domain-getfields.html + * + * @throws \Bitrix24\SDK\Core\Exceptions\BaseException + * @throws \Bitrix24\SDK\Core\Exceptions\TransportException + */ + #[ApiEndpointMetadata( + 'sale.businessValuePersonDomain.getFields', + 'https://apidocs.bitrix24.com/api-reference/sale/business-value-person-domain/sale-business-value-person-domain-getfields.html', + 'Get fields for business value person domain' + )] + public function getFields(): PersonTypeStatusFieldsResult + { + return new PersonTypeStatusFieldsResult( + $this->core->call( + 'sale.businessValuePersonDomain.getFields', + [] + ) + ); + } +} diff --git a/src/Services/Sale/SaleServiceBuilder.php b/src/Services/Sale/SaleServiceBuilder.php index 7ca6cc12..cae5ce0e 100644 --- a/src/Services/Sale/SaleServiceBuilder.php +++ b/src/Services/Sale/SaleServiceBuilder.php @@ -16,10 +16,23 @@ use Bitrix24\SDK\Attributes\ApiServiceBuilderMetadata; use Bitrix24\SDK\Core\Credentials\Scope; use Bitrix24\SDK\Services\AbstractServiceBuilder; +use Bitrix24\SDK\Services\Sale\PersonTypeStatus\Service\PersonTypeStatus; #[ApiServiceBuilderMetadata(new Scope(['sale']))] class SaleServiceBuilder extends AbstractServiceBuilder { + public function personTypeStatus(): PersonTypeStatus + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new PersonTypeStatus( + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } + public function personType(): PersonType\Service\PersonType { if (!isset($this->serviceCache[__METHOD__])) { @@ -31,5 +44,4 @@ public function personType(): PersonType\Service\PersonType return $this->serviceCache[__METHOD__]; } - } diff --git a/src/Services/ServiceBuilder.php b/src/Services/ServiceBuilder.php index c8d9c863..88656329 100644 --- a/src/Services/ServiceBuilder.php +++ b/src/Services/ServiceBuilder.php @@ -274,4 +274,4 @@ public function getAiAdminScope(): AIServiceBuilder return $this->serviceCache[__METHOD__]; } -} \ No newline at end of file +} diff --git a/tests/Integration/Services/Sale/PersonTypeStatus/Service/PersonTypeStatusTest.php b/tests/Integration/Services/Sale/PersonTypeStatus/Service/PersonTypeStatusTest.php new file mode 100644 index 00000000..1174a2ad --- /dev/null +++ b/tests/Integration/Services/Sale/PersonTypeStatus/Service/PersonTypeStatusTest.php @@ -0,0 +1,105 @@ +service = Fabric::getServiceBuilder()->getSaleScope()->personTypeStatus(); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testFields(): void + { + self::assertIsArray($this->service->getFields()->getFieldsDescription()); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testList(): void + { + $list = $this->service->list(); + $items = $list->getPersonTypeStatuses(); + if ($items !== []) { + self::assertInstanceOf(PersonTypeStatusItemResult::class, $items[0]); + } else { + self::assertIsArray($items); + } + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testAdd(): void + { + $personTypeId = $this->getPersonTypeId(); + + self::assertTrue($this->service->add($personTypeId, 'I')->isSuccess()); + + $items = $this->service->list(['personTypeId' => $personTypeId, 'domain' => 'I'])->getPersonTypeStatuses(); + self::assertNotEmpty($items); + self::assertEquals('I', $items[0]->domain); + self::assertEquals($personTypeId, $items[0]->personTypeId); + + // cleanup + $this->deletePersonType($personTypeId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testDelete(): void + { + $personTypeId = $this->getPersonTypeId(); + + $this->service->add($personTypeId, 'I'); + + $deletedItemResult = $this->service->delete($personTypeId, 'I'); + self::assertTrue($deletedItemResult->isSuccess()); + + $itemsAfter = $this->service->list(['personTypeId' => $personTypeId, 'domain' => 'I'])->getPersonTypeStatuses(); + self::assertEmpty($itemsAfter); + + // cleanup + $this->deletePersonType($personTypeId); + } + + protected function getPersonTypeId(): int + { + $core = Fabric::getCore(); + return (int)$core->call('sale.persontype.add', [ + 'fields' => [ + 'name' => 'Test Person Type', + 'sort' => 100, + ] + ])->getResponseData()->getResult()['personType']['id']; + } + + protected function deletePersonType(int $id): void + { + $core = Fabric::getCore(); + $core->call('sale.persontype.delete', [ + 'id' => $id + ]); + } + +}