diff --git a/CHANGELOG.md b/CHANGELOG.md
index f4bc3b52..b51bf729 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,23 @@
### Added
+- Added services `Services\Catalog\Enum\Service\CatalogEnum`, `Services\Catalog\Extra\Service\Extra`
+ and `Services\Catalog\Measure\Service\Measure` with support for `catalog.enum.*`, `catalog.extra.*`
+ and `catalog.measure.*` methods,
+ see [catalog.enum.* methods](https://apidocs.bitrix24.com/api-reference/catalog/enum/index.html),
+ [catalog.extra.* methods](https://apidocs.bitrix24.com/api-reference/catalog/extra/index.html) and
+ [catalog.measure.* methods](https://apidocs.bitrix24.com/api-reference/catalog/measure/index.html) ([#530](https://github.com/bitrix24/b24phpsdk/issues/530)):
+ - `CatalogEnum::getRoundTypes` returns available catalog rounding types
+ - `CatalogEnum::getStoreDocumentTypes` returns available store accounting document types
+ - `Extra::get` gets information about a markup by its identifier
+ - `Extra::list` gets a list of markups by filter
+ - `Extra::fields` returns the description of markup fields
+ - `Measure::add` creates a new measurement unit
+ - `Measure::update` updates an existing measurement unit
+ - `Measure::get` gets information about a measurement unit by its identifier
+ - `Measure::list` gets the list of measurement units
+ - `Measure::delete` deletes a measurement unit
+ - `Measure::fields` returns the description of measurement unit fields
- Added service `Services\Landing\Site\Service\Site` with support methods,
see [landing.site.* methods](https://github.com/bitrix24/b24phpsdk/issues/267):
- `add` adds a site
diff --git a/Makefile b/Makefile
index c2fc4a9a..db2538a7 100644
--- a/Makefile
+++ b/Makefile
@@ -492,6 +492,18 @@ test-integration-landing-role:
test-integration-landing-repowidget:
docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_landing_repowidget
+.PHONY: test-integration-catalog-enum
+test-integration-catalog-enum:
+ docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_catalog_enum
+
+.PHONY: test-integration-catalog-extra
+test-integration-catalog-extra:
+ docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_catalog_extra
+
+.PHONY: test-integration-catalog-measure
+test-integration-catalog-measure:
+ docker compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_catalog_measure
+
# work dev environment
.PHONY: php-dev-server-up
php-dev-server-up:
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index d0187ae5..8e35fdbe 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -262,6 +262,15 @@
./tests/Integration/Services/Landing/RepoWidget/
+
+ ./tests/Integration/Services/Catalog/Enum/
+
+
+ ./tests/Integration/Services/Catalog/Extra/
+
+
+ ./tests/Integration/Services/Catalog/Measure/
+
diff --git a/src/Services/Catalog/CatalogServiceBuilder.php b/src/Services/Catalog/CatalogServiceBuilder.php
index 57c91b88..bf420bfb 100644
--- a/src/Services/Catalog/CatalogServiceBuilder.php
+++ b/src/Services/Catalog/CatalogServiceBuilder.php
@@ -18,6 +18,7 @@
use Bitrix24\SDK\Services\AbstractServiceBuilder;
use Bitrix24\SDK\Services\Catalog;
#[ApiServiceBuilderMetadata(new Scope(['catalog']))]
+
class CatalogServiceBuilder extends AbstractServiceBuilder
{
public function product(): Catalog\Product\Service\Product
@@ -44,4 +45,40 @@ public function catalog(): Catalog\Catalog\Service\Catalog
return $this->serviceCache[__METHOD__];
}
-}
\ No newline at end of file
+
+ public function catalogEnum(): Catalog\Enum\Service\CatalogEnum
+ {
+ if (!isset($this->serviceCache[__METHOD__])) {
+ $this->serviceCache[__METHOD__] = new Catalog\Enum\Service\CatalogEnum(
+ $this->core,
+ $this->log
+ );
+ }
+
+ return $this->serviceCache[__METHOD__];
+ }
+
+ public function extra(): Catalog\Extra\Service\Extra
+ {
+ if (!isset($this->serviceCache[__METHOD__])) {
+ $this->serviceCache[__METHOD__] = new Catalog\Extra\Service\Extra(
+ $this->core,
+ $this->log
+ );
+ }
+
+ return $this->serviceCache[__METHOD__];
+ }
+
+ public function measure(): Catalog\Measure\Service\Measure
+ {
+ if (!isset($this->serviceCache[__METHOD__])) {
+ $this->serviceCache[__METHOD__] = new Catalog\Measure\Service\Measure(
+ $this->core,
+ $this->log
+ );
+ }
+
+ return $this->serviceCache[__METHOD__];
+ }
+}
diff --git a/src/Services/Catalog/Enum/Result/RoundTypeItemResult.php b/src/Services/Catalog/Enum/Result/RoundTypeItemResult.php
new file mode 100644
index 00000000..e837c22d
--- /dev/null
+++ b/src/Services/Catalog/Enum/Result/RoundTypeItemResult.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\Catalog\Enum\Result;
+
+use Bitrix24\SDK\Core\Result\AbstractItem;
+
+/**
+ * @property-read int $id
+ * @property-read string $name
+ */
+class RoundTypeItemResult extends AbstractItem
+{
+}
diff --git a/src/Services/Catalog/Enum/Result/RoundTypesResult.php b/src/Services/Catalog/Enum/Result/RoundTypesResult.php
new file mode 100644
index 00000000..8fd96393
--- /dev/null
+++ b/src/Services/Catalog/Enum/Result/RoundTypesResult.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\Catalog\Enum\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class RoundTypesResult extends AbstractResult
+{
+ /**
+ * @return RoundTypeItemResult[]
+ * @throws BaseException
+ */
+ public function getRoundTypes(): array
+ {
+ $items = [];
+ foreach ($this->getCoreResponse()->getResponseData()->getResult()['enum'] as $item) {
+ $items[] = new RoundTypeItemResult($item);
+ }
+
+ return $items;
+ }
+}
diff --git a/src/Services/Catalog/Enum/Result/StoreDocumentTypeItemResult.php b/src/Services/Catalog/Enum/Result/StoreDocumentTypeItemResult.php
new file mode 100644
index 00000000..c2fb8f3f
--- /dev/null
+++ b/src/Services/Catalog/Enum/Result/StoreDocumentTypeItemResult.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\Catalog\Enum\Result;
+
+use Bitrix24\SDK\Core\Result\AbstractItem;
+
+/**
+ * @property-read string $id
+ * @property-read string $name
+ */
+class StoreDocumentTypeItemResult extends AbstractItem
+{
+}
diff --git a/src/Services/Catalog/Enum/Result/StoreDocumentTypesResult.php b/src/Services/Catalog/Enum/Result/StoreDocumentTypesResult.php
new file mode 100644
index 00000000..ec340f24
--- /dev/null
+++ b/src/Services/Catalog/Enum/Result/StoreDocumentTypesResult.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\Catalog\Enum\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class StoreDocumentTypesResult extends AbstractResult
+{
+ /**
+ * @return StoreDocumentTypeItemResult[]
+ * @throws BaseException
+ */
+ public function getStoreDocumentTypes(): array
+ {
+ $items = [];
+ foreach ($this->getCoreResponse()->getResponseData()->getResult()['enum'] as $item) {
+ $items[] = new StoreDocumentTypeItemResult($item);
+ }
+
+ return $items;
+ }
+}
diff --git a/src/Services/Catalog/Enum/Service/CatalogEnum.php b/src/Services/Catalog/Enum/Service/CatalogEnum.php
new file mode 100644
index 00000000..0188986f
--- /dev/null
+++ b/src/Services/Catalog/Enum/Service/CatalogEnum.php
@@ -0,0 +1,61 @@
+
+ *
+ * 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\Catalog\Enum\Service;
+
+use Bitrix24\SDK\Attributes\ApiEndpointMetadata;
+use Bitrix24\SDK\Attributes\ApiServiceMetadata;
+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\Catalog\Enum\Result\RoundTypesResult;
+use Bitrix24\SDK\Services\Catalog\Enum\Result\StoreDocumentTypesResult;
+
+#[ApiServiceMetadata(new Scope(['catalog']))]
+class CatalogEnum extends AbstractService
+{
+ /**
+ * Returns a list of rounding types available in the catalog.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/enum/catalog-enum-get-round-types.html
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.enum.getRoundTypes',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/enum/catalog-enum-get-round-types.html',
+ 'Returns a list of rounding types available in the catalog.'
+ )]
+ public function getRoundTypes(): RoundTypesResult
+ {
+ return new RoundTypesResult($this->core->call('catalog.enum.getRoundTypes'));
+ }
+
+ /**
+ * Returns the types of store accounting documents available for REST.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/enum/catalog-enum-get-store-document-types.html
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.enum.getStoreDocumentTypes',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/enum/catalog-enum-get-store-document-types.html',
+ 'Returns the types of store accounting documents available for REST.'
+ )]
+ public function getStoreDocumentTypes(): StoreDocumentTypesResult
+ {
+ return new StoreDocumentTypesResult($this->core->call('catalog.enum.getStoreDocumentTypes'));
+ }
+}
diff --git a/src/Services/Catalog/Extra/Result/ExtraItemResult.php b/src/Services/Catalog/Extra/Result/ExtraItemResult.php
new file mode 100644
index 00000000..0b87a93d
--- /dev/null
+++ b/src/Services/Catalog/Extra/Result/ExtraItemResult.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\Catalog\Extra\Result;
+
+use Bitrix24\SDK\Core\Result\AbstractItem;
+use MoneyPHP\Percentage\Percentage;
+
+/**
+ * @property-read int $id
+ * @property-read string $name
+ * @property-read Percentage $percentage
+ */
+class ExtraItemResult extends AbstractItem
+{
+ /**
+ * @param int|string $offset
+ */
+ public function __get($offset): mixed
+ {
+ if ($offset === 'percentage') {
+ return new Percentage((string)$this->data[$offset]);
+ }
+
+ return parent::__get($offset);
+ }
+}
diff --git a/src/Services/Catalog/Extra/Result/ExtraResult.php b/src/Services/Catalog/Extra/Result/ExtraResult.php
new file mode 100644
index 00000000..b7f1fa88
--- /dev/null
+++ b/src/Services/Catalog/Extra/Result/ExtraResult.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\Catalog\Extra\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class ExtraResult extends AbstractResult
+{
+ /**
+ * @throws BaseException
+ */
+ public function extra(): ExtraItemResult
+ {
+ return new ExtraItemResult($this->getCoreResponse()->getResponseData()->getResult()['extra']);
+ }
+}
diff --git a/src/Services/Catalog/Extra/Result/ExtrasResult.php b/src/Services/Catalog/Extra/Result/ExtrasResult.php
new file mode 100644
index 00000000..a389a40b
--- /dev/null
+++ b/src/Services/Catalog/Extra/Result/ExtrasResult.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\Catalog\Extra\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class ExtrasResult extends AbstractResult
+{
+ /**
+ * @return ExtraItemResult[]
+ * @throws BaseException
+ */
+ public function getExtras(): array
+ {
+ $items = [];
+ foreach ($this->getCoreResponse()->getResponseData()->getResult()['extras'] as $item) {
+ $items[] = new ExtraItemResult($item);
+ }
+
+ return $items;
+ }
+
+ /**
+ * @throws BaseException
+ */
+ public function getTotal(): int
+ {
+ return $this->getCoreResponse()->getResponseData()->getPagination()->getTotal() ?? 0;
+ }
+}
diff --git a/src/Services/Catalog/Extra/Service/Extra.php b/src/Services/Catalog/Extra/Service/Extra.php
new file mode 100644
index 00000000..be884620
--- /dev/null
+++ b/src/Services/Catalog/Extra/Service/Extra.php
@@ -0,0 +1,88 @@
+
+ *
+ * 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\Catalog\Extra\Service;
+
+use Bitrix24\SDK\Attributes\ApiEndpointMetadata;
+use Bitrix24\SDK\Attributes\ApiServiceMetadata;
+use Bitrix24\SDK\Core\Credentials\Scope;
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Core\Result\FieldsResult;
+use Bitrix24\SDK\Services\AbstractService;
+use Bitrix24\SDK\Services\Catalog\Extra\Result\ExtraResult;
+use Bitrix24\SDK\Services\Catalog\Extra\Result\ExtrasResult;
+
+#[ApiServiceMetadata(new Scope(['catalog']))]
+class Extra extends AbstractService
+{
+ /**
+ * Returns information about a markup by its identifier.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/extra/catalog-extra-get.html
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.extra.get',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/extra/catalog-extra-get.html',
+ 'Returns information about a markup by its identifier.'
+ )]
+ public function get(int $id): ExtraResult
+ {
+ $this->guardPositiveId($id);
+
+ return new ExtraResult($this->core->call('catalog.extra.get', ['id' => $id]));
+ }
+
+ /**
+ * Returns a list of markups matching the given filter.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/extra/catalog-extra-list.html
+ *
+ * @param string[] $select
+ * @param array $filter
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.extra.list',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/extra/catalog-extra-list.html',
+ 'Returns a list of markups matching the given filter.'
+ )]
+ public function list(array $select = [], array $filter = []): ExtrasResult
+ {
+ return new ExtrasResult($this->core->call('catalog.extra.list', [
+ 'select' => $select,
+ 'filter' => $filter,
+ ]));
+ }
+
+ /**
+ * Returns the fields for markup in the catalog module.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/extra/catalog-extra-get-fields.html
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.extra.getFields',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/extra/catalog-extra-get-fields.html',
+ 'Returns the fields for markup in the catalog module.'
+ )]
+ public function fields(): FieldsResult
+ {
+ return new FieldsResult($this->core->call('catalog.extra.getFields'));
+ }
+}
diff --git a/src/Services/Catalog/Measure/Result/AddedMeasureResult.php b/src/Services/Catalog/Measure/Result/AddedMeasureResult.php
new file mode 100644
index 00000000..ab3705b2
--- /dev/null
+++ b/src/Services/Catalog/Measure/Result/AddedMeasureResult.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\Catalog\Measure\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AddedItemResult;
+
+class AddedMeasureResult extends AddedItemResult
+{
+ /**
+ * @throws BaseException
+ */
+ #[\Override]
+ public function getId(): int
+ {
+ return (int)$this->getCoreResponse()->getResponseData()->getResult()['measure']['id'];
+ }
+}
diff --git a/src/Services/Catalog/Measure/Result/DeletedMeasureResult.php b/src/Services/Catalog/Measure/Result/DeletedMeasureResult.php
new file mode 100644
index 00000000..721c55b6
--- /dev/null
+++ b/src/Services/Catalog/Measure/Result/DeletedMeasureResult.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\Catalog\Measure\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\DeletedItemResult;
+
+class DeletedMeasureResult extends DeletedItemResult
+{
+ /**
+ * @throws BaseException
+ */
+ #[\Override]
+ public function isSuccess(): bool
+ {
+ return (bool)$this->getCoreResponse()->getResponseData()->getResult();
+ }
+}
diff --git a/src/Services/Catalog/Measure/Result/MeasureItemResult.php b/src/Services/Catalog/Measure/Result/MeasureItemResult.php
new file mode 100644
index 00000000..75fa111c
--- /dev/null
+++ b/src/Services/Catalog/Measure/Result/MeasureItemResult.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\Catalog\Measure\Result;
+
+use Bitrix24\SDK\Core\Result\AbstractItem;
+
+/**
+ * @property-read int $id
+ * @property-read int $code
+ * @property-read string|null $measureTitle
+ * @property-read bool $isDefault
+ * @property-read string|null $symbol
+ * @property-read string|null $symbolIntl
+ * @property-read string|null $symbolLetterIntl
+ */
+class MeasureItemResult extends AbstractItem
+{
+}
diff --git a/src/Services/Catalog/Measure/Result/MeasureResult.php b/src/Services/Catalog/Measure/Result/MeasureResult.php
new file mode 100644
index 00000000..e3997e1f
--- /dev/null
+++ b/src/Services/Catalog/Measure/Result/MeasureResult.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\Catalog\Measure\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class MeasureResult extends AbstractResult
+{
+ /**
+ * @throws BaseException
+ */
+ public function measure(): MeasureItemResult
+ {
+ return new MeasureItemResult($this->getCoreResponse()->getResponseData()->getResult()['measure']);
+ }
+}
diff --git a/src/Services/Catalog/Measure/Result/MeasuresResult.php b/src/Services/Catalog/Measure/Result/MeasuresResult.php
new file mode 100644
index 00000000..aac9881e
--- /dev/null
+++ b/src/Services/Catalog/Measure/Result/MeasuresResult.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\Catalog\Measure\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\AbstractResult;
+
+class MeasuresResult extends AbstractResult
+{
+ /**
+ * @return MeasureItemResult[]
+ * @throws BaseException
+ */
+ public function getMeasures(): array
+ {
+ $items = [];
+ foreach ($this->getCoreResponse()->getResponseData()->getResult()['measures'] as $item) {
+ $items[] = new MeasureItemResult($item);
+ }
+
+ return $items;
+ }
+
+ /**
+ * @throws BaseException
+ */
+ public function getTotal(): int
+ {
+ return $this->getCoreResponse()->getResponseData()->getPagination()->getTotal() ?? 0;
+ }
+}
diff --git a/src/Services/Catalog/Measure/Result/UpdatedMeasureResult.php b/src/Services/Catalog/Measure/Result/UpdatedMeasureResult.php
new file mode 100644
index 00000000..197aac04
--- /dev/null
+++ b/src/Services/Catalog/Measure/Result/UpdatedMeasureResult.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\Catalog\Measure\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Result\UpdatedItemResult;
+
+class UpdatedMeasureResult extends UpdatedItemResult
+{
+ /**
+ * @throws BaseException
+ */
+ #[\Override]
+ public function isSuccess(): bool
+ {
+ return (bool)$this->getCoreResponse()->getResponseData()->getResult()['measure'];
+ }
+}
diff --git a/src/Services/Catalog/Measure/Service/Measure.php b/src/Services/Catalog/Measure/Service/Measure.php
new file mode 100644
index 00000000..15d0bf78
--- /dev/null
+++ b/src/Services/Catalog/Measure/Service/Measure.php
@@ -0,0 +1,171 @@
+
+ *
+ * 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\Catalog\Measure\Service;
+
+use Bitrix24\SDK\Attributes\ApiEndpointMetadata;
+use Bitrix24\SDK\Attributes\ApiServiceMetadata;
+use Bitrix24\SDK\Core\Credentials\Scope;
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Core\Result\FieldsResult;
+use Bitrix24\SDK\Services\AbstractService;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\AddedMeasureResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\DeletedMeasureResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\MeasureResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\MeasuresResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\UpdatedMeasureResult;
+
+#[ApiServiceMetadata(new Scope(['catalog']))]
+class Measure extends AbstractService
+{
+ /**
+ * Creates a new measurement unit in the catalog.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-add.html
+ *
+ * @param array{
+ * code: int,
+ * measureTitle: string,
+ * isDefault?: string,
+ * symbol?: string,
+ * symbolIntl?: string,
+ * symbolLetterIntl?: string
+ * } $fields
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.measure.add',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-add.html',
+ 'Creates a new measurement unit in the catalog.'
+ )]
+ public function add(array $fields): AddedMeasureResult
+ {
+ return new AddedMeasureResult($this->core->call('catalog.measure.add', ['fields' => $fields]));
+ }
+
+ /**
+ * Updates a measurement unit in the catalog.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-update.html
+ *
+ * @param array{
+ * code?: int,
+ * measureTitle?: string,
+ * isDefault?: string,
+ * symbol?: string,
+ * symbolIntl?: string,
+ * symbolLetterIntl?: string
+ * } $fields
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.measure.update',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-update.html',
+ 'Updates a measurement unit in the catalog.'
+ )]
+ public function update(int $id, array $fields): UpdatedMeasureResult
+ {
+ $this->guardPositiveId($id);
+
+ return new UpdatedMeasureResult($this->core->call('catalog.measure.update', [
+ 'id' => $id,
+ 'fields' => $fields,
+ ]));
+ }
+
+ /**
+ * Returns information about a measurement unit by its identifier.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-get.html
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.measure.get',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-get.html',
+ 'Returns information about a measurement unit by its identifier.'
+ )]
+ public function get(int $id): MeasureResult
+ {
+ $this->guardPositiveId($id);
+
+ return new MeasureResult($this->core->call('catalog.measure.get', ['id' => $id]));
+ }
+
+ /**
+ * Returns a list of measurement units from the catalog.
+ *
+ * Use MeasuresResult::getMeasures() for items and MeasuresResult::getTotal() for the total count.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-list.html
+ *
+ * @param string[] $select
+ * @param array $filter
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.measure.list',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-list.html',
+ 'Returns a list of measurement units from the catalog.'
+ )]
+ public function list(array $select = [], array $filter = []): MeasuresResult
+ {
+ return new MeasuresResult($this->core->call('catalog.measure.list', [
+ 'select' => $select,
+ 'filter' => $filter,
+ ]));
+ }
+
+ /**
+ * Deletes a measurement unit from the catalog.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-delete.html
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.measure.delete',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-delete.html',
+ 'Deletes a measurement unit from the catalog.'
+ )]
+ public function delete(int $id): DeletedMeasureResult
+ {
+ $this->guardPositiveId($id);
+
+ return new DeletedMeasureResult($this->core->call('catalog.measure.delete', ['id' => $id]));
+ }
+
+ /**
+ * Returns the available measurement unit fields in the catalog.
+ *
+ * @link https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-get-fields.html
+ * @throws BaseException
+ * @throws TransportException
+ */
+ #[ApiEndpointMetadata(
+ 'catalog.measure.getFields',
+ 'https://apidocs.bitrix24.com/api-reference/catalog/measure/catalog-measure-get-fields.html',
+ 'Returns the available measurement unit fields in the catalog.'
+ )]
+ public function fields(): FieldsResult
+ {
+ return new FieldsResult($this->core->call('catalog.measure.getFields'));
+ }
+}
diff --git a/tests/CustomAssertions/CustomBitrix24Assertions.php b/tests/CustomAssertions/CustomBitrix24Assertions.php
index dd1d32b7..cae74444 100644
--- a/tests/CustomAssertions/CustomBitrix24Assertions.php
+++ b/tests/CustomAssertions/CustomBitrix24Assertions.php
@@ -48,7 +48,7 @@ protected function assertBitrix24AllResultItemFieldsAnnotated(
}
sort($propsFromAnnotations);
- if (count($fieldCodesFromApi) >= $propsFromAnnotations) {
+ if (count($fieldCodesFromApi) >= count($propsFromAnnotations)) {
$this->assertEquals(
$fieldCodesFromApi,
$propsFromAnnotations,
@@ -211,7 +211,7 @@ protected function assertBitrix24AllResultItemFieldsHasValidTypeAnnotation(
);
break;
}
- if (str_contains(mb_strtoupper($fieldCode), 'RATE')) {
+ if (str_contains(mb_strtoupper($fieldCode), 'RATE') || str_contains(mb_strtoupper($fieldCode), 'PERCENTAGE')) {
$this->assertTrue(
str_contains($propsFromAnnotations[$fieldCode], Percentage::class),
sprintf(
diff --git a/tests/Integration/Services/Catalog/Enum/Result/RoundTypeItemResultAnnotationsTest.php b/tests/Integration/Services/Catalog/Enum/Result/RoundTypeItemResultAnnotationsTest.php
new file mode 100644
index 00000000..ec06ab0c
--- /dev/null
+++ b/tests/Integration/Services/Catalog/Enum/Result/RoundTypeItemResultAnnotationsTest.php
@@ -0,0 +1,66 @@
+
+ *
+ * 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\Catalog\Enum\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\Catalog\Enum\Result\RoundTypeItemResult;
+use Bitrix24\SDK\Services\Catalog\Enum\Service\CatalogEnum;
+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(RoundTypeItemResult::class)]
+class RoundTypeItemResultAnnotationsTest extends TestCase
+{
+ use CustomBitrix24Assertions;
+
+ private CatalogEnum $catalogEnumService;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->catalogEnumService = Fabric::getServiceBuilder()->getCatalogScope()->catalogEnum();
+ }
+
+ /**
+ * @return array
+ * @throws BaseException
+ * @throws TransportException
+ */
+ private function getFirstRoundTypeRawItem(): array
+ {
+ $rawItems = $this->catalogEnumService->getRoundTypes()
+ ->getCoreResponse()->getResponseData()->getResult()['enum'];
+
+ self::assertNotEmpty($rawItems, 'getRoundTypes() must return at least one item to run this test');
+
+ return $rawItems[0];
+ }
+
+ #[Test]
+ #[TestDox('all fields in RoundTypeItemResult are annotated in phpdoc and match with raw api response')]
+ public function testAllSystemFieldsAnnotated(): void
+ {
+ $rawItem = $this->getFirstRoundTypeRawItem();
+
+ $this->assertBitrix24AllResultItemFieldsAnnotated(
+ array_keys($rawItem),
+ RoundTypeItemResult::class
+ );
+ }
+}
diff --git a/tests/Integration/Services/Catalog/Enum/Result/StoreDocumentTypeItemResultAnnotationsTest.php b/tests/Integration/Services/Catalog/Enum/Result/StoreDocumentTypeItemResultAnnotationsTest.php
new file mode 100644
index 00000000..4ad7fa04
--- /dev/null
+++ b/tests/Integration/Services/Catalog/Enum/Result/StoreDocumentTypeItemResultAnnotationsTest.php
@@ -0,0 +1,66 @@
+
+ *
+ * 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\Catalog\Enum\Result;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\Catalog\Enum\Result\StoreDocumentTypeItemResult;
+use Bitrix24\SDK\Services\Catalog\Enum\Service\CatalogEnum;
+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(StoreDocumentTypeItemResult::class)]
+class StoreDocumentTypeItemResultAnnotationsTest extends TestCase
+{
+ use CustomBitrix24Assertions;
+
+ private CatalogEnum $catalogEnumService;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->catalogEnumService = Fabric::getServiceBuilder()->getCatalogScope()->catalogEnum();
+ }
+
+ /**
+ * @return array
+ * @throws BaseException
+ * @throws TransportException
+ */
+ private function getFirstStoreDocumentTypeRawItem(): array
+ {
+ $rawItems = $this->catalogEnumService->getStoreDocumentTypes()
+ ->getCoreResponse()->getResponseData()->getResult()['enum'];
+
+ self::assertNotEmpty($rawItems, 'getStoreDocumentTypes() must return at least one item to run this test');
+
+ return $rawItems[0];
+ }
+
+ #[Test]
+ #[TestDox('all fields in StoreDocumentTypeItemResult are annotated in phpdoc and match with raw api response')]
+ public function testAllSystemFieldsAnnotated(): void
+ {
+ $rawItem = $this->getFirstStoreDocumentTypeRawItem();
+
+ $this->assertBitrix24AllResultItemFieldsAnnotated(
+ array_keys($rawItem),
+ StoreDocumentTypeItemResult::class
+ );
+ }
+}
diff --git a/tests/Integration/Services/Catalog/Enum/Service/CatalogEnumTest.php b/tests/Integration/Services/Catalog/Enum/Service/CatalogEnumTest.php
new file mode 100644
index 00000000..ef4433a6
--- /dev/null
+++ b/tests/Integration/Services/Catalog/Enum/Service/CatalogEnumTest.php
@@ -0,0 +1,60 @@
+
+ *
+ * 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\Catalog\Enum\Service;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\Catalog\Enum\Result\RoundTypeItemResult;
+use Bitrix24\SDK\Services\Catalog\Enum\Result\StoreDocumentTypeItemResult;
+use Bitrix24\SDK\Services\Catalog\Enum\Service\CatalogEnum;
+use Bitrix24\SDK\Tests\Integration\Fabric;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\TestCase;
+
+#[CoversMethod(CatalogEnum::class, 'getRoundTypes')]
+#[CoversMethod(CatalogEnum::class, 'getStoreDocumentTypes')]
+class CatalogEnumTest extends TestCase
+{
+ private CatalogEnum $catalogEnumService;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->catalogEnumService = Fabric::getServiceBuilder()->getCatalogScope()->catalogEnum();
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testGetRoundTypes(): void
+ {
+ $roundTypes = $this->catalogEnumService->getRoundTypes()->getRoundTypes();
+
+ self::assertNotEmpty($roundTypes);
+ self::assertInstanceOf(RoundTypeItemResult::class, $roundTypes[0]);
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testGetStoreDocumentTypes(): void
+ {
+ $storeDocumentTypes = $this->catalogEnumService->getStoreDocumentTypes()->getStoreDocumentTypes();
+
+ self::assertNotEmpty($storeDocumentTypes);
+ self::assertInstanceOf(StoreDocumentTypeItemResult::class, $storeDocumentTypes[0]);
+ }
+}
diff --git a/tests/Integration/Services/Catalog/Extra/Result/ExtraItemResultAnnotationsTest.php b/tests/Integration/Services/Catalog/Extra/Result/ExtraItemResultAnnotationsTest.php
new file mode 100644
index 00000000..6fba0010
--- /dev/null
+++ b/tests/Integration/Services/Catalog/Extra/Result/ExtraItemResultAnnotationsTest.php
@@ -0,0 +1,55 @@
+
+ *
+ * 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\Catalog\Extra\Result;
+
+use Bitrix24\SDK\Services\Catalog\Extra\Result\ExtraItemResult;
+use Bitrix24\SDK\Services\Catalog\Extra\Service\Extra;
+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(ExtraItemResult::class)]
+class ExtraItemResultAnnotationsTest extends TestCase
+{
+ use CustomBitrix24Assertions;
+
+ private Extra $extraService;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->extraService = Fabric::getServiceBuilder()->getCatalogScope()->extra();
+ }
+
+ #[Test]
+ #[TestDox('all fields in ExtraItemResult are annotated in phpdoc and match with raw api response')]
+ public function testAllSystemFieldsAnnotated(): void
+ {
+ $propListFromApi = array_keys($this->extraService->fields()->getFieldsDescription()['extra']);
+
+ $this->assertBitrix24AllResultItemFieldsAnnotated($propListFromApi, ExtraItemResult::class);
+ }
+
+ #[Test]
+ #[TestDox('all fields in ExtraItemResult have valid type casting in magic getters')]
+ public function testAllSystemFieldsHasValidTypeAnnotation(): void
+ {
+ $fields = $this->extraService->fields()->getFieldsDescription()['extra'];
+
+ $this->assertBitrix24AllResultItemFieldsHasValidTypeAnnotation($fields, ExtraItemResult::class);
+ }
+}
diff --git a/tests/Integration/Services/Catalog/Extra/Service/ExtraTest.php b/tests/Integration/Services/Catalog/Extra/Service/ExtraTest.php
new file mode 100644
index 00000000..8c1e5359
--- /dev/null
+++ b/tests/Integration/Services/Catalog/Extra/Service/ExtraTest.php
@@ -0,0 +1,83 @@
+
+ *
+ * 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\Catalog\Extra\Service;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\Catalog\Extra\Result\ExtraItemResult;
+use Bitrix24\SDK\Services\Catalog\Extra\Service\Extra;
+use Bitrix24\SDK\Tests\Integration\Fabric;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\TestCase;
+
+#[CoversMethod(Extra::class, 'get')]
+#[CoversMethod(Extra::class, 'list')]
+#[CoversMethod(Extra::class, 'fields')]
+class ExtraTest extends TestCase
+{
+ private Extra $extraService;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->extraService = Fabric::getServiceBuilder()->getCatalogScope()->extra();
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testGetFields(): void
+ {
+ $fields = $this->extraService->fields()->getFieldsDescription();
+
+ self::assertArrayHasKey('extra', $fields);
+ self::assertArrayHasKey('id', $fields['extra']);
+ self::assertArrayHasKey('name', $fields['extra']);
+ self::assertArrayHasKey('percentage', $fields['extra']);
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testList(): void
+ {
+ $extrasResult = $this->extraService->list();
+
+ self::assertIsArray($extrasResult->getExtras());
+ self::assertGreaterThanOrEqual(0, $extrasResult->getTotal());
+ }
+
+ /**
+ * catalog.extra has no REST method to create a markup — markups are portal-configured.
+ * If the portal has none, this test is skipped as there is no way to fabricate one via REST.
+ *
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testGet(): void
+ {
+ $extras = $this->extraService->list()->getExtras();
+ if ($extras === []) {
+ $this->markTestSkipped('portal has no markups (catalog.extra) configured to test get() against');
+ }
+
+ $firstExtra = $extras[0];
+ $extraItemResult = $this->extraService->get($firstExtra->id)->extra();
+
+ self::assertInstanceOf(ExtraItemResult::class, $extraItemResult);
+ self::assertEquals($firstExtra->id, $extraItemResult->id);
+ }
+}
diff --git a/tests/Integration/Services/Catalog/Measure/Result/MeasureItemResultAnnotationsTest.php b/tests/Integration/Services/Catalog/Measure/Result/MeasureItemResultAnnotationsTest.php
new file mode 100644
index 00000000..5c73e41a
--- /dev/null
+++ b/tests/Integration/Services/Catalog/Measure/Result/MeasureItemResultAnnotationsTest.php
@@ -0,0 +1,55 @@
+
+ *
+ * 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\Catalog\Measure\Result;
+
+use Bitrix24\SDK\Services\Catalog\Measure\Result\MeasureItemResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Service\Measure;
+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(MeasureItemResult::class)]
+class MeasureItemResultAnnotationsTest extends TestCase
+{
+ use CustomBitrix24Assertions;
+
+ private Measure $measureService;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->measureService = Fabric::getServiceBuilder()->getCatalogScope()->measure();
+ }
+
+ #[Test]
+ #[TestDox('all fields in MeasureItemResult are annotated in phpdoc and match with raw api response')]
+ public function testAllSystemFieldsAnnotated(): void
+ {
+ $propListFromApi = array_keys($this->measureService->fields()->getFieldsDescription()['measure']);
+
+ $this->assertBitrix24AllResultItemFieldsAnnotated($propListFromApi, MeasureItemResult::class);
+ }
+
+ #[Test]
+ #[TestDox('all fields in MeasureItemResult have valid type casting in magic getters')]
+ public function testAllSystemFieldsHasValidTypeAnnotation(): void
+ {
+ $fields = $this->measureService->fields()->getFieldsDescription()['measure'];
+
+ $this->assertBitrix24AllResultItemFieldsHasValidTypeAnnotation($fields, MeasureItemResult::class);
+ }
+}
diff --git a/tests/Integration/Services/Catalog/Measure/Service/MeasureTest.php b/tests/Integration/Services/Catalog/Measure/Service/MeasureTest.php
new file mode 100644
index 00000000..9f2d3356
--- /dev/null
+++ b/tests/Integration/Services/Catalog/Measure/Service/MeasureTest.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\Catalog\Measure\Service;
+
+use Bitrix24\SDK\Core\Exceptions\BaseException;
+use Bitrix24\SDK\Core\Exceptions\TransportException;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\MeasureItemResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Service\Measure;
+use Bitrix24\SDK\Tests\Integration\Fabric;
+use Faker;
+use PHPUnit\Framework\Attributes\CoversMethod;
+use PHPUnit\Framework\TestCase;
+
+#[CoversMethod(Measure::class, 'add')]
+#[CoversMethod(Measure::class, 'update')]
+#[CoversMethod(Measure::class, 'get')]
+#[CoversMethod(Measure::class, 'list')]
+#[CoversMethod(Measure::class, 'delete')]
+#[CoversMethod(Measure::class, 'fields')]
+class MeasureTest extends TestCase
+{
+ private Measure $measureService;
+
+ private Faker\Generator $faker;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->measureService = Fabric::getServiceBuilder()->getCatalogScope()->measure();
+ $this->faker = Faker\Factory::create();
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ private function createMeasure(): int
+ {
+ return $this->measureService->add([
+ 'code' => $this->faker->unique()->numberBetween(100000, 999999),
+ 'measureTitle' => 'SDK_TEST_' . $this->faker->uuid(),
+ 'isDefault' => 'N',
+ ])->getId();
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testAdd(): void
+ {
+ $id = $this->createMeasure();
+ self::assertGreaterThan(0, $id);
+
+ $this->measureService->delete($id);
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testGet(): void
+ {
+ $id = $this->createMeasure();
+
+ try {
+ $measureItemResult = $this->measureService->get($id)->measure();
+ self::assertInstanceOf(MeasureItemResult::class, $measureItemResult);
+ self::assertEquals($id, $measureItemResult->id);
+ } finally {
+ $this->measureService->delete($id);
+ }
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testList(): void
+ {
+ $id = $this->createMeasure();
+
+ try {
+ $measuresResult = $this->measureService->list();
+ self::assertGreaterThanOrEqual(1, count($measuresResult->getMeasures()));
+ self::assertGreaterThanOrEqual(1, $measuresResult->getTotal());
+ } finally {
+ $this->measureService->delete($id);
+ }
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testUpdate(): void
+ {
+ $id = $this->createMeasure();
+
+ try {
+ $updatedTitle = 'SDK_TEST_UPDATED_' . $this->faker->uuid();
+ self::assertTrue(
+ $this->measureService->update($id, ['measureTitle' => $updatedTitle])->isSuccess()
+ );
+
+ $updatedMeasure = $this->measureService->get($id)->measure();
+ self::assertEquals($updatedTitle, $updatedMeasure->measureTitle);
+ } finally {
+ $this->measureService->delete($id);
+ }
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testDelete(): void
+ {
+ $id = $this->createMeasure();
+
+ self::assertTrue($this->measureService->delete($id)->isSuccess());
+ }
+
+ /**
+ * @throws BaseException
+ * @throws TransportException
+ */
+ public function testGetFields(): void
+ {
+ $fields = $this->measureService->fields()->getFieldsDescription();
+
+ self::assertArrayHasKey('measure', $fields);
+ self::assertArrayHasKey('id', $fields['measure']);
+ self::assertArrayHasKey('code', $fields['measure']);
+ self::assertArrayHasKey('measureTitle', $fields['measure']);
+ }
+}
diff --git a/tests/Unit/Catalog/Enum/Service/CatalogEnumTest.php b/tests/Unit/Catalog/Enum/Service/CatalogEnumTest.php
new file mode 100644
index 00000000..d45d4ced
--- /dev/null
+++ b/tests/Unit/Catalog/Enum/Service/CatalogEnumTest.php
@@ -0,0 +1,47 @@
+
+ *
+ * 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\Unit\Services\Catalog\Enum\Service;
+
+use Bitrix24\SDK\Services\Catalog\Enum\Result\RoundTypesResult;
+use Bitrix24\SDK\Services\Catalog\Enum\Result\StoreDocumentTypesResult;
+use Bitrix24\SDK\Services\Catalog\Enum\Service\CatalogEnum;
+use Bitrix24\SDK\Tests\Unit\Stubs\NullCore;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\Test;
+use PHPUnit\Framework\TestCase;
+use Psr\Log\NullLogger;
+
+#[CoversClass(CatalogEnum::class)]
+class CatalogEnumTest extends TestCase
+{
+ private CatalogEnum $service;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->service = new CatalogEnum(new NullCore(), new NullLogger());
+ }
+
+ #[Test]
+ public function testGetRoundTypesReturnsRoundTypesResult(): void
+ {
+ $this->assertInstanceOf(RoundTypesResult::class, $this->service->getRoundTypes());
+ }
+
+ #[Test]
+ public function testGetStoreDocumentTypesReturnsStoreDocumentTypesResult(): void
+ {
+ $this->assertInstanceOf(StoreDocumentTypesResult::class, $this->service->getStoreDocumentTypes());
+ }
+}
diff --git a/tests/Unit/Catalog/Extra/Service/ExtraTest.php b/tests/Unit/Catalog/Extra/Service/ExtraTest.php
new file mode 100644
index 00000000..5ad0e619
--- /dev/null
+++ b/tests/Unit/Catalog/Extra/Service/ExtraTest.php
@@ -0,0 +1,62 @@
+
+ *
+ * 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\Unit\Services\Catalog\Extra\Service;
+
+use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException;
+use Bitrix24\SDK\Core\Result\FieldsResult;
+use Bitrix24\SDK\Services\Catalog\Extra\Result\ExtraResult;
+use Bitrix24\SDK\Services\Catalog\Extra\Result\ExtrasResult;
+use Bitrix24\SDK\Services\Catalog\Extra\Service\Extra;
+use Bitrix24\SDK\Tests\Unit\Stubs\NullCore;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\Test;
+use PHPUnit\Framework\TestCase;
+use Psr\Log\NullLogger;
+
+#[CoversClass(Extra::class)]
+class ExtraTest extends TestCase
+{
+ private Extra $service;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->service = new Extra(new NullCore(), new NullLogger());
+ }
+
+ #[Test]
+ public function testGetReturnsExtraResult(): void
+ {
+ $this->assertInstanceOf(ExtraResult::class, $this->service->get(1));
+ }
+
+ #[Test]
+ public function testListReturnsExtrasResult(): void
+ {
+ $this->assertInstanceOf(ExtrasResult::class, $this->service->list());
+ }
+
+ #[Test]
+ public function testFieldsReturnsFieldsResult(): void
+ {
+ $this->assertInstanceOf(FieldsResult::class, $this->service->fields());
+ }
+
+ #[Test]
+ public function testGetThrowsOnNonPositiveId(): void
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->service->get(0);
+ }
+}
diff --git a/tests/Unit/Catalog/Measure/Service/MeasureTest.php b/tests/Unit/Catalog/Measure/Service/MeasureTest.php
new file mode 100644
index 00000000..4b3b5f8f
--- /dev/null
+++ b/tests/Unit/Catalog/Measure/Service/MeasureTest.php
@@ -0,0 +1,103 @@
+
+ *
+ * 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\Unit\Services\Catalog\Measure\Service;
+
+use Bitrix24\SDK\Core\Exceptions\InvalidArgumentException;
+use Bitrix24\SDK\Core\Result\FieldsResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\AddedMeasureResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\DeletedMeasureResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\MeasureResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\MeasuresResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Result\UpdatedMeasureResult;
+use Bitrix24\SDK\Services\Catalog\Measure\Service\Measure;
+use Bitrix24\SDK\Tests\Unit\Stubs\NullCore;
+use PHPUnit\Framework\Attributes\CoversClass;
+use PHPUnit\Framework\Attributes\Test;
+use PHPUnit\Framework\TestCase;
+use Psr\Log\NullLogger;
+
+#[CoversClass(Measure::class)]
+class MeasureTest extends TestCase
+{
+ private Measure $service;
+
+ #[\Override]
+ protected function setUp(): void
+ {
+ $this->service = new Measure(new NullCore(), new NullLogger());
+ }
+
+ #[Test]
+ public function testAddReturnsAddedMeasureResult(): void
+ {
+ $this->assertInstanceOf(
+ AddedMeasureResult::class,
+ $this->service->add(['code' => 715, 'measureTitle' => 'Pair'])
+ );
+ }
+
+ #[Test]
+ public function testUpdateReturnsUpdatedMeasureResult(): void
+ {
+ $this->assertInstanceOf(
+ UpdatedMeasureResult::class,
+ $this->service->update(1, ['measureTitle' => 'Pair'])
+ );
+ }
+
+ #[Test]
+ public function testGetReturnsMeasureResult(): void
+ {
+ $this->assertInstanceOf(MeasureResult::class, $this->service->get(1));
+ }
+
+ #[Test]
+ public function testListReturnsMeasuresResult(): void
+ {
+ $this->assertInstanceOf(MeasuresResult::class, $this->service->list());
+ }
+
+ #[Test]
+ public function testDeleteReturnsDeletedMeasureResult(): void
+ {
+ $this->assertInstanceOf(DeletedMeasureResult::class, $this->service->delete(1));
+ }
+
+ #[Test]
+ public function testFieldsReturnsFieldsResult(): void
+ {
+ $this->assertInstanceOf(FieldsResult::class, $this->service->fields());
+ }
+
+ #[Test]
+ public function testGetThrowsOnNonPositiveId(): void
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->service->get(0);
+ }
+
+ #[Test]
+ public function testUpdateThrowsOnNonPositiveId(): void
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->service->update(0, []);
+ }
+
+ #[Test]
+ public function testDeleteThrowsOnNonPositiveId(): void
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->service->delete(0);
+ }
+}