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
+ ]);
+ }
+
+}