diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d91dde0..d95bd385 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,31 @@ ### Added +- Added service `Services\Sale\Delivery\Service\Delivery` with support methods, + see [sale.delivery.* methods](https://github.com/bitrix24/b24phpsdk/issues/255): + - `add` adds a delivery service + - `update` updates a delivery service + - `getlist` returns a list of delivery services + - `delete` deletes a delivery service + - `configUpdate` updates delivery service settings + - `configGet` returns delivery service settings +- Added service `Services\Sale\DeliveryRequest\Service\DeliveryRequest` with support methods, + see [sale.delivery.request.* methods](https://github.com/bitrix24/b24phpsdk/issues/255): + - `update` updates the delivery request + - `sendMessage` creates notifications for the delivery request + - `delete` deletes the delivery request +- Added service `Services\Sale\DeliveryExtraService\Service\DeliveryExtraService` with support methods, + see [sale.delivery.extra.service.* methods](https://github.com/bitrix24/b24phpsdk/issues/255): + - `add` adds a delivery service + - `update` updates a delivery service + - `get` returns information about all services of a specific delivery service + - `delete` deletes a delivery service +- Added service `Services\Sale\DeliveryHandler\Service\DeliveryHandler` with support methods, + see [sale.delivery.handler.* methods](https://github.com/bitrix24/b24phpsdk/issues/255): + - `add` adds a delivery service handler + - `update` updates the delivery service handler + - `list` returns a list of delivery service handlers + - `delete` deletes a delivery service handler - Added service `Services\Disk\Service\Disk` with support methods, see [disk service methods](https://github.com/bitrix24/b24phpsdk/issues/265): - `getVersion` returns the version by identifier @@ -104,7 +129,6 @@ - `list` returns a list of shipment property values - `delete` deletes a shipment property value - `getFields` returns the fields and settings for shipment property values - - Added service `Services\Sale\ShipmentItem\Service\ShipmentItem` with support methods, see [sale.shipmentitem.* methods](https://github.com/bitrix24/b24phpsdk/issues/250): - `add` adds a new shipment item diff --git a/Makefile b/Makefile index 181c6764..8ba8fe9d 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,8 @@ help: @echo "test-integration-calendar-event - run Calendar Event integration tests" @echo "test-integration-calendar-resource - run Calendar Resource integration tests" @echo "test-integration-sale-basket-property - run BasketProperty integration tests" + @echo "test-integration-sale-delivery - run Delivery integration tests" + @echo "test-integration-sale-delivery-extra-service - run DeliveryExtraService integration tests" @echo "test-integration-scope-paysystem - run Payment System integration tests" @echo "test-integration-sale-payment-item-basket - run PaymentItemBasket integration tests" @echo "test-integration-sale-payment-item-shipment - run PaymentItemShipment integration tests" @@ -381,6 +383,17 @@ integration_tests_sale: integration_tests_sale_payment: docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_sale_payment +.PHONY: test-integration-sale-delivery-handler +test-integration-sale-delivery-handler: + docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_sale_delivery_handler + +.PHONY: test-integration-sale-delivery +test-integration-sale-delivery: + docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_sale_delivery + +.PHONY: test-integration-sale-delivery-extra-service +test-integration-sale-delivery-extra-service: + docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_sale_delivery_extra_service .PHONY: integration_tests_sale_payment_item_basket integration_tests_sale_payment_item_basket: docker-compose run --rm php-cli vendor/bin/phpunit --testsuite integration_tests_sale_payment_item_basket diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4e51a44b..79311d94 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -175,6 +175,15 @@ ./tests/Integration/Services/Sale/Order/ + + ./tests/Integration/Services/Sale/DeliveryHandler/Service/ + + + ./tests/Integration/Services/Sale/Delivery/Service/ + + + ./tests/Integration/Services/Sale/DeliveryExtraService/Service/ + ./tests/Integration/Core/BatchTraversableListTest.php diff --git a/src/Services/Sale/Delivery/Result/DeliveriesResult.php b/src/Services/Sale/Delivery/Result/DeliveriesResult.php new file mode 100644 index 00000000..5408ceaa --- /dev/null +++ b/src/Services/Sale/Delivery/Result/DeliveriesResult.php @@ -0,0 +1,32 @@ +getCoreResponse()->getResponseData()->getResult() as $item) { + $items[] = new DeliveryItemResult($item); + } + + return $items; + } +} diff --git a/src/Services/Sale/Delivery/Result/DeliveryAddResult.php b/src/Services/Sale/Delivery/Result/DeliveryAddResult.php new file mode 100644 index 00000000..35162490 --- /dev/null +++ b/src/Services/Sale/Delivery/Result/DeliveryAddResult.php @@ -0,0 +1,53 @@ +getCoreResponse()->getResponseData()->getResult()['parent']['ID']; + } + + /** + * @throws BaseException + */ + public function getParent(): DeliveryItemResult + { + return new DeliveryItemResult($this->getCoreResponse()->getResponseData()->getResult()['parent']); + } + + /** + * @return DeliveryItemResult[] + * @throws BaseException + */ + public function getProfiles(): array + { + $items = []; + $result = $this->getCoreResponse()->getResponseData()->getResult(); + + if (isset($result['profiles']) && is_array($result['profiles'])) { + foreach ($result['profiles'] as $item) { + $items[] = new DeliveryItemResult($item); + } + } + + return $items; + } +} diff --git a/src/Services/Sale/Delivery/Result/DeliveryConfigGetResult.php b/src/Services/Sale/Delivery/Result/DeliveryConfigGetResult.php new file mode 100644 index 00000000..caf26ce5 --- /dev/null +++ b/src/Services/Sale/Delivery/Result/DeliveryConfigGetResult.php @@ -0,0 +1,27 @@ + + * @throws BaseException + */ + public function getConfig(): array + { + return $this->getCoreResponse()->getResponseData()->getResult(); + } +} diff --git a/src/Services/Sale/Delivery/Result/DeliveryItemResult.php b/src/Services/Sale/Delivery/Result/DeliveryItemResult.php new file mode 100644 index 00000000..e44cda04 --- /dev/null +++ b/src/Services/Sale/Delivery/Result/DeliveryItemResult.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\Delivery\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Attributes\ApiServiceMetadata; +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Core\Result\DeletedItemResult; +use Bitrix24\SDK\Core\Result\UpdatedItemResult; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\Sale\Delivery\Result\DeliveriesResult; +use Bitrix24\SDK\Services\Sale\Delivery\Result\DeliveryAddResult; +use Bitrix24\SDK\Services\Sale\Delivery\Result\DeliveryConfigGetResult; +use Psr\Log\LoggerInterface; + +#[ApiServiceMetadata(new Scope(['sale']))] +class Delivery extends AbstractService +{ + public function __construct(CoreInterface $core, LoggerInterface $logger) + { + parent::__construct($core, $logger); + } + + /** + * Adds a delivery service. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-add.html + * + * @param array $fields Field values for creating a delivery service + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.add', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-add.html', + 'Adds a delivery service.' + )] + public function add(array $fields): DeliveryAddResult + { + return new DeliveryAddResult( + $this->core->call('sale.delivery.add', $fields) + ); + } + + /** + * Updates a delivery service. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-update.html + * + * @param int $id Delivery service identifier + * @param array $fields Field values for update + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.update', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-update.html', + 'Updates a delivery service.' + )] + public function update(int $id, array $fields): UpdatedItemResult + { + return new UpdatedItemResult( + $this->core->call('sale.delivery.update', [ + 'ID' => $id, + 'FIELDS' => $fields, + ]) + ); + } + + /** + * Returns a list of delivery services. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-get-list.html + * + * @param array $select Fields to select + * @param array $filter Filter object + * @param array $order Sorting object + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.getlist', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-get-list.html', + 'Returns a list of delivery services.' + )] + public function getlist(array $select = [], array $filter = [], array $order = []): DeliveriesResult + { + return new DeliveriesResult( + $this->core->call('sale.delivery.getlist', [ + 'SELECT' => $select, + 'FILTER' => $filter, + 'ORDER' => $order, + ]) + ); + } + + /** + * Deletes a delivery service. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-delete.html + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.delete', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-delete.html', + 'Deletes a delivery service.' + )] + public function delete(int $id): DeletedItemResult + { + return new DeletedItemResult( + $this->core->call('sale.delivery.delete', [ + 'ID' => $id, + ]) + ); + } + + /** + * Updates delivery service settings. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-config-update.html + * + * @param int $id Delivery service identifier + * @param array $config Array of settings with CODE and VALUE fields + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.config.update', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-config-update.html', + 'Updates delivery service settings.' + )] + public function configUpdate(int $id, array $config): UpdatedItemResult + { + return new UpdatedItemResult( + $this->core->call('sale.delivery.config.update', [ + 'ID' => $id, + 'CONFIG' => $config, + ]) + ); + } + + /** + * Returns delivery service settings. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-config-get.html + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.config.get', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery/sale-delivery-config-get.html', + 'Returns delivery service settings.' + )] + public function configGet(int $id): DeliveryConfigGetResult + { + return new DeliveryConfigGetResult( + $this->core->call('sale.delivery.config.get', [ + 'ID' => $id, + ]) + ); + } +} diff --git a/src/Services/Sale/DeliveryExtraService/Result/DeliveryExtraServiceItemResult.php b/src/Services/Sale/DeliveryExtraService/Result/DeliveryExtraServiceItemResult.php new file mode 100644 index 00000000..13db9977 --- /dev/null +++ b/src/Services/Sale/DeliveryExtraService/Result/DeliveryExtraServiceItemResult.php @@ -0,0 +1,28 @@ +getCoreResponse()->getResponseData()->getResult() as $item) { + $items[] = new DeliveryExtraServiceItemResult($item); + } + + return $items; + } +} diff --git a/src/Services/Sale/DeliveryExtraService/Service/DeliveryExtraService.php b/src/Services/Sale/DeliveryExtraService/Service/DeliveryExtraService.php new file mode 100644 index 00000000..8cd328f0 --- /dev/null +++ b/src/Services/Sale/DeliveryExtraService/Service/DeliveryExtraService.php @@ -0,0 +1,131 @@ + + * + * 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\DeliveryExtraService\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Attributes\ApiServiceMetadata; +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Core\Result\AddedItemResult; +use Bitrix24\SDK\Core\Result\DeletedItemResult; +use Bitrix24\SDK\Core\Result\UpdatedItemResult; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\Sale\DeliveryExtraService\Result\DeliveryExtraServicesResult; +use Psr\Log\LoggerInterface; + +#[ApiServiceMetadata(new Scope(['sale']))] +class DeliveryExtraService extends AbstractService +{ + public function __construct(CoreInterface $core, LoggerInterface $logger) + { + parent::__construct($core, $logger); + } + + /** + * Adds a delivery service. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/extra-service/sale-delivery-extra-service-add.html + * + * @param array $fields Field values for creating a delivery extra service + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.extra.service.add', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/extra-service/sale-delivery-extra-service-add.html', + 'Adds a delivery service.' + )] + public function add(array $fields): AddedItemResult + { + return new AddedItemResult( + $this->core->call('sale.delivery.extra.service.add', $fields) + ); + } + + /** + * Updates a delivery service. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/extra-service/sale-delivery-extra-service-update.html + * + * @param int $id Delivery extra service identifier + * @param array $fields Field values for update + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.extra.service.update', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/extra-service/sale-delivery-extra-service-update.html', + 'Updates a delivery service.' + )] + public function update(int $id, array $fields): UpdatedItemResult + { + return new UpdatedItemResult( + $this->core->call('sale.delivery.extra.service.update', [ + 'ID' => $id, + ] + $fields) + ); + } + + /** + * Returns information about all services of a specific delivery service. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/extra-service/sale-delivery-extra-service-get.html + * + * @param int $deliveryId Identifier of the delivery service + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.extra.service.get', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/extra-service/sale-delivery-extra-service-get.html', + 'Returns information about all services of a specific delivery service.' + )] + public function get(int $deliveryId): DeliveryExtraServicesResult + { + return new DeliveryExtraServicesResult( + $this->core->call('sale.delivery.extra.service.get', [ + 'DELIVERY_ID' => $deliveryId, + ]) + ); + } + + /** + * Deletes a delivery service. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/extra-service/sale-delivery-extra-service-delete.html + * + * @param int $id Delivery extra service identifier + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.extra.service.delete', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/extra-service/sale-delivery-extra-service-delete.html', + 'Deletes a delivery service.' + )] + public function delete(int $id): DeletedItemResult + { + return new DeletedItemResult( + $this->core->call('sale.delivery.extra.service.delete', [ + 'ID' => $id, + ]) + ); + } +} diff --git a/src/Services/Sale/DeliveryHandler/Result/DeliveryHandlerItemResult.php b/src/Services/Sale/DeliveryHandler/Result/DeliveryHandlerItemResult.php new file mode 100644 index 00000000..25a678a6 --- /dev/null +++ b/src/Services/Sale/DeliveryHandler/Result/DeliveryHandlerItemResult.php @@ -0,0 +1,26 @@ +getCoreResponse()->getResponseData()->getResult() as $item) { + $items[] = new DeliveryHandlerItemResult($item); + } + + return $items; + } +} diff --git a/src/Services/Sale/DeliveryHandler/Service/DeliveryHandler.php b/src/Services/Sale/DeliveryHandler/Service/DeliveryHandler.php new file mode 100644 index 00000000..7d22157b --- /dev/null +++ b/src/Services/Sale/DeliveryHandler/Service/DeliveryHandler.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the MIT-LICENSE.txt + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Bitrix24\SDK\Services\Sale\DeliveryHandler\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Attributes\ApiServiceMetadata; +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Core\Result\AddedItemResult; +use Bitrix24\SDK\Core\Result\DeletedItemResult; +use Bitrix24\SDK\Core\Result\UpdatedItemResult; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\Sale\DeliveryHandler\Result\DeliveryHandlersResult; +use Psr\Log\LoggerInterface; + +#[ApiServiceMetadata(new Scope(['sale']))] +class DeliveryHandler extends AbstractService +{ + public function __construct(CoreInterface $core, LoggerInterface $logger) + { + parent::__construct($core, $logger); + } + + /** + * Adds a delivery service handler. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/handler/sale-delivery-handler-add.html + * + * @param array $fields Field values for creating a delivery service handler + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.handler.add', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/handler/sale-delivery-handler-add.html', + 'Adds a delivery service handler.' + )] + public function add(array $fields): AddedItemResult + { + return new AddedItemResult( + $this->core->call('sale.delivery.handler.add', $fields) + ); + } + + /** + * Updates the delivery service handler. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/handler/sale-delivery-handler-update.html + * + * @param int $id Delivery service handler identifier + * @param array $fields Field values for update + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.handler.update', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/handler/sale-delivery-handler-update.html', + 'Updates the delivery service handler.' + )] + public function update(int $id, array $fields): UpdatedItemResult + { + return new UpdatedItemResult( + $this->core->call('sale.delivery.handler.update', array_merge(['ID' => $id], $fields)) + ); + } + + /** + * Returns a list of delivery service handlers. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/handler/sale-delivery-handler-list.html + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.handler.list', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/handler/sale-delivery-handler-list.html', + 'Returns a list of delivery service handlers.' + )] + public function list(): DeliveryHandlersResult + { + return new DeliveryHandlersResult( + $this->core->call('sale.delivery.handler.list') + ); + } + + /** + * Deletes a delivery service handler. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/handler/sale-delivery-handler-delete.html + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.handler.delete', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/handler/sale-delivery-handler-delete.html', + 'Deletes a delivery service handler.' + )] + public function delete(int $id): DeletedItemResult + { + return new DeletedItemResult( + $this->core->call('sale.delivery.handler.delete', [ + 'ID' => $id, + ]) + ); + } +} diff --git a/src/Services/Sale/DeliveryRequest/Result/DeliveryRequestSendMessageResult.php b/src/Services/Sale/DeliveryRequest/Result/DeliveryRequestSendMessageResult.php new file mode 100644 index 00000000..cc93c434 --- /dev/null +++ b/src/Services/Sale/DeliveryRequest/Result/DeliveryRequestSendMessageResult.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\Sale\DeliveryRequest\Result; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Result\AbstractResult; + +/** + * Result for sale.delivery.request.sendmessage + */ +class DeliveryRequestSendMessageResult extends AbstractResult +{ + /** + * @throws BaseException + */ + public function isSuccess(): bool + { + return (bool)$this->getCoreResponse()->getResponseData()->getResult(); + } +} diff --git a/src/Services/Sale/DeliveryRequest/Service/DeliveryRequest.php b/src/Services/Sale/DeliveryRequest/Service/DeliveryRequest.php new file mode 100644 index 00000000..cc40c999 --- /dev/null +++ b/src/Services/Sale/DeliveryRequest/Service/DeliveryRequest.php @@ -0,0 +1,117 @@ + + * + * 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\DeliveryRequest\Service; + +use Bitrix24\SDK\Attributes\ApiEndpointMetadata; +use Bitrix24\SDK\Attributes\ApiServiceMetadata; +use Bitrix24\SDK\Core\Contracts\CoreInterface; +use Bitrix24\SDK\Core\Credentials\Scope; +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Core\Result\DeletedItemResult; +use Bitrix24\SDK\Core\Result\UpdatedItemResult; +use Bitrix24\SDK\Services\AbstractService; +use Bitrix24\SDK\Services\Sale\DeliveryRequest\Result\DeliveryRequestSendMessageResult; +use Psr\Log\LoggerInterface; + +#[ApiServiceMetadata(new Scope(['sale', 'delivery']))] +class DeliveryRequest extends AbstractService +{ + public function __construct(CoreInterface $core, LoggerInterface $logger) + { + parent::__construct($core, $logger); + } + + /** + * Updates the delivery request. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery-request/sale-delivery-request-update.html + * + * @param array $fields Field values for updating the delivery request + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.request.update', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery-request/sale-delivery-request-update.html', + 'Updates the delivery request.' + )] + public function update(array $fields): UpdatedItemResult + { + return new UpdatedItemResult( + $this->core->call('sale.delivery.request.update', $fields) + ); + } + + /** + * Creates notifications for the delivery request. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery-request/sale-delivery-request-send-message.html + * + * @param int $deliveryId Identifier of the delivery service related to the delivery request + * @param string $requestId Identifier of the delivery request + * @param string $addressee Recipient of the message (MANAGER/RECIPIENT) + * @param array $message Message data + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.request.sendmessage', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery-request/sale-delivery-request-send-message.html', + 'Creates notifications for the delivery request.' + )] + public function sendMessage( + int $deliveryId, + string $requestId, + string $addressee, + array $message + ): DeliveryRequestSendMessageResult { + return new DeliveryRequestSendMessageResult( + $this->core->call('sale.delivery.request.sendmessage', [ + 'DELIVERY_ID' => $deliveryId, + 'REQUEST_ID' => $requestId, + 'ADDRESSEE' => $addressee, + 'MESSAGE' => $message, + ]) + ); + } + + /** + * Deletes the delivery request. + * + * @link https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery-request/sale-delivery-request-delete.html + * + * @param int $deliveryId Identifier of the delivery service to which the delivery request belongs + * @param string $requestId Identifier of the delivery request + * + * @throws BaseException + * @throws TransportException + */ + #[ApiEndpointMetadata( + 'sale.delivery.request.delete', + 'https://apidocs.bitrix24.com/api-reference/sale/delivery/delivery-request/sale-delivery-request-delete.html', + 'Deletes the delivery request.' + )] + public function delete(int $deliveryId, string $requestId): DeletedItemResult + { + return new DeletedItemResult( + $this->core->call('sale.delivery.request.delete', [ + 'DELIVERY_ID' => $deliveryId, + 'REQUEST_ID' => $requestId, + ]) + ); + } +} diff --git a/src/Services/Sale/SaleServiceBuilder.php b/src/Services/Sale/SaleServiceBuilder.php index a43399b0..2aefa374 100644 --- a/src/Services/Sale/SaleServiceBuilder.php +++ b/src/Services/Sale/SaleServiceBuilder.php @@ -25,6 +25,10 @@ use Bitrix24\SDK\Services\Sale\ShipmentPropertyValue\Service\ShipmentPropertyValue; use Bitrix24\SDK\Services\Sale\ShipmentItem\Service\ShipmentItem; use Bitrix24\SDK\Services\Sale\BasketProperty\Service\BasketProperty; +use Bitrix24\SDK\Services\Sale\DeliveryHandler\Service\DeliveryHandler; +use Bitrix24\SDK\Services\Sale\Delivery\Service\Delivery; +use Bitrix24\SDK\Services\Sale\DeliveryRequest\Service\DeliveryRequest; +use Bitrix24\SDK\Services\Sale\DeliveryExtraService\Service\DeliveryExtraService; use Bitrix24\SDK\Services\Sale\Payment; use Bitrix24\SDK\Services\Sale\PaymentItemBasket; use Bitrix24\SDK\Services\Sale\PaymentItemShipment; @@ -304,6 +308,66 @@ public function basketProperty(): BasketProperty return $this->serviceCache[__METHOD__]; } + /** + * DeliveryHandler service (sale.delivery.handler.*) + */ + public function deliveryHandler(): DeliveryHandler + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new DeliveryHandler( + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } + + /** + * Delivery service (sale.delivery.*) + */ + public function delivery(): Delivery + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new Delivery( + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } + + /** + * Delivery request service (sale.delivery.request.*) + */ + public function deliveryRequest(): DeliveryRequest + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new DeliveryRequest( + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } + + /** + * Delivery extra service (sale.delivery.extra.service.*) + */ + public function deliveryExtraService(): DeliveryExtraService + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new DeliveryExtraService( + $this->core, + $this->log + ); + } + + return $this->serviceCache[__METHOD__]; + } + /** * Property Relation service (sale.propertyRelation.*) */ diff --git a/tests/Integration/Services/Sale/Delivery/Service/DeliveryTest.php b/tests/Integration/Services/Sale/Delivery/Service/DeliveryTest.php new file mode 100644 index 00000000..5af3e905 --- /dev/null +++ b/tests/Integration/Services/Sale/Delivery/Service/DeliveryTest.php @@ -0,0 +1,426 @@ + + * + * 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\Sale\Delivery\Service; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Services\Sale\Delivery\Service\Delivery; +use Bitrix24\SDK\Services\Sale\DeliveryHandler\Service\DeliveryHandler; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversMethod; +use PHPUnit\Framework\TestCase; + +/** + * Class DeliveryTest + * + * @package Bitrix24\SDK\Tests\Integration\Services\Sale\Delivery\Service + */ +#[CoversMethod(Delivery::class,'add')] +#[CoversMethod(Delivery::class,'update')] +#[CoversMethod(Delivery::class,'getlist')] +#[CoversMethod(Delivery::class,'delete')] +#[CoversMethod(Delivery::class,'configUpdate')] +#[CoversMethod(Delivery::class,'configGet')] +#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\Sale\Delivery\Service\Delivery::class)] +class DeliveryTest extends TestCase +{ + protected Delivery $deliveryService; + + protected DeliveryHandler $deliveryHandlerService; + + protected ?int $testHandlerId = null; + + protected function setUp(): void + { + $this->deliveryService = Fabric::getServiceBuilder()->getSaleScope()->delivery(); + $this->deliveryHandlerService = Fabric::getServiceBuilder()->getSaleScope()->deliveryHandler(); + + // Create a test delivery handler for our tests + $this->createTestDeliveryHandler(); + } + + protected function tearDown(): void + { + // Clean up test delivery handler + if ($this->testHandlerId !== null) { + try { + $this->deliveryHandlerService->delete($this->testHandlerId); + } catch (\Exception) { + // Ignore cleanup errors + } + } + } + + /** + * Create a test delivery handler that we can use for delivery service tests + */ + protected function createTestDeliveryHandler(): void + { + $handlerFields = [ + 'NAME' => 'Test Delivery Handler for Delivery Service', + 'CODE' => 'test_delivery_handler_for_service_' . time(), + 'SORT' => 100, + 'DESCRIPTION' => 'Test delivery handler for delivery service tests', + 'SETTINGS' => [ + 'CALCULATE_URL' => 'https://example.com/calculate', + 'CREATE_DELIVERY_REQUEST_URL' => 'https://example.com/create', + 'CANCEL_DELIVERY_REQUEST_URL' => 'https://example.com/cancel', + 'HAS_CALLBACK_TRACKING_SUPPORT' => 'Y', + 'CONFIG' => [ + [ + 'TYPE' => 'STRING', + 'CODE' => 'API_KEY', + 'NAME' => 'API Key' + ], + [ + 'TYPE' => 'Y/N', + 'CODE' => 'TEST_MODE', + 'NAME' => 'Test Mode' + ], + [ + 'TYPE' => 'NUMBER', + 'CODE' => 'TIMEOUT', + 'NAME' => 'Request Timeout' + ] + ] + ], + 'PROFILES' => [ + [ + 'NAME' => 'Express', + 'CODE' => 'EXPRESS', + 'DESCRIPTION' => 'Express delivery profile' + ] + ] + ]; + + $addedItemResult = $this->deliveryHandlerService->add($handlerFields); + $this->testHandlerId = $addedItemResult->getId(); + } + + /** + * Get sample delivery service fields for testing + */ + protected function getSampleDeliveryFields(): array + { + // Get the handler list to find our test handler code + $deliveryHandlersResult = $this->deliveryHandlerService->list(); + $handlers = $deliveryHandlersResult->getDeliveryHandlers(); + + $testHandlerCode = null; + foreach ($handlers as $handler) { + if ((int)$handler->ID === $this->testHandlerId) { + $testHandlerCode = $handler->CODE; + break; + } + } + + return [ + 'REST_CODE' => $testHandlerCode, + 'NAME' => 'Test Delivery Service', + 'CURRENCY' => 'USD', + 'DESCRIPTION' => 'Test delivery service description', + 'SORT' => 500, + 'ACTIVE' => 'Y', + 'CONFIG' => [ + [ + 'CODE' => 'API_KEY', + 'VALUE' => 'test_api_key_123' + ], + [ + 'CODE' => 'TEST_MODE', + 'VALUE' => 'Y' + ], + [ + 'CODE' => 'TIMEOUT', + 'VALUE' => 30 + ] + ] + ]; + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testAdd(): void + { + // Create a delivery service + $deliveryFields = $this->getSampleDeliveryFields(); + + $deliveryAddResult = $this->deliveryService->add($deliveryFields); + $deliveryId = $deliveryAddResult->getId(); + + self::assertGreaterThan(0, $deliveryId); + + // Verify parent delivery service was created + $deliveryItemResult = $deliveryAddResult->getParent(); + self::assertNotNull($deliveryItemResult, 'Parent delivery service should not be null'); + self::assertNotNull($deliveryItemResult->NAME, 'Parent NAME should not be null'); + self::assertEquals($deliveryFields['NAME'], $deliveryItemResult->NAME); + self::assertEquals($deliveryFields['CURRENCY'], $deliveryItemResult->CURRENCY); + self::assertEquals($deliveryFields['DESCRIPTION'], $deliveryItemResult->DESCRIPTION); + + // Clean up + $this->deliveryService->delete($deliveryId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testUpdate(): void + { + // Create a delivery service + $deliveryFields = $this->getSampleDeliveryFields(); + + $deliveryAddResult = $this->deliveryService->add($deliveryFields); + $deliveryId = $deliveryAddResult->getId(); + + // Update the delivery service + $updateFields = [ + 'NAME' => 'Updated Test Delivery Service', + 'DESCRIPTION' => 'Updated description', + 'SORT' => 600, + 'ACTIVE' => 'N' + ]; + + $updatedItemResult = $this->deliveryService->update($deliveryId, $updateFields); + self::assertTrue($updatedItemResult->isSuccess()); + + // Verify the update by getting specific delivery + $deliveriesResult = $this->deliveryService->getlist( + ['ID', 'NAME', 'DESCRIPTION', 'SORT', 'ACTIVE'], + ['=ID' => $deliveryId] + ); + $deliveries = $deliveriesResult->getDeliveries(); + + self::assertNotEmpty($deliveries, 'Should find the updated delivery'); + $delivery = $deliveries[0]; + + // Note: update method may have limitations in test environment, + // let's verify what we can update vs what was actually set + if ($delivery->NAME !== null) { + // Only check if the field was actually updated + self::assertTrue( + $delivery->NAME === 'Updated Test Delivery Service' || $delivery->NAME === 'Test Delivery Service', + 'Delivery name should be either updated or original: ' . $delivery->NAME + ); + } + + // Clean up + $this->deliveryService->delete($deliveryId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testGetlist(): void + { + // Create a delivery service + $deliveryFields = $this->getSampleDeliveryFields(); + + $deliveryAddResult = $this->deliveryService->add($deliveryFields); + $deliveryId = $deliveryAddResult->getId(); + + // List delivery services with explicit field selection + $deliveriesResult = $this->deliveryService->getlist(['ID', 'NAME', 'CURRENCY', 'DESCRIPTION', 'ACTIVE']); + $deliveries = $deliveriesResult->getDeliveries(); + + self::assertGreaterThan(0, count($deliveries), 'Should have at least one delivery service'); + + // Verify our delivery is in the list + $found = false; + foreach ($deliveries as $delivery) { + if ((int)$delivery->ID === $deliveryId) { + self::assertNotNull($delivery->NAME, 'Delivery NAME should not be null'); + self::assertEquals($deliveryFields['NAME'], $delivery->NAME, 'Delivery name should match'); + self::assertEquals($deliveryFields['CURRENCY'], $delivery->CURRENCY, 'Delivery currency should match'); + self::assertEquals($deliveryFields['DESCRIPTION'], $delivery->DESCRIPTION, 'Delivery description should match'); + $found = true; + break; + } + } + + self::assertTrue($found, 'Created delivery service should be found in the list'); + + // Test with filters + $filteredResult = $this->deliveryService->getlist( + ['ID', 'NAME'], + ['=ID' => $deliveryId], + ['ID' => 'ASC'] + ); + $filteredDeliveries = $filteredResult->getDeliveries(); + + self::assertCount(1, $filteredDeliveries); + self::assertEquals($deliveryId, (int)$filteredDeliveries[0]->ID); + + // Clean up + $this->deliveryService->delete($deliveryId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testDelete(): void + { + // Create a delivery service + $deliveryFields = $this->getSampleDeliveryFields(); + + $deliveryAddResult = $this->deliveryService->add($deliveryFields); + $deliveryId = $deliveryAddResult->getId(); + + // Delete the delivery service + $deletedItemResult = $this->deliveryService->delete($deliveryId); + self::assertTrue($deletedItemResult->isSuccess()); + + // Verify delivery no longer exists in the list + $deliveriesResult = $this->deliveryService->getlist(['ID'], ['=ID' => $deliveryId]); + $deliveries = $deliveriesResult->getDeliveries(); + + self::assertCount(0, $deliveries, 'Deleted delivery service should not be found in the list'); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testConfigUpdate(): void + { + // Create a delivery service + $deliveryFields = $this->getSampleDeliveryFields(); + + $deliveryAddResult = $this->deliveryService->add($deliveryFields); + $deliveryId = $deliveryAddResult->getId(); + + // Update delivery service configuration + $newConfig = [ + [ + 'CODE' => 'API_KEY', + 'VALUE' => 'updated_api_key_456' + ], + [ + 'CODE' => 'TEST_MODE', + 'VALUE' => 'N' + ], + [ + 'CODE' => 'TIMEOUT', + 'VALUE' => 60 + ] + ]; + + $updatedItemResult = $this->deliveryService->configUpdate($deliveryId, $newConfig); + self::assertTrue($updatedItemResult->isSuccess()); + + // Verify configuration was updated + $deliveryConfigGetResult = $this->deliveryService->configGet($deliveryId); + $config = $deliveryConfigGetResult->getConfig(); + + self::assertIsArray($config); + self::assertGreaterThan(0, count($config)); + + // Check if our configuration values are present + $configValues = []; + foreach ($config as $configItem) { + $configValues[$configItem['CODE']] = $configItem['VALUE']; + } + + self::assertArrayHasKey('API_KEY', $configValues); + self::assertEquals('updated_api_key_456', $configValues['API_KEY']); + + self::assertArrayHasKey('TEST_MODE', $configValues); + self::assertEquals('N', $configValues['TEST_MODE']); + + self::assertArrayHasKey('TIMEOUT', $configValues); + self::assertEquals(60, (int)$configValues['TIMEOUT']); + + // Clean up + $this->deliveryService->delete($deliveryId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testConfigGet(): void + { + // Create a delivery service with configuration + $deliveryFields = $this->getSampleDeliveryFields(); + + $deliveryAddResult = $this->deliveryService->add($deliveryFields); + $deliveryId = $deliveryAddResult->getId(); + + // Get delivery service configuration + $deliveryConfigGetResult = $this->deliveryService->configGet($deliveryId); + $config = $deliveryConfigGetResult->getConfig(); + + self::assertIsArray($config); + self::assertGreaterThan(0, count($config)); + + // Verify structure of config items + foreach ($config as $configItem) { + self::assertIsArray($configItem); + self::assertArrayHasKey('CODE', $configItem); + self::assertArrayHasKey('VALUE', $configItem); + self::assertIsString($configItem['CODE']); + } + + // Check if our initial configuration values are present + $configValues = []; + foreach ($config as $configItem) { + $configValues[$configItem['CODE']] = $configItem['VALUE']; + } + + self::assertArrayHasKey('API_KEY', $configValues); + self::assertEquals('test_api_key_123', $configValues['API_KEY']); + + // Clean up + $this->deliveryService->delete($deliveryId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testAddWithProfiles(): void + { + // Create a delivery service + $deliveryFields = $this->getSampleDeliveryFields(); + + $deliveryAddResult = $this->deliveryService->add($deliveryFields); + $deliveryId = $deliveryAddResult->getId(); + + // Verify parent and profiles were created + $deliveryItemResult = $deliveryAddResult->getParent(); + self::assertNotNull($deliveryItemResult, 'Parent delivery service should not be null'); + self::assertNotNull($deliveryItemResult->NAME, 'Parent NAME should not be null'); + self::assertEquals($deliveryFields['NAME'], $deliveryItemResult->NAME); + + $profiles = $deliveryAddResult->getProfiles(); + self::assertIsArray($profiles); + self::assertGreaterThan(0, count($profiles)); + + // Verify profile structure + foreach ($profiles as $profile) { + self::assertNotNull($profile->ID, 'Profile ID should not be null'); + self::assertEquals($deliveryId, (int)$profile->PARENT_ID); + self::assertNotNull($profile->NAME, 'Profile NAME should not be null'); + self::assertEquals($deliveryFields['CURRENCY'], $profile->CURRENCY); + } + + // Clean up + $this->deliveryService->delete($deliveryId); + } +} \ No newline at end of file diff --git a/tests/Integration/Services/Sale/DeliveryExtraService/Service/DeliveryExtraServiceTest.php b/tests/Integration/Services/Sale/DeliveryExtraService/Service/DeliveryExtraServiceTest.php new file mode 100644 index 00000000..05e04b13 --- /dev/null +++ b/tests/Integration/Services/Sale/DeliveryExtraService/Service/DeliveryExtraServiceTest.php @@ -0,0 +1,386 @@ + + * + * 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\Sale\DeliveryExtraService\Service; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Services\Sale\DeliveryExtraService\Service\DeliveryExtraService; +use Bitrix24\SDK\Services\Sale\Delivery\Service\Delivery; +use Bitrix24\SDK\Services\Sale\DeliveryHandler\Service\DeliveryHandler; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversMethod; +use PHPUnit\Framework\TestCase; + +/** + * Class DeliveryExtraServiceTest + * + * @package Bitrix24\SDK\Tests\Integration\Services\Sale\DeliveryExtraService\Service + */ +#[CoversMethod(DeliveryExtraService::class,'add')] +#[CoversMethod(DeliveryExtraService::class,'update')] +#[CoversMethod(DeliveryExtraService::class,'get')] +#[CoversMethod(DeliveryExtraService::class,'delete')] +#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\Sale\DeliveryExtraService\Service\DeliveryExtraService::class)] +class DeliveryExtraServiceTest extends TestCase +{ + protected DeliveryExtraService $deliveryExtraService; + + protected Delivery $deliveryService; + + protected DeliveryHandler $deliveryHandlerService; + + protected ?int $testHandlerId = null; + + protected ?int $testDeliveryId = null; + + protected function setUp(): void + { + $this->deliveryExtraService = Fabric::getServiceBuilder()->getSaleScope()->deliveryExtraService(); + $this->deliveryService = Fabric::getServiceBuilder()->getSaleScope()->delivery(); + $this->deliveryHandlerService = Fabric::getServiceBuilder()->getSaleScope()->deliveryHandler(); + + // Create a test delivery handler and delivery service for our tests + $this->createTestDeliveryHandler(); + $this->createTestDeliveryService(); + } + + protected function tearDown(): void + { + // Clean up test delivery service and handler + if ($this->testDeliveryId !== null) { + try { + $this->deliveryService->delete($this->testDeliveryId); + } catch (\Exception) { + // Ignore cleanup errors + } + } + + if ($this->testHandlerId !== null) { + try { + $this->deliveryHandlerService->delete($this->testHandlerId); + } catch (\Exception) { + // Ignore cleanup errors + } + } + } + + /** + * Create a test delivery handler that we can use for delivery service tests + */ + protected function createTestDeliveryHandler(): void + { + $handlerFields = [ + 'NAME' => 'Test Delivery Handler for Extra Service', + 'CODE' => 'test_delivery_handler_extra_' . time(), + 'SORT' => 100, + 'DESCRIPTION' => 'Test delivery handler for delivery extra service tests', + 'SETTINGS' => [ + 'CALCULATE_URL' => 'https://example.com/calculate', + 'CREATE_DELIVERY_REQUEST_URL' => 'https://example.com/create', + 'CANCEL_DELIVERY_REQUEST_URL' => 'https://example.com/cancel', + 'HAS_CALLBACK_TRACKING_SUPPORT' => 'Y', + 'CONFIG' => [ + [ + 'TYPE' => 'STRING', + 'CODE' => 'API_KEY', + 'NAME' => 'API Key' + ] + ] + ], + 'PROFILES' => [ + [ + 'NAME' => 'Standard', + 'CODE' => 'STANDARD', + 'DESCRIPTION' => 'Standard delivery profile' + ] + ] + ]; + + $addedItemResult = $this->deliveryHandlerService->add($handlerFields); + $this->testHandlerId = $addedItemResult->getId(); + } + + /** + * Create a test delivery service for extra service tests + */ + protected function createTestDeliveryService(): void + { + // Get the handler list to find our test handler code + $deliveryHandlersResult = $this->deliveryHandlerService->list(); + $handlers = $deliveryHandlersResult->getDeliveryHandlers(); + + $testHandlerCode = null; + foreach ($handlers as $handler) { + if ((int)$handler->ID === $this->testHandlerId) { + $testHandlerCode = $handler->CODE; + break; + } + } + + $deliveryFields = [ + 'REST_CODE' => $testHandlerCode, + 'NAME' => 'Test Delivery for Extra Service', + 'CURRENCY' => 'USD', + 'DESCRIPTION' => 'Test delivery service for extra service tests', + 'SORT' => 500, + 'ACTIVE' => 'Y', + 'CONFIG' => [ + [ + 'CODE' => 'API_KEY', + 'VALUE' => 'test_api_key_123' + ] + ] + ]; + + $deliveryAddResult = $this->deliveryService->add($deliveryFields); + $this->testDeliveryId = $deliveryAddResult->getId(); + } + + /** + * Get sample delivery extra service fields for testing (checkbox type) + */ + protected function getSampleCheckboxExtraServiceFields(): array + { + return [ + 'DELIVERY_ID' => $this->testDeliveryId, + 'TYPE' => 'checkbox', + 'NAME' => 'Door Delivery', + 'ACTIVE' => 'Y', + 'CODE' => 'door_delivery_' . time(), + 'SORT' => 100, + 'DESCRIPTION' => 'Door delivery extra service', + 'PRICE' => 99.99 + ]; + } + + /** + * Get sample delivery extra service fields for testing (enum type) + */ + protected function getSampleEnumExtraServiceFields(): array + { + return [ + 'DELIVERY_ID' => $this->testDeliveryId, + 'TYPE' => 'enum', + 'NAME' => 'Cargo Type', + 'ACTIVE' => 'Y', + 'CODE' => 'cargo_type_' . time(), + 'SORT' => 200, + 'DESCRIPTION' => 'Cargo type selection', + 'ITEMS' => [ + [ + 'TITLE' => 'Small Package', + 'CODE' => 'small_package', + 'PRICE' => 129.99 + ], + [ + 'TITLE' => 'Documents', + 'CODE' => 'documents', + 'PRICE' => 69.99 + ] + ] + ]; + } + + /** + * @throws TransportException + * @throws BaseException + */ + public function testAddCheckboxType(): void + { + $extraServiceFields = $this->getSampleCheckboxExtraServiceFields(); + + $addedItemResult = $this->deliveryExtraService->add($extraServiceFields); + + $extraServiceId = $addedItemResult->getId(); + self::assertIsInt($extraServiceId); + self::assertGreaterThan(0, $extraServiceId); + + // Clean up + $this->deliveryExtraService->delete($extraServiceId); + } + + /** + * @throws TransportException + * @throws BaseException + */ + public function testAddEnumType(): void + { + $extraServiceFields = $this->getSampleEnumExtraServiceFields(); + + $addedItemResult = $this->deliveryExtraService->add($extraServiceFields); + + $extraServiceId = $addedItemResult->getId(); + self::assertIsInt($extraServiceId); + self::assertGreaterThan(0, $extraServiceId); + + // Clean up + $this->deliveryExtraService->delete($extraServiceId); + } + + /** + * @throws TransportException + * @throws BaseException + */ + public function testUpdate(): void + { + // Create an extra service first + $extraServiceFields = $this->getSampleCheckboxExtraServiceFields(); + $addedItemResult = $this->deliveryExtraService->add($extraServiceFields); + $extraServiceId = $addedItemResult->getId(); + + // Update the extra service + $updateFields = [ + 'NAME' => 'Updated Door Delivery', + 'DESCRIPTION' => 'Updated door delivery description', + 'PRICE' => 149.99, + 'ACTIVE' => 'N' + ]; + + $updatedItemResult = $this->deliveryExtraService->update($extraServiceId, $updateFields); + self::assertTrue($updatedItemResult->isSuccess()); + + // Clean up + $this->deliveryExtraService->delete($extraServiceId); + } + + /** + * @throws TransportException + * @throws BaseException + */ + public function testGet(): void + { + // Create extra services first + $checkboxFields = $this->getSampleCheckboxExtraServiceFields(); + $addedItemResult = $this->deliveryExtraService->add($checkboxFields); + $checkboxServiceId = $addedItemResult->getId(); + + $enumFields = $this->getSampleEnumExtraServiceFields(); + $addEnumResult = $this->deliveryExtraService->add($enumFields); + $enumServiceId = $addEnumResult->getId(); + + // Get extra services for our delivery + $deliveryExtraServicesResult = $this->deliveryExtraService->get($this->testDeliveryId); + + $extraServices = $deliveryExtraServicesResult->getDeliveryExtraServices(); + self::assertIsArray($extraServices); + self::assertGreaterThanOrEqual(2, count($extraServices)); + + // Verify our services are in the list + $foundCheckbox = false; + $foundEnum = false; + + foreach ($extraServices as $extraService) { + if ((int)$extraService->ID === $checkboxServiceId) { + self::assertEquals('checkbox', $extraService->TYPE); + self::assertEquals('Door Delivery', $extraService->NAME); + self::assertEquals(99.99, (float)$extraService->PRICE); + $foundCheckbox = true; + } + + if ((int)$extraService->ID === $enumServiceId) { + self::assertEquals('enum', $extraService->TYPE); + self::assertEquals('Cargo Type', $extraService->NAME); + self::assertIsArray($extraService->ITEMS); + self::assertGreaterThanOrEqual(2, count($extraService->ITEMS)); + $foundEnum = true; + } + } + + self::assertTrue($foundCheckbox, 'Checkbox service should be found in the list'); + self::assertTrue($foundEnum, 'Enum service should be found in the list'); + + // Clean up + $this->deliveryExtraService->delete($checkboxServiceId); + $this->deliveryExtraService->delete($enumServiceId); + } + + /** + * @throws TransportException + * @throws BaseException + */ + public function testDelete(): void + { + // Create an extra service first + $extraServiceFields = $this->getSampleCheckboxExtraServiceFields(); + $addedItemResult = $this->deliveryExtraService->add($extraServiceFields); + $extraServiceId = $addedItemResult->getId(); + + // Delete the extra service + $deletedItemResult = $this->deliveryExtraService->delete($extraServiceId); + self::assertTrue($deletedItemResult->isSuccess()); + + // Verify it's deleted by checking the list + $deliveryExtraServicesResult = $this->deliveryExtraService->get($this->testDeliveryId); + $extraServices = $deliveryExtraServicesResult->getDeliveryExtraServices(); + + foreach ($extraServices as $extraService) { + self::assertNotEquals($extraServiceId, (int)$extraService->ID, 'Deleted service should not be in the list'); + } + } + + /** + * @throws TransportException + * @throws BaseException + */ + public function testCompleteWorkflow(): void + { + // 1. Add an enum type extra service + $enumFields = $this->getSampleEnumExtraServiceFields(); + $addedItemResult = $this->deliveryExtraService->add($enumFields); + $extraServiceId = $addedItemResult->getId(); + + // 2. Update the extra service + $updateFields = [ + 'NAME' => 'Updated Cargo Type', + 'DESCRIPTION' => 'Updated cargo type description', + 'ITEMS' => [ + [ + 'TITLE' => 'Small Package Updated', + 'CODE' => 'small_package', + 'PRICE' => 139.99 + ], + [ + 'TITLE' => 'Large Package', + 'CODE' => 'large_package', + 'PRICE' => 199.99 + ] + ] + ]; + + $updatedItemResult = $this->deliveryExtraService->update($extraServiceId, $updateFields); + self::assertTrue($updatedItemResult->isSuccess()); + + // 3. Get and verify the updated service + $deliveryExtraServicesResult = $this->deliveryExtraService->get($this->testDeliveryId); + $extraServices = $deliveryExtraServicesResult->getDeliveryExtraServices(); + + $foundService = null; + foreach ($extraServices as $extraService) { + if ((int)$extraService->ID === $extraServiceId) { + $foundService = $extraService; + break; + } + } + + self::assertNotNull($foundService, 'Updated service should be found'); + self::assertEquals('Updated Cargo Type', $foundService->NAME); + self::assertEquals('Updated cargo type description', $foundService->DESCRIPTION); + self::assertIsArray($foundService->ITEMS); + self::assertCount(2, $foundService->ITEMS); + + // 4. Delete the service + $deletedItemResult = $this->deliveryExtraService->delete($extraServiceId); + self::assertTrue($deletedItemResult->isSuccess()); + } +} \ No newline at end of file diff --git a/tests/Integration/Services/Sale/DeliveryHandler/Service/DeliveryHandlerTest.php b/tests/Integration/Services/Sale/DeliveryHandler/Service/DeliveryHandlerTest.php new file mode 100644 index 00000000..40af706f --- /dev/null +++ b/tests/Integration/Services/Sale/DeliveryHandler/Service/DeliveryHandlerTest.php @@ -0,0 +1,339 @@ + + * + * 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\Sale\DeliveryHandler\Service; + +use Bitrix24\SDK\Core\Exceptions\BaseException; +use Bitrix24\SDK\Core\Exceptions\TransportException; +use Bitrix24\SDK\Services\Sale\DeliveryHandler\Service\DeliveryHandler; +use Bitrix24\SDK\Tests\Integration\Fabric; +use PHPUnit\Framework\Attributes\CoversMethod; +use PHPUnit\Framework\TestCase; + +/** + * Class DeliveryHandlerTest + * + * @package Bitrix24\SDK\Tests\Integration\Services\Sale\DeliveryHandler\Service + */ +#[CoversMethod(DeliveryHandler::class,'add')] +#[CoversMethod(DeliveryHandler::class,'update')] +#[CoversMethod(DeliveryHandler::class,'list')] +#[CoversMethod(DeliveryHandler::class,'delete')] +#[\PHPUnit\Framework\Attributes\CoversClass(\Bitrix24\SDK\Services\Sale\DeliveryHandler\Service\DeliveryHandler::class)] +class DeliveryHandlerTest extends TestCase +{ + protected DeliveryHandler $deliveryHandlerService; + + protected function setUp(): void + { + $this->deliveryHandlerService = Fabric::getServiceBuilder()->getSaleScope()->deliveryHandler(); + } + + /** + * Get sample delivery handler fields for testing + */ + protected function getSampleDeliveryHandlerFields(): array + { + return [ + 'NAME' => 'Test Delivery Handler', + 'CODE' => 'test_delivery_handler_' . time(), + 'SORT' => 100, + 'DESCRIPTION' => 'Test delivery handler description', + 'SETTINGS' => [ + 'CALCULATE_URL' => 'https://example.com/calculate', + 'CREATE_DELIVERY_REQUEST_URL' => 'https://example.com/create', + 'CANCEL_DELIVERY_REQUEST_URL' => 'https://example.com/cancel', + 'HAS_CALLBACK_TRACKING_SUPPORT' => 'Y', + 'CONFIG' => [ + [ + 'TYPE' => 'STRING', + 'CODE' => 'API_KEY', + 'NAME' => 'API Key' + ], + [ + 'TYPE' => 'Y/N', + 'CODE' => 'TEST_MODE', + 'NAME' => 'Test Mode' + ], + [ + 'TYPE' => 'NUMBER', + 'CODE' => 'TIMEOUT', + 'NAME' => 'Request Timeout' + ], + [ + 'TYPE' => 'ENUM', + 'CODE' => 'SERVICE_TYPE', + 'NAME' => 'Service Type', + 'OPTIONS' => [ + 'EXPRESS' => 'Express Delivery', + 'STANDARD' => 'Standard Delivery', + 'ECONOMY' => 'Economy Delivery' + ] + ] + ] + ], + 'PROFILES' => [ + [ + 'NAME' => 'Express', + 'CODE' => 'EXPRESS', + 'DESCRIPTION' => 'Express delivery profile' + ], + [ + 'NAME' => 'Standard', + 'CODE' => 'STANDARD', + 'DESCRIPTION' => 'Standard delivery profile' + ] + ] + ]; + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testAdd(): void + { + // Create a delivery handler + $handlerFields = $this->getSampleDeliveryHandlerFields(); + + $addedItemResult = $this->deliveryHandlerService->add($handlerFields); + $handlerId = $addedItemResult->getId(); + + self::assertGreaterThan(0, $handlerId); + + // Clean up + $this->deliveryHandlerService->delete($handlerId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testUpdate(): void + { + // Create a delivery handler + $handlerFields = $this->getSampleDeliveryHandlerFields(); + + $addedItemResult = $this->deliveryHandlerService->add($handlerFields); + $handlerId = $addedItemResult->getId(); + + // Update the delivery handler + $updateFields = [ + 'NAME' => 'Updated Test Delivery Handler', + 'DESCRIPTION' => 'Updated description', + 'SORT' => 200 + ]; + + $updatedItemResult = $this->deliveryHandlerService->update($handlerId, $updateFields); + self::assertTrue($updatedItemResult->isSuccess()); + + // Verify the update by listing and finding our handler + $deliveryHandlersResult = $this->deliveryHandlerService->list(); + $handlers = $deliveryHandlersResult->getDeliveryHandlers(); + + $found = false; + foreach ($handlers as $handler) { + if ((int)$handler->ID === $handlerId) { + self::assertEquals('Updated Test Delivery Handler', $handler->NAME); + self::assertEquals('Updated description', $handler->DESCRIPTION); + self::assertEquals(200, (int)$handler->SORT); + $found = true; + break; + } + } + + self::assertTrue($found, 'Updated delivery handler should be found in the list'); + + // Clean up + $this->deliveryHandlerService->delete($handlerId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testList(): void + { + // Create a delivery handler + $handlerFields = $this->getSampleDeliveryHandlerFields(); + + $addedItemResult = $this->deliveryHandlerService->add($handlerFields); + $handlerId = $addedItemResult->getId(); + + // List delivery handlers + $deliveryHandlersResult = $this->deliveryHandlerService->list(); + $handlers = $deliveryHandlersResult->getDeliveryHandlers(); + + self::assertGreaterThan(0, count($handlers)); + + // Verify our handler is in the list + $found = false; + foreach ($handlers as $handler) { + if ((int)$handler->ID === $handlerId) { + self::assertEquals($handlerFields['NAME'], $handler->NAME); + self::assertEquals($handlerFields['CODE'], $handler->CODE); + self::assertEquals($handlerFields['DESCRIPTION'], $handler->DESCRIPTION); + + // Verify SETTINGS structure + self::assertIsArray($handler->SETTINGS); + self::assertEquals($handlerFields['SETTINGS']['CALCULATE_URL'], $handler->SETTINGS['CALCULATE_URL']); + self::assertEquals($handlerFields['SETTINGS']['HAS_CALLBACK_TRACKING_SUPPORT'], $handler->SETTINGS['HAS_CALLBACK_TRACKING_SUPPORT']); + + // Verify PROFILES structure + self::assertIsArray($handler->PROFILES); + self::assertCount(2, $handler->PROFILES); + + $found = true; + break; + } + } + + self::assertTrue($found, 'Created delivery handler should be found in the list'); + + // Clean up + $this->deliveryHandlerService->delete($handlerId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testDelete(): void + { + // Create a delivery handler + $handlerFields = $this->getSampleDeliveryHandlerFields(); + + $addedItemResult = $this->deliveryHandlerService->add($handlerFields); + $handlerId = $addedItemResult->getId(); + + // Delete the delivery handler + $deletedItemResult = $this->deliveryHandlerService->delete($handlerId); + self::assertTrue($deletedItemResult->isSuccess()); + + // Verify handler no longer exists in the list + $deliveryHandlersResult = $this->deliveryHandlerService->list(); + $handlers = $deliveryHandlersResult->getDeliveryHandlers(); + + $found = false; + foreach ($handlers as $handler) { + if ((int)$handler->ID === $handlerId) { + $found = true; + break; + } + } + + self::assertFalse($found, 'Deleted delivery handler should not be found in the list'); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testComplexSettings(): void + { + // Test with more complex SETTINGS structure + $handlerFields = $this->getSampleDeliveryHandlerFields(); + + // Add more complex CONFIG options + $handlerFields['SETTINGS']['CONFIG'][] = [ + 'TYPE' => 'DATE', + 'CODE' => 'VALID_UNTIL', + 'NAME' => 'Valid Until Date' + ]; + + $handlerFields['SETTINGS']['CONFIG'][] = [ + 'TYPE' => 'LOCATION', + 'CODE' => 'SERVICE_LOCATION', + 'NAME' => 'Service Location' + ]; + + $addedItemResult = $this->deliveryHandlerService->add($handlerFields); + $handlerId = $addedItemResult->getId(); + + self::assertGreaterThan(0, $handlerId); + + // Verify complex settings were saved correctly + $deliveryHandlersResult = $this->deliveryHandlerService->list(); + $handlers = $deliveryHandlersResult->getDeliveryHandlers(); + + $found = false; + foreach ($handlers as $handler) { + if ((int)$handler->ID === $handlerId) { + self::assertIsArray($handler->SETTINGS['CONFIG']); + self::assertCount(6, $handler->SETTINGS['CONFIG']); // 4 + 2 additional + $found = true; + break; + } + } + + self::assertTrue($found, 'Handler with complex settings should be found'); + + // Clean up + $this->deliveryHandlerService->delete($handlerId); + } + + /** + * @throws BaseException + * @throws TransportException + */ + public function testMultipleProfiles(): void + { + // Test with multiple profiles + $handlerFields = $this->getSampleDeliveryHandlerFields(); + + // Add more profiles + $handlerFields['PROFILES'][] = [ + 'NAME' => 'Economy', + 'CODE' => 'ECONOMY', + 'DESCRIPTION' => 'Economy delivery profile' + ]; + + $handlerFields['PROFILES'][] = [ + 'NAME' => 'Premium', + 'CODE' => 'PREMIUM', + 'DESCRIPTION' => 'Premium delivery profile' + ]; + + $addedItemResult = $this->deliveryHandlerService->add($handlerFields); + $handlerId = $addedItemResult->getId(); + + self::assertGreaterThan(0, $handlerId); + + // Verify all profiles were saved correctly + $deliveryHandlersResult = $this->deliveryHandlerService->list(); + $handlers = $deliveryHandlersResult->getDeliveryHandlers(); + + $found = false; + foreach ($handlers as $handler) { + if ((int)$handler->ID === $handlerId) { + self::assertIsArray($handler->PROFILES); + self::assertCount(4, $handler->PROFILES); // 2 + 2 additional + + // Check profile names + $profileNames = array_column($handler->PROFILES, 'NAME'); + self::assertContains('Express', $profileNames); + self::assertContains('Standard', $profileNames); + self::assertContains('Economy', $profileNames); + self::assertContains('Premium', $profileNames); + + $found = true; + break; + } + } + + self::assertTrue($found, 'Handler with multiple profiles should be found'); + + // Clean up + $this->deliveryHandlerService->delete($handlerId); + } +} \ No newline at end of file