From cf6729cbdc6924f203257647377ab3ab5dc6f647 Mon Sep 17 00:00:00 2001 From: Kocmonavtik <61938582+Kocmonavtik@users.noreply.github.com> Date: Tue, 11 Apr 2023 11:57:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B5=D0=B4=D0=B0=D1=87=D0=B8?= =?UTF-8?q?=20=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8?= =?UTF-8?q?=20=D0=BE=20=D0=BA=D0=BE=D1=80=D0=B7=D0=B8=D0=BD=D0=B0=D1=85=20?= =?UTF-8?q?=D0=B2=20=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=83=20(#284)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 + .../RetailcrmClasspathBuilder.php | 4 +- .../classes/general/ApiClient_v5.php | 51 +++++++ .../classes/general/RCrmActions.php | 5 + .../classes/general/cart/RetailCrmCart_v5.php | 129 ++++++++++++++++++ .../classes/general/events/RetailCrmEvent.php | 22 +++ .../general/order/RetailCrmOrder_v5.php | 16 +++ intaro.retailcrm/description.ru | 2 +- intaro.retailcrm/install/index.php | 3 + intaro.retailcrm/install/version.php | 4 +- intaro.retailcrm/lang/ru/options.php | 3 + .../lib/component/apiclient/clientadapter.php | 5 + .../component/apiclient/traits/carttrait.php | 70 ++++++++++ .../lib/component/configprovider.php | 8 ++ intaro.retailcrm/lib/component/constants.php | 1 + intaro.retailcrm/lib/model/api/cart/cart.php | 85 ++++++++++++ .../lib/model/api/cart/cartitem.php | 85 ++++++++++++ .../api/response/cart/cartgetresponse.php | 39 ++++++ .../model/api/response/cart/cartresponse.php | 32 +++++ intaro.retailcrm/options.php | 44 ++++++ .../general/events/RetailCrmEventTest.php | 93 +++++++++++++ 21 files changed, 700 insertions(+), 4 deletions(-) create mode 100644 intaro.retailcrm/classes/general/cart/RetailCrmCart_v5.php create mode 100644 intaro.retailcrm/lib/component/apiclient/traits/carttrait.php create mode 100644 intaro.retailcrm/lib/model/api/cart/cart.php create mode 100644 intaro.retailcrm/lib/model/api/cart/cartitem.php create mode 100644 intaro.retailcrm/lib/model/api/response/cart/cartgetresponse.php create mode 100644 intaro.retailcrm/lib/model/api/response/cart/cartresponse.php diff --git a/CHANGELOG.md b/CHANGELOG.md index ba71246d..12ecc428 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2023-04-06 v.6.3.0 +- Добавлен функционал передачи данных о содержимом корзины в систему + ## 2023-03-30 v.6.2.4 - Добавлен функционал слияния дублей пользователей по истории diff --git a/intaro.retailcrm/RetailcrmClasspathBuilder.php b/intaro.retailcrm/RetailcrmClasspathBuilder.php index 0d02f0d2..ef08a149 100644 --- a/intaro.retailcrm/RetailcrmClasspathBuilder.php +++ b/intaro.retailcrm/RetailcrmClasspathBuilder.php @@ -103,7 +103,8 @@ class RetailcrmClasspathBuilder protected static $versionedClasses = [ 'RetailCrm\ApiClient' => ['ApiClient.php', 'ApiClient_%s.php'], 'RetailCrmOrder' => ['RetailCrmOrder.php', 'RetailCrmOrder_%s.php'], - 'RetailCrmHistory' => ['RetailCrmHistory.php', 'RetailCrmHistory_%s.php'] + 'RetailCrmHistory' => ['RetailCrmHistory.php', 'RetailCrmHistory_%s.php'], + 'RetailCrmCart' => ['RetailCrmCart.php', 'RetailCrmCart_%s.php'] ]; /** @@ -116,6 +117,7 @@ class RetailcrmClasspathBuilder 'RetailCrmOrder_v5.php', 'RetailCrmHistory_v4.php', 'RetailCrmHistory_v5.php', + 'RetailCrmCart_v5.php', ]; /** diff --git a/intaro.retailcrm/classes/general/ApiClient_v5.php b/intaro.retailcrm/classes/general/ApiClient_v5.php index 598166a7..eb3118a0 100644 --- a/intaro.retailcrm/classes/general/ApiClient_v5.php +++ b/intaro.retailcrm/classes/general/ApiClient_v5.php @@ -12,6 +12,7 @@ namespace RetailCrm; use InvalidArgumentException; +use RetailCrm\Exception\CurlException; use RetailCrm\Http\Client; use RetailCrm\Response\ApiResponse; @@ -3127,4 +3128,54 @@ class ApiClient $request ); } + + /** + * @param int $customerId + * @param string $site + * @param string $by + * + * @return ApiResponse + */ + public function cartGet(int $customerId, string $site, string $by = 'externalId'): ApiResponse + { + $this->checkIdParameter($by); + + return $this->client->makeRequest( + '/customer-interaction/' . $site . '/cart/' . $customerId, + Client::METHOD_GET, + $this->fillSite($site, ['by' => $by]) + ); + } + + /** + * @param array $cart + * @param string $site + * @throws CurlException + * + * @return ApiResponse + */ + public function cartSet(array $cart, string $site): ApiResponse + { + return $this->client->makeRequest( + '/customer-interaction/' . $site . '/cart/set', + Client::METHOD_POST, + ['cart' => json_encode($cart)] + ); + } + + /** + * @param array $cart + * @param string $site + * @throws CurlException + * + * @return ApiResponse + */ + public function cartClear(array $cart, string $site): ApiResponse + { + return $this->client->makeRequest( + '/customer-interaction/' . $site . '/cart/clear', + Client::METHOD_POST, + ['cart' => json_encode($cart)] + ); + } } diff --git a/intaro.retailcrm/classes/general/RCrmActions.php b/intaro.retailcrm/classes/general/RCrmActions.php index 6a01b8fd..d5cec5bd 100644 --- a/intaro.retailcrm/classes/general/RCrmActions.php +++ b/intaro.retailcrm/classes/general/RCrmActions.php @@ -485,6 +485,11 @@ class RCrmActions return self::proxy($api, 'ordersPaymentEdit', $method, [$params, 'externalId', $site]); case 'customersCorporateEdit': return self::proxy($api, 'customersCorporateEdit', $method, [$params, 'externalId', $site]); + case 'cartGet': + return self::proxy($api, $methodApi, $method, [$params, $site, 'externalId']); + case 'cartSet': + case 'cartClear': + return self::proxy($api, $methodApi, $method, [$params, $site]); default: return self::proxy($api, $methodApi, $method, array($params, $site)); } diff --git a/intaro.retailcrm/classes/general/cart/RetailCrmCart_v5.php b/intaro.retailcrm/classes/general/cart/RetailCrmCart_v5.php new file mode 100644 index 00000000..454f630e --- /dev/null +++ b/intaro.retailcrm/classes/general/cart/RetailCrmCart_v5.php @@ -0,0 +1,129 @@ +setSite($site); + } else { + RCrmActions::eventLog( + 'RetailCrmCart::handlerCart', + 'RetailcrmConfigProvider::getSitesList', + 'Error set site' + ); + + return null; + } + } else { + $site = RetailcrmConfigProvider::getSitesAvailable(); + } + + $crmBasket = RCrmActions::apiMethod($api, 'cartGet', __METHOD__, $arBasket['USER_ID'], $site); + + if (empty($arBasket['BASKET'])) { + if (!empty($crmBasket['cart']['items'])) { + return RCrmActions::apiMethod( + $api, + 'cartClear', + __METHOD__, + [ + 'clearedAt' => date(self::$dateFormat), + 'customer' => [ + 'externalId' => $arBasket['USER_ID'] + ] + ], + $site + ); + } + + return null; + } + + $date = 'createdAt'; + $items = []; + + foreach ($arBasket['BASKET'] as $itemBitrix) { + $item['quantity'] = $itemBitrix['QUANTITY']; + $item['price'] = $itemBitrix['PRICE']; + $item['createdAt'] = $itemBitrix['DATE_INSERT']->format(self::$dateFormat); + $item['updateAt'] = $itemBitrix['DATE_UPDATE']->format(self::$dateFormat); + $item['offer']['externalId'] = $itemBitrix['PRODUCT_ID']; + $items[] = $item; + } + + if (!empty($crmBasket['cart']['items'])) { + $date = 'updatedAt'; + } + + return RCrmActions::apiMethod( + $api, + 'cartSet', + __METHOD__, + [ + 'customer' => [ + 'externalId' => $arBasket['USER_ID'], + 'site' => $site, + $date => date(self::$dateFormat), + ], + 'items' => $items, + ], + $site + ); + } + + /** + * @throws \Bitrix\Main\SystemException + * + * @return array|null + */ + public static function getBasketArray($event): ?array + { + if ($event instanceof Basket) { + $obBasket = $event; + } elseif ($event instanceof Event) { + $obBasket = $event->getParameter('ENTITY'); + } else { + RCrmActions::eventLog('RetailCrmEvent::onChangeBasket', 'getBasketArray', 'event error'); + + return null; + } + + $arBasket = [ + 'LID' => $obBasket->getSiteId(), + ]; + + $items = $obBasket->getBasket(); + + foreach ($items as $item) { + $arBasket['BASKET'][] = $item->getFields(); + } + + return $arBasket; + } +} diff --git a/intaro.retailcrm/classes/general/events/RetailCrmEvent.php b/intaro.retailcrm/classes/general/events/RetailCrmEvent.php index 6e3deabe..a3d10bb7 100644 --- a/intaro.retailcrm/classes/general/events/RetailCrmEvent.php +++ b/intaro.retailcrm/classes/general/events/RetailCrmEvent.php @@ -98,6 +98,28 @@ class RetailCrmEvent return; } + /** + * событие изменения корзины + * + * @param object $event + */ + public static function onChangeBasket($event) + { + $id = \Bitrix\Main\Engine\CurrentUser::get()->getId(); + + if ($id) { + $arBasket = RetailCrmCart::getBasketArray($event); + + if ($arBasket === null) { + return; + } + + $arBasket['USER_ID'] = $id; + + RetailCrmCart::handlerCart($arBasket); + } + } + /** * @param $event * diff --git a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php index 5bf9b46c..bb6562ed 100644 --- a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php +++ b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php @@ -400,6 +400,22 @@ class RetailCrmOrder if ($send) { if ($methodApi === 'ordersCreate') { + if (isset($arParams['customerCorporate']) && !empty($order['contact']['externalId'])) { + $externalId = $order['contact']['externalId']; + } else { + $externalId = $order['customer']['externalId']; + } + + if ($site === null) { + $site = RetailcrmConfigProvider::getSitesAvailable(); + } + + $crmBasket = RCrmActions::apiMethod($api, 'cartGet', __METHOD__, $externalId, $site); + + if (!empty($crmBasket['cart'])) { + $order['isFromCart'] = true; + } + return $client->createOrder($order, $site); } diff --git a/intaro.retailcrm/description.ru b/intaro.retailcrm/description.ru index 905c4eec..7620a546 100644 --- a/intaro.retailcrm/description.ru +++ b/intaro.retailcrm/description.ru @@ -1 +1 @@ -- Добавлен функционал слияния дублей пользователей по истории +- Добавлен функционал передачи данных о содержимом корзины в систему diff --git a/intaro.retailcrm/install/index.php b/intaro.retailcrm/install/index.php index 84805c26..e914ab1e 100644 --- a/intaro.retailcrm/install/index.php +++ b/intaro.retailcrm/install/index.php @@ -155,6 +155,7 @@ class intaro_retailcrm extends CModule include($this->INSTALL_PATH . '/../lib/component/apiclient/traits/customerscorporatetrait.php'); include($this->INSTALL_PATH . '/../lib/component/apiclient/traits/loyaltytrait.php'); include($this->INSTALL_PATH . '/../lib/component/apiclient/traits/ordertrait.php'); + include($this->INSTALL_PATH . '/../lib/component/apiclient/traits/carttrait.php'); include($this->INSTALL_PATH . '/../classes/general/Http/Client.php'); include($this->INSTALL_PATH . '/../classes/general/Response/ApiResponse.php'); include($this->INSTALL_PATH . '/../classes/general/RCrmActions.php'); @@ -197,6 +198,7 @@ class intaro_retailcrm extends CModule include($this->INSTALL_PATH . '/../classes/general/ApiClient_v5.php'); include($this->INSTALL_PATH . '/../classes/general/order/RetailCrmOrder_v5.php'); include($this->INSTALL_PATH . '/../classes/general/history/RetailCrmHistory_v5.php'); + include($this->INSTALL_PATH . '/../classes/general/cart/RetailCrmCart_v5.php'); $step = (int) $_REQUEST['step']; @@ -1212,6 +1214,7 @@ class intaro_retailcrm extends CModule require_once($this->INSTALL_PATH . '/../classes/general/order/RetailCrmOrder_v5.php'); require_once($this->INSTALL_PATH . '/../classes/general/history/RetailCrmHistory_v5.php'); require_once($this->INSTALL_PATH . '/../lib/component/constants.php'); + require_once($this->INSTALL_PATH . '/../classes/general/cart/RetailCrmCart_v5.php'); $retail_crm_api = new ApiClient($api_host, $api_key); diff --git a/intaro.retailcrm/install/version.php b/intaro.retailcrm/install/version.php index acc6155a..82d6d674 100644 --- a/intaro.retailcrm/install/version.php +++ b/intaro.retailcrm/install/version.php @@ -1,6 +1,6 @@ '6.2.4', - 'VERSION_DATE' => '2023-03-30 18:00:00' + 'VERSION' => '6.3.0', + 'VERSION_DATE' => '2023-04-06 17:00:00' ]; diff --git a/intaro.retailcrm/lang/ru/options.php b/intaro.retailcrm/lang/ru/options.php index 09517259..aff7189f 100644 --- a/intaro.retailcrm/lang/ru/options.php +++ b/intaro.retailcrm/lang/ru/options.php @@ -102,6 +102,9 @@ $MESS ['UNIVERSAL_ANALYTICS'] = 'Включить интеграцию с UA'; $MESS ['ID_UA'] = 'Идентификатор отслеживания:'; $MESS ['INDEX_UA'] = 'Индекс пользовательского параметра:'; +$MESS ['CART'] = 'Передавать состав корзины в систему'; +$MESS ['CART_DESCRIPTION'] = 'При включенной опции, данные о составе корзины передаются в карточку клиента в системе'; + $MESS ['API_NOT_FOUND'] = 'Неверная версия API'; $MESS ['API_NOT_WORK'] = 'Выбранная версия API не поддерживается'; diff --git a/intaro.retailcrm/lib/component/apiclient/clientadapter.php b/intaro.retailcrm/lib/component/apiclient/clientadapter.php index 8a06d2a7..72019a92 100644 --- a/intaro.retailcrm/lib/component/apiclient/clientadapter.php +++ b/intaro.retailcrm/lib/component/apiclient/clientadapter.php @@ -14,6 +14,7 @@ namespace Intaro\RetailCrm\Component\ApiClient; use Intaro\RetailCrm\Component\ApiClient\Traits\BaseClientTrait; +use Intaro\RetailCrm\Component\ApiClient\Traits\CartTrait; use Intaro\RetailCrm\Component\ApiClient\Traits\CustomersCorporateTrait; use Intaro\RetailCrm\Component\ApiClient\Traits\CustomersTrait; use Intaro\RetailCrm\Component\ApiClient\Traits\LoyaltyTrait; @@ -102,6 +103,9 @@ use RetailCrm\Response\ApiResponse; * @method ApiResponse statisticUpdate() * @method ApiResponse getSite() * @method ApiResponse setSite($site) + * @method ApiResponse cartGet(int $id, string $site, string $by = 'externalId') + * @method ApiResponse cartSet(array $cart, string $site) + * @method ApiResponse cartClear(array $cart, string $site) */ class ClientAdapter { @@ -110,6 +114,7 @@ class ClientAdapter use CustomersCorporateTrait; use LoyaltyTrait; use OrderTrait; + use CartTrait; /** @var string */ public const ID = 'id'; diff --git a/intaro.retailcrm/lib/component/apiclient/traits/carttrait.php b/intaro.retailcrm/lib/component/apiclient/traits/carttrait.php new file mode 100644 index 00000000..0c5ea334 --- /dev/null +++ b/intaro.retailcrm/lib/component/apiclient/traits/carttrait.php @@ -0,0 +1,70 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://retailcrm.ru/docs + */ + +namespace Intaro\RetailCrm\Component\ApiClient\Traits; + +use Intaro\RetailCrm\Component\Json\Deserializer; +use Intaro\RetailCrm\Model\Api\Response\Cart\CartGetResponse; +use Intaro\RetailCrm\Model\Api\Response\Cart\CartResponse; + +/** + * Trait CartTrait + * @package Intaro\RetailCrm\Component\ApiClient\Traits + */ +trait CartTrait +{ + /** + * Получение текущей корзины клиента + * + * @param int $id + * @param string $site + * @param string $by + * + * @return CartGetResponse|null + */ + public function cartGet(int $id, string $site, string $by = 'externalId'): ?CartGetResponse + { + $response = $this->client->cartGet($id, $site, $by); + + return Deserializer::deserializeArray($response->getResponseBody(), CartGetResponse::class); + } + + /** + * Создание или перезапись данных корзины + * + * @param array $cart + * @param string $site + * + * @return CartResponse|null + */ + public function cartSet(array $cart, string $site): ?CartResponse + { + $response = $this->client->cartSet($cart, $site); + + return Deserializer::deserializeArray($response->getResponseBody(), CartResponse::class); + } + + /** + * Очистка текущей корзины клиента + * + * @param array $cart + * @param string $site + * + * @return CartResponse|null + */ + public function cartClear(array $cart, string $site): ?CartResponse + { + $response = $this->client->cartClear($cart, $site); + + return Deserializer::deserializeArray($response->getResponseBody(), CartResponse::class); + } +} diff --git a/intaro.retailcrm/lib/component/configprovider.php b/intaro.retailcrm/lib/component/configprovider.php index 3a9c4cf1..d08ef0b7 100644 --- a/intaro.retailcrm/lib/component/configprovider.php +++ b/intaro.retailcrm/lib/component/configprovider.php @@ -1052,6 +1052,14 @@ class ConfigProvider COption::SetOptionString(Constants::MODULE_ID, Constants::CRM_DISCOUNT_ROUND, $discount_round); } + /** + * @return void + */ + public static function setCart($optionCart) + { + COption::SetOptionString(Constants::MODULE_ID, Constants::CART, $optionCart); + } + /** * @param string $version * diff --git a/intaro.retailcrm/lib/component/constants.php b/intaro.retailcrm/lib/component/constants.php index 318f3158..03c573a1 100644 --- a/intaro.retailcrm/lib/component/constants.php +++ b/intaro.retailcrm/lib/component/constants.php @@ -95,6 +95,7 @@ class Constants public const LOYALTY_FIELDS = 'loyalty_fields'; public const AGREEMENT_PERSONAL_DATA_CODE = 'AGREEMENT_PERSONAL_DATA_CODE'; public const AGREEMENT_LOYALTY_PROGRAM_CODE = 'AGREEMENT_LOYALTY_PROGRAM_CODE'; + public const CART = 'cart'; public const LP_EVENTS = [ ['EVENT_NAME' => 'OnSaleOrderSaved', 'FROM_MODULE' => 'sale'], ['EVENT_NAME' => 'OnSaleComponentOrderResultPrepared', 'FROM_MODULE' => 'sale'], diff --git a/intaro.retailcrm/lib/model/api/cart/cart.php b/intaro.retailcrm/lib/model/api/cart/cart.php new file mode 100644 index 00000000..e99bb5a1 --- /dev/null +++ b/intaro.retailcrm/lib/model/api/cart/cart.php @@ -0,0 +1,85 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://retailcrm.ru/docs + */ + +namespace Intaro\RetailCrm\Model\Api\Cart; + +use Intaro\RetailCrm\Component\Json\Mapping; +use Intaro\RetailCrm\Model\Api\AbstractApiModel; + +/** + * Class Cart + * + * @package Intaro\RetailCrm\Model\Api\Cart + */ +class Cart extends AbstractApiModel +{ + /** + * Внешний ID корзины + * + * @var string $externalId + * + * @Mapping\Type("string") + * @Mapping\SerializedName("externalId") + */ + public $externalId; + + /** + * Дата создания + * + * @var \DateTime $createdAt + * + * @Mapping\Type("DateTime<'Y-m-d H:i:s'>") + * @Mapping\SerializedName("createdAt") + */ + public $createdAt; + + /** + * Дата последнего обновления корзины + * + * @var \DateTime $updatedAt + * + * @Mapping\Type("DateTime<'Y-m-d H:i:s'>") + * @Mapping\SerializedName("updatedAt") + */ + public $updatedAt; + + /** + * Дата становления брошенной корзиной + * + * @var \DateTime $droppedAt + * + * @Mapping\Type("DateTime<'Y-m-d H:i:s'>") + * @Mapping\SerializedName("droppedAt") + */ + public $droppedAt; + + /** + * Ссылка + * + * @var string $link + * + * @Mapping\Type("string") + * @Mapping\SerializedName("link") + */ + public $link; + + /** + * Элементы корзины + * + * @var array $items + * + * @Mapping\Type("array") + * @Mapping\SerializedName("items") + */ + public $items; +} diff --git a/intaro.retailcrm/lib/model/api/cart/cartitem.php b/intaro.retailcrm/lib/model/api/cart/cartitem.php new file mode 100644 index 00000000..1a12b35c --- /dev/null +++ b/intaro.retailcrm/lib/model/api/cart/cartitem.php @@ -0,0 +1,85 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://retailcrm.ru/docs + */ + +namespace Intaro\RetailCrm\Model\Api\Cart; + +use Intaro\RetailCrm\Component\Json\Mapping; +use Intaro\RetailCrm\Model\Api\AbstractApiModel; + +/** + * Class CartItem + * + * @package Intaro\RetailCrm\Model\Api\Cart + */ +class CartItem extends AbstractApiModel +{ + /** + * ID элемента корзины + * + * @var int $id + * + * @Mapping\Type("integer") + * @Mapping\SerializedName("id") + */ + public $id; + + /** + * Количество + * + * @var $quantity + * + * @Mapping\Type("float") + * @Mapping\SerializedName("quantity") + */ + public $quantity; + + /** + * Цена + * + * @var float $price + * + * @Mapping\Type("float") + * @Mapping\SerializedName("price") + */ + public $price; + + /** + * Дата добавления в корзину + * + * @var \DateTime $createdAt + * + * @Mapping\Type("DateTime<'Y-m-d H:i:s'>") + * @Mapping\SerializedName("createdAt") + */ + public $createdAt; + + /** + * Дата обновления элемента корзины + * + * @var \DateTime $updatedAt + * + * @Mapping\Type("DateTime<'Y-m-d H:i:s'>") + * @Mapping\SerializedName("updatedAt") + */ + public $updatedAt; + + /** + * Торговое предложение + * + * @var array $offer + * + * @Mapping\Type("array") + * @Mapping\SerializedName("offer") + */ + public $offer; +} diff --git a/intaro.retailcrm/lib/model/api/response/cart/cartgetresponse.php b/intaro.retailcrm/lib/model/api/response/cart/cartgetresponse.php new file mode 100644 index 00000000..3b264363 --- /dev/null +++ b/intaro.retailcrm/lib/model/api/response/cart/cartgetresponse.php @@ -0,0 +1,39 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://retailcrm.ru/docs + */ + +namespace Intaro\RetailCrm\Model\Api\Response\Cart; + +use Intaro\RetailCrm\Model\Api\Cart\Cart; +use Intaro\RetailCrm\Model\Api\Response\AbstractApiResponseModel; +use Intaro\RetailCrm\Component\Json\Mapping; + +class CartGetResponse extends AbstractApiResponseModel +{ + /** + * Результат запроса (успешный/неуспешный) + * + * @var bool $success + * + * @Mapping\Type("boolean") + * @Mapping\SerializedName("success") + */ + public $success; + + /** + * @var Cart $cart + * + * @Mapping\Type("Intaro\RetailCrm\Model\Api\Cart\Cart") + * @Mapping\SerializedName("cart") + */ + public $cart; +} diff --git a/intaro.retailcrm/lib/model/api/response/cart/cartresponse.php b/intaro.retailcrm/lib/model/api/response/cart/cartresponse.php new file mode 100644 index 00000000..3ecf4725 --- /dev/null +++ b/intaro.retailcrm/lib/model/api/response/cart/cartresponse.php @@ -0,0 +1,32 @@ + + * @license MIT + * @link http://retailcrm.ru + * @see http://retailcrm.ru/docs + */ + +namespace Intaro\RetailCrm\Model\Api\Response\Cart; + +use Intaro\RetailCrm\Component\Json\Mapping; +use Intaro\RetailCrm\Model\Api\Response\AbstractApiResponseModel; + +/** + * Class CartResponse + * @package Intaro\RetailCrm\Model\Api\Response + */ +class CartResponse extends AbstractApiResponseModel +{ + /** + * @var bool + * + * @Mapping\Type("bool") + * @Mapping\SerializedName("success") + */ + public $success; +} diff --git a/intaro.retailcrm/options.php b/intaro.retailcrm/options.php index 3837de7f..4af988c5 100644 --- a/intaro.retailcrm/options.php +++ b/intaro.retailcrm/options.php @@ -62,6 +62,7 @@ $CRM_ADDRESS_OPTIONS = 'address_options'; $CRM_DIMENSIONS = 'order_dimensions'; $PROTOCOL = 'protocol'; $CRM_PURCHASE_PRICE_NULL = 'purchasePrice_null'; +$CRM_CART = 'cart'; if (!CModule::IncludeModule('intaro.retailcrm') || !CModule::IncludeModule('sale') || !CModule::IncludeModule('iblock') || !CModule::IncludeModule('catalog')) { return; @@ -319,6 +320,20 @@ if (isset($_POST['Update']) && ($_POST['Update'] === 'Y')) { RegisterModuleDependences('sale', 'OnSaleOrderDeleted', $mid, 'RetailCrmEvent', "orderDelete"); } + $optionCart = COption::GetOptionString($mid, $CRM_CART, 'N'); + + $cart = htmlspecialchars(trim($_POST['cart'])); + + if ($cart != $optionCart) { + if ($cart === 'Y') { + $optionCart = 'Y'; + RegisterModuleDependences('sale', 'OnSaleBasketSaved', $mid, 'RetailCrmEvent', 'onChangeBasket'); + } else { + $optionCart = 'N'; + UnRegisterModuleDependences('sale', 'OnSaleBasketSaved', $mid, 'RetailCrmEvent', 'onChangeBasket'); + } + } + $orderPropsArr = []; foreach ($orderTypesList as $orderType) { $propsCount = 0; @@ -757,6 +772,7 @@ if (isset($_POST['Update']) && ($_POST['Update'] === 'Y')) { ); RetailcrmConfigProvider::setSendPaymentAmount($sendPaymentAmount); RetailCrmConfigProvider::setDiscountRound($discount_round); + RetailcrmConfigProvider::setCart($optionCart); COption::SetOptionString( $mid, $CRM_PURCHASE_PRICE_NULL, @@ -924,6 +940,8 @@ if (isset($_POST['Update']) && ($_POST['Update'] === 'Y')) { $optionsOrderDimensions = COption::GetOptionString($mid, $CRM_DIMENSIONS, 'N'); $addressOptions = unserialize(COption::GetOptionString($mid, $CRM_ADDRESS_OPTIONS, 0)); + $optionCart = COption::GetOptionString($mid, $CRM_CART, 'N'); + //loyalty program options $loyaltyProgramToggle = ConfigProvider::getLoyaltyProgramStatus(); @@ -1176,6 +1194,16 @@ if (isset($_POST['Update']) && ($_POST['Update'] === 'Y')) { return true; }); + $('.r-ac-button label').change(function() { + if ($(this).find('input').is(':checked') === true) { + $('tr.r-ac').show('slow'); + } else if ($(this).find('input').is(':checked') === false) { + $('tr.r-ac').hide('slow'); + } + + return true; + }) + $('.r-cc-button label').change(function() { if ($(this).find('input').is(':checked') === true) { $('tr.r-cc').show('slow'); @@ -2328,6 +2356,22 @@ if (isset($_POST['Update']) && ($_POST['Update'] === 'Y')) { + + + + + + + + + > + + + + + diff --git a/tests/classes/general/events/RetailCrmEventTest.php b/tests/classes/general/events/RetailCrmEventTest.php index 7d019850..14ef001e 100755 --- a/tests/classes/general/events/RetailCrmEventTest.php +++ b/tests/classes/general/events/RetailCrmEventTest.php @@ -168,6 +168,60 @@ class RetailCrmEventTest extends PHPUnit\Framework\TestCase $this->assertEquals(true, $GLOBALS['ORDER_DELETE_USER_ADMIN']); } + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testSetBasket(): void + { + $arBasket = $this->getBasket(); + $crmBasket = $this->getCrmCart(); + + $actionsMock = Mockery::mock('alias:' . RCrmActions::class); + + $actionsMock->shouldReceive('apiMethod')->withAnyArgs()->andReturn($crmBasket, ['success' => true]); + + $result = RetailCrmCart::handlerCart($arBasket); + + self::assertTrue($result['success']); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testClearBasket(): void + { + $arBasket = ['LID' => 's1', 'USER_ID' => '1']; + $crmBasket = $this->getCrmCart(); + + $actionsMock = Mockery::mock('alias:' . RCrmActions::class); + + $actionsMock->shouldReceive('apiMethod')->withAnyArgs()->andReturn($crmBasket, ['success' => true]); + + $result = RetailCrmCart::handlerCart($arBasket); + + self::assertTrue($result['success']); + } + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testIgnoreChangeBasket() + { + $arBasket = ['LID' => 's1', 'USER_ID' => '1']; + $crmBasket = []; + + $actionsMock = Mockery::mock('alias:' . RCrmActions::class); + + $actionsMock->shouldReceive('apiMethod')->withAnyArgs()->andReturn($crmBasket); + + $result = RetailCrmCart::handlerCart($arBasket); + + self::assertNull($result); + } + /** * @return array */ @@ -238,4 +292,43 @@ class RetailCrmEventTest extends PHPUnit\Framework\TestCase $GLOBALS['RETAILCRM_ORDER_OLD_EVENT'] = true; $GLOBALS['RETAILCRM_ORDER_DELETE'] = false; } + + /** + * @return array + */ + public function getBasket(): array + { + return [ + 'LID' => 's1', + 'USER_ID' => '1', + 'BASKET' => [ + [ + 'QUANTITY' => 2, + 'PRICE' => 100, + 'DATE_INSERT' => new DateTime('now'), + 'DATE_UPDATE' => new DateTime('now'), + 'PRODUCT_ID' => '10' + ], + [ + 'QUANTITY' => 1, + 'PRICE' => 300, + 'DATE_INSERT' => new DateTime('now'), + 'DATE_UPDATE' => new DateTime('now'), + 'PRODUCT_ID' => '2' + ], + ], + ]; + } + + /** + * @return array + */ + public function getCrmCart(): array + { + return [ + 'cart' => [ + 'items' => 'items' + ] + ]; + } }