From 96e5bce336723f2f98df73633b71bdbaaa2e569f Mon Sep 17 00:00:00 2001
From: Vlad <48670792+Mozgito@users.noreply.github.com>
Date: Tue, 28 Jun 2022 15:28:28 +0300
Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?=
=?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B?=
=?UTF-8?q?=20=D1=81=D0=BE=20=D1=81=D0=BA=D0=B8=D0=B4=D0=BA=D0=B0=D0=BC?=
=?UTF-8?q?=D0=B8=20(#258)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 6 +
.../classes/general/config/objects.xml | 2 +
.../classes/general/config/retailcrm.json | 3 +
.../general/history/RetailCrmHistory_v5.php | 60 +++++-
.../general/order/RetailCrmOrder_v5.php | 19 +-
intaro.retailcrm/description.ru | 5 +-
intaro.retailcrm/install/version.php | 4 +-
.../builder/bitrix/loyaltydatabuilder.php | 21 ++-
.../lib/component/handlers/eventshandlers.php | 4 +-
.../en/service/orderloyaltydataservice.php | 2 +-
.../ru/service/orderloyaltydataservice.php | 2 +-
.../lib/model/api/order/orderproduct.php | 10 +
.../api/order/orderproductdiscountitem.php | 44 +++++
.../lib/model/bitrix/orderloyaltydata.php | 10 +-
.../repository/orderloyaltydatarepository.php | 85 ++++++---
.../lib/service/orderloyaltydataservice.php | 63 ++++++-
intaro.retailcrm/updater.php | 172 +++++++++++++++++-
17 files changed, 436 insertions(+), 76 deletions(-)
create mode 100644 intaro.retailcrm/lib/model/api/order/orderproductdiscountitem.php
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fe0fc214..cde84522 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 2022-06-28 v.6.1.0
+- Исправлены ошибки дублирования скидок при обмене данными
+- Скорректирована работа с общей скидкой по заказу, она более не переносится в скидку по товару в CRM
+- Скорректирована передача бонусов и персональных скидок
+- Исправлены типы полей скидок в HL-блоке программы лояльности
+
## 2022-06-17 v.6.0.6
- Замена устаревшего jQuery метода
diff --git a/intaro.retailcrm/classes/general/config/objects.xml b/intaro.retailcrm/classes/general/config/objects.xml
index 564883a6..82210e9a 100644
--- a/intaro.retailcrm/classes/general/config/objects.xml
+++ b/intaro.retailcrm/classes/general/config/objects.xml
@@ -81,6 +81,8 @@
quantity
status
discountTotal
+ bonusesCharge
+ bonusesCredit
status
type
diff --git a/intaro.retailcrm/classes/general/config/retailcrm.json b/intaro.retailcrm/classes/general/config/retailcrm.json
index ff2c144f..a0708826 100644
--- a/intaro.retailcrm/classes/general/config/retailcrm.json
+++ b/intaro.retailcrm/classes/general/config/retailcrm.json
@@ -564,6 +564,9 @@
},
"content": {
"type": "string"
+ },
+ "privilegeType": {
+ "type": "string"
}
}
}
diff --git a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
index 12af716a..e7f3c92e 100644
--- a/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
+++ b/intaro.retailcrm/classes/general/history/RetailCrmHistory_v5.php
@@ -15,7 +15,10 @@ use Bitrix\Sale\Location\Search\Finder;
use Bitrix\Sale\Order;
use Bitrix\Sale\OrderUserProperties;
use Bitrix\Sale\Payment;
+use Intaro\RetailCrm\Component\ServiceLocator;
+use Intaro\RetailCrm\Component\Builder\Bitrix\LoyaltyDataBuilder;
use Intaro\RetailCrm\Service\ManagerService;
+use Intaro\RetailCrm\Service\OrderLoyaltyDataService;
use Intaro\RetailCrm\Component\ConfigProvider;
use Intaro\RetailCrm\Component\Constants;
use Intaro\RetailCrm\Component\Handlers\EventsHandlers;
@@ -251,6 +254,9 @@ class RetailCrmHistory
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
+ /* @var OrderLoyaltyDataService $orderLoyaltyDataService */
+ $orderLoyaltyDataService = ServiceLocator::get(OrderLoyaltyDataService::class);
+
$historyFilter = array();
$historyStart = COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_HISTORY);
@@ -988,6 +994,10 @@ class RetailCrmHistory
$optionDiscRound = COption::GetOptionString(self::$MODULE_ID, self::$CRM_DISCOUNT_ROUND, 0);
+ $editBasketInfo = [];
+ $deleteBasketInfo = [];
+ $bonusesChargeTotal = null;
+
foreach ($order['items'] as $product) {
if ($collectItems[$product['offer']['externalId']]['quantity']) {
$product['quantity'] = $collectItems[$product['offer']['externalId']]['quantity'];
@@ -1029,12 +1039,11 @@ class RetailCrmHistory
}
}
- if ($product['delete']) {
- if ($collectItems[$product['offer']['externalId']]['quantity'] <= 0) {
+ if ($product['delete'] && $collectItems[$product['offer']['externalId']]['quantity'] <= 0) {
+ $deleteBasketInfo[] = $item->getBasketCode();
$item->delete();
continue;
- }
}
if ($product['quantity']) {
@@ -1065,6 +1074,25 @@ class RetailCrmHistory
$item->setField('PRICE', $price);
}
+
+ $manualProductDiscount = 0;
+ $bonusesChargeProduct = $product['bonusesCharge'] ?? null;
+
+ foreach ($product['discounts'] as $productDiscount) {
+ if ('manual_product' === $productDiscount['type']) {
+ $manualProductDiscount = $productDiscount['amount'];
+ }
+ }
+
+ $editBasketInfo[] = [
+ 'productId' => $item->getProductId(),
+ 'productDiscount' => $manualProductDiscount / $item->getQuantity(),
+ 'bonusesCharge' => $bonusesChargeProduct,
+ ];
+
+ if (null !== $bonusesChargeProduct) {
+ $bonusesChargeTotal += $bonusesChargeProduct;
+ }
}
}
@@ -1152,6 +1180,32 @@ class RetailCrmHistory
self::orderSave($newOrder);
}
+ //items loyalty info to HL
+ if (!empty($editBasketInfo)) {
+ $newBasket = $newOrder->getBasket();
+ $calculateItemsInput = [];
+ $basketItemIds = [];
+
+ foreach ($editBasketInfo as $itemInfo) {
+ $basketItem = self::getExistsItem($newBasket, 'catalog', $itemInfo['productId']);
+ if (false !== $basketItem) {
+ $calculateItemsInput[$basketItem->getId()]['SHOP_ITEM_DISCOUNT'] = $itemInfo['productDiscount'];
+ $calculateItemsInput[$basketItem->getId()]['BONUSES_CHARGE'] = $itemInfo['bonusesCharge'];
+ $basketItemIds[] = $basketItem->getId();
+ }
+ }
+
+ $hlInfoBuilder = new LoyaltyDataBuilder();
+ $hlInfoBuilder->setOrder($newOrder);
+ $hlInfoBuilder->setCalculateItemsInput($calculateItemsInput);
+ $hlInfoBuilder->setBonusCountTotal($bonusesChargeTotal);
+ $orderLoyaltyDataService->saveLoyaltyInfoToHl($hlInfoBuilder->build($basketItemIds)->getResult());
+ }
+
+ if (!empty($deleteBasketInfo)) {
+ $orderLoyaltyDataService->deleteLoyaltyInfoFromHl($deleteBasketInfo);
+ }
+
if (!empty($newHistoryPayments)) {
foreach ($newOrder->getPaymentCollection() as $orderPayment) {
if (array_key_exists($orderPayment->getField('XML_ID'), $newHistoryPayments)) {
diff --git a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php
index cf2ad645..ca1b61d9 100644
--- a/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php
+++ b/intaro.retailcrm/classes/general/order/RetailCrmOrder_v5.php
@@ -98,11 +98,6 @@ class RetailCrmOrder
$order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arOrder['PERSON_TYPE_ID']];
- if ($methodApi === 'ordersEdit') {
- $order['discountManualAmount'] = 0;
- $order['discountManualPercent'] = 0;
- }
-
//fields
foreach ($arOrder['PROPS']['properties'] as $prop) {
if (!empty($arParams['optionsLegalDetails'])
@@ -284,7 +279,7 @@ class RetailCrmOrder
) {
/** @var LoyaltyService $service */
$service = ServiceLocator::get(LoyaltyService::class);
- $item['discountManualAmount'] = $service->getInitialDiscount((int) $externalId) ?? $discount;
+ $item['discountManualAmount'] = $service->getInitialDiscount((int) $product['ID']) ?? $discount;
} elseif ($product['BASE_PRICE'] >= $product['PRICE']) {
$item['discountManualAmount'] = self::getDiscountManualAmount($product);
$item['initialPrice'] = (double) $product['BASE_PRICE'];
@@ -355,6 +350,14 @@ class RetailCrmOrder
$order['payments'] = $payments;
}
+ if (!empty($arParams['crmOrder']['privilegeType'])) {
+ $order['privilegeType'] = $arParams['crmOrder']['privilegeType'];
+ } elseif (ConfigProvider::getLoyaltyProgramStatus() === 'Y' && LoyaltyAccountService::getLoyaltyPersonalStatus()) {
+ $order['privilegeType'] = 'loyalty_level';
+ } else {
+ $order['privilegeType'] = 'none';
+ }
+
//send
if (function_exists('retailCrmBeforeOrderSend')) {
$newResOrder = retailCrmBeforeOrderSend($order, $arOrder);
@@ -380,10 +383,6 @@ class RetailCrmOrder
Logger::getInstance()->write($order, 'orderSend');
- if (ConfigProvider::getLoyaltyProgramStatus() === 'Y' && LoyaltyAccountService::getLoyaltyPersonalStatus()) {
- $order['privilegeType'] = 'loyalty_level';
- }
-
/** @var \Intaro\RetailCrm\Component\ApiClient\ClientAdapter $client */
$client = ClientFactory::createClientAdapter();
diff --git a/intaro.retailcrm/description.ru b/intaro.retailcrm/description.ru
index c83d006f..8941ef9b 100644
--- a/intaro.retailcrm/description.ru
+++ b/intaro.retailcrm/description.ru
@@ -1 +1,4 @@
-- Замена устаревшего jQuery метода
\ No newline at end of file
+- Исправлены ошибки задвоения скидок при обмене данными
+- Скорректирована работа с общей скидкой по заказу, она более не переносится в скидку по товару в CRM
+- Скорректирована передача бонусов и персональных скидок
+- Исправлены типы полей скидок в HL-блоке программы лояльности
\ No newline at end of file
diff --git a/intaro.retailcrm/install/version.php b/intaro.retailcrm/install/version.php
index ad883cb8..61f71d4b 100644
--- a/intaro.retailcrm/install/version.php
+++ b/intaro.retailcrm/install/version.php
@@ -1,6 +1,6 @@
'6.0.6',
- 'VERSION_DATE' => '2022-06-17 12:00:00'
+ 'VERSION' => '6.1.0',
+ 'VERSION_DATE' => '2022-06-28 11:00:00'
];
diff --git a/intaro.retailcrm/lib/component/builder/bitrix/loyaltydatabuilder.php b/intaro.retailcrm/lib/component/builder/bitrix/loyaltydatabuilder.php
index 600a2145..4f65aae6 100644
--- a/intaro.retailcrm/lib/component/builder/bitrix/loyaltydatabuilder.php
+++ b/intaro.retailcrm/lib/component/builder/bitrix/loyaltydatabuilder.php
@@ -24,8 +24,6 @@ use Intaro\RetailCrm\Model\Api\OrderProduct;
use Intaro\RetailCrm\Model\Api\Response\Order\Loyalty\OrderLoyaltyApplyResponse;
use Intaro\RetailCrm\Model\Bitrix\OrderLoyaltyData;
use Intaro\RetailCrm\Service\CookieService;
-use Intaro\RetailCrm\Service\LoyaltyService;
-use Intaro\RetailCrm\Service\OrderLoyaltyDataService;
use Logger;
/**
@@ -50,9 +48,7 @@ class LoyaltyDataBuilder implements BuilderInterface
/** @var OrderLoyaltyData[] $data */
private $data;
- /**
- * @var float
- */
+ /** @var float|null */
private $bonusCountTotal;
/**
@@ -64,13 +60,19 @@ class LoyaltyDataBuilder implements BuilderInterface
}
/**
+ * @param int[] $basketItemIds
+ *
* @return \Intaro\RetailCrm\Component\Builder\BuilderInterface
*/
- public function build(): BuilderInterface
+ public function build(array $basketItemIds = []): BuilderInterface
{
try {
/** @var BasketItemBase $basketItem */
foreach ($this->order->getBasket() as $key => $basketItem) {
+ if (!empty($basketItemIds) && !in_array($basketItem->getId(), $basketItemIds)) {
+ continue;
+ }
+
$loyaltyHl = new OrderLoyaltyData();
$loyaltyHl->orderId = $this->order->getId();
$loyaltyHl->itemId= $basketItem->getProductId();
@@ -82,6 +84,9 @@ class LoyaltyDataBuilder implements BuilderInterface
$loyaltyHl->defaultDiscount
= $this->calculateItemsInput[$loyaltyHl->basketItemPositionId]['SHOP_ITEM_DISCOUNT'] ?? null;
+ $loyaltyHl->bonusCount
+ = $this->calculateItemsInput[$loyaltyHl->basketItemPositionId]['BONUSES_CHARGE'] ?? null;
+
$this->addBonusInfo($loyaltyHl, $key);
$this->data[] = $loyaltyHl;
@@ -150,9 +155,9 @@ class LoyaltyDataBuilder implements BuilderInterface
}
/**
- * @param float $bonusCountTotal
+ * @param float|null $bonusCountTotal
*/
- public function setBonusInputTotal(float $bonusCountTotal): void
+ public function setBonusCountTotal(?float $bonusCountTotal): void
{
$this->bonusCountTotal = $bonusCountTotal;
}
diff --git a/intaro.retailcrm/lib/component/handlers/eventshandlers.php b/intaro.retailcrm/lib/component/handlers/eventshandlers.php
index aead029f..d99ec5b5 100644
--- a/intaro.retailcrm/lib/component/handlers/eventshandlers.php
+++ b/intaro.retailcrm/lib/component/handlers/eventshandlers.php
@@ -185,7 +185,7 @@ class EventsHandlers
? json_decode(htmlspecialchars_decode($_POST['calculate-items-input']), true)
: [];
- if ($isNewOrder && $isLoyaltyOn) {
+ if ($isNewOrder && $isLoyaltyOn && ($isDataForLoyaltyDiscount || $isBonusInput)) {
self::$disableSaleHandler = true;
$hlInfoBuilder = new LoyaltyDataBuilder();
@@ -204,7 +204,7 @@ class EventsHandlers
$hlInfoBuilder->setApplyResponse($applyBonusResponse);
$loyaltyBonusMsg = $bonusFloat;
- $hlInfoBuilder->setBonusInputTotal($bonusFloat);
+ $hlInfoBuilder->setBonusCountTotal($bonusFloat);
}
//Если бонусов нет, но скидка по ПЛ есть
diff --git a/intaro.retailcrm/lib/lang/en/service/orderloyaltydataservice.php b/intaro.retailcrm/lib/lang/en/service/orderloyaltydataservice.php
index 1da3d02d..df4b2f64 100644
--- a/intaro.retailcrm/lib/lang/en/service/orderloyaltydataservice.php
+++ b/intaro.retailcrm/lib/lang/en/service/orderloyaltydataservice.php
@@ -4,7 +4,7 @@ $MESS ['UF_ITEM_ID'] = 'Product ID';
$MESS ['UF_DEF_DISCOUNT'] = 'Shop discount';
$MESS ['UF_ITEM_POS_ID'] = 'Basket position ID';
$MESS ['UF_CHECK_ID'] = 'Verification code ID';
-$MESS ['LP_BONUS_INFO'] = 'Bonus info';
+$MESS ['LP_BONUS_INFO'] = 'Bonuses charged';
$MESS ['LP_DISCOUNT_INFO'] = 'Personal discount';
$MESS ['LP_ORDER_GROUP_NAME'] = 'Loyalty program';
$MESS ['UF_QUANTITY'] = 'Quantity in the basket';
diff --git a/intaro.retailcrm/lib/lang/ru/service/orderloyaltydataservice.php b/intaro.retailcrm/lib/lang/ru/service/orderloyaltydataservice.php
index 59b820cc..f3fbc35a 100644
--- a/intaro.retailcrm/lib/lang/ru/service/orderloyaltydataservice.php
+++ b/intaro.retailcrm/lib/lang/ru/service/orderloyaltydataservice.php
@@ -4,7 +4,7 @@ $MESS ['UF_ITEM_ID'] = 'ID товара';
$MESS ['UF_DEF_DISCOUNT'] = 'Скидка магазина';
$MESS ['UF_ITEM_POS_ID'] = 'ID позиции в корзине';
$MESS ['UF_CHECK_ID'] = 'ID проверочного кода';
-$MESS ['LP_BONUS_INFO'] = 'Бонусов начислено';
+$MESS ['LP_BONUS_INFO'] = 'Бонусов списано';
$MESS ['LP_DISCOUNT_INFO'] = 'Персональная скидка';
$MESS ['LP_ORDER_GROUP_NAME'] = 'Программа лояльности';
$MESS ['UF_QUANTITY'] = 'Количество в корзине';
diff --git a/intaro.retailcrm/lib/model/api/order/orderproduct.php b/intaro.retailcrm/lib/model/api/order/orderproduct.php
index d079eeef..a1b3c8f0 100644
--- a/intaro.retailcrm/lib/model/api/order/orderproduct.php
+++ b/intaro.retailcrm/lib/model/api/order/orderproduct.php
@@ -73,6 +73,16 @@ class OrderProduct extends AbstractApiModel
*/
public $quantity;
+ /**
+ * Набор итоговых скидок на товарную позицию
+ *
+ * @var array $discounts
+ *
+ * @Mapping\Type("array")
+ * @Mapping\SerializedName("discounts")
+ */
+ public $discounts;
+
/**
* Итоговая денежная скидка на единицу товара c учетом всех скидок на товар и заказ
*
diff --git a/intaro.retailcrm/lib/model/api/order/orderproductdiscountitem.php b/intaro.retailcrm/lib/model/api/order/orderproductdiscountitem.php
new file mode 100644
index 00000000..48ba1f51
--- /dev/null
+++ b/intaro.retailcrm/lib/model/api/order/orderproductdiscountitem.php
@@ -0,0 +1,44 @@
+
+ * @license MIT
+ * @link http://retailcrm.ru
+ * @see http://retailcrm.ru/docs
+ */
+
+namespace Intaro\RetailCrm\Model\Api\Order;
+
+use Intaro\RetailCrm\Model\Api\AbstractApiModel;
+use Intaro\RetailCrm\Component\Json\Mapping;
+
+/**
+ * Class OrderProductPriceItem
+ * @package Intaro\RetailCrm\Model\Api\Order
+ */
+class OrderProductDiscountItem extends AbstractApiModel
+{
+ /**
+ * Тип скидки
+ *
+ * @var string
+ *
+ * @Mapping\Type("string")
+ * @Mapping\SerializedName("type")
+ */
+ public $type;
+
+ /**
+ * Денежная величина скидки на товарную позицию
+ *
+ * @var float $amount
+ *
+ * @Mapping\Type("float")
+ * @Mapping\SerializedName("amount")
+ */
+ public $amount;
+}
diff --git a/intaro.retailcrm/lib/model/bitrix/orderloyaltydata.php b/intaro.retailcrm/lib/model/bitrix/orderloyaltydata.php
index b893733f..0125fd97 100644
--- a/intaro.retailcrm/lib/model/bitrix/orderloyaltydata.php
+++ b/intaro.retailcrm/lib/model/bitrix/orderloyaltydata.php
@@ -77,7 +77,7 @@ class OrderLoyaltyData
/**
* Количество в корзине
*
- * @var float
+ * @var integer
*
* @Mapping\Type("integer")
* @Mapping\SerializedName("UF_QUANTITY")
@@ -119,9 +119,9 @@ class OrderLoyaltyData
/**
* Количество списываемых бонусов по позиции
*
- * @var integer
+ * @var float
*
- * @Mapping\Type("integer")
+ * @Mapping\Type("float")
* @Mapping\SerializedName("UF_BONUS_COUNT")
*/
public $bonusCount;
@@ -129,9 +129,9 @@ class OrderLoyaltyData
/**
* Количество списываемых бонусов по всему заказу
*
- * @var integer
+ * @var float
*
- * @Mapping\Type("integer")
+ * @Mapping\Type("float")
* @Mapping\SerializedName("UF_BONUS_COUNT_TOTAL")
*/
public $bonusCountTotal;
diff --git a/intaro.retailcrm/lib/repository/orderloyaltydatarepository.php b/intaro.retailcrm/lib/repository/orderloyaltydatarepository.php
index c1759110..12edbad8 100644
--- a/intaro.retailcrm/lib/repository/orderloyaltydatarepository.php
+++ b/intaro.retailcrm/lib/repository/orderloyaltydatarepository.php
@@ -35,12 +35,12 @@ class OrderLoyaltyDataRepository extends AbstractRepository
* @var \Bitrix\Main\Entity\DataManager|string|null
*/
private $dataManager;
-
+
/**
* @var \Logger
*/
private $logger;
-
+
/**
* OrderLoyaltyDataRepository constructor.
* @throws \Bitrix\Main\LoaderException
@@ -51,7 +51,7 @@ class OrderLoyaltyDataRepository extends AbstractRepository
$this->logger = Logger::getInstance();
$this->dataManager = Utils::getHlClassByName(Constants::HL_LOYALTY_CODE);
}
-
+
/**
* @param \Intaro\RetailCrm\Model\Bitrix\OrderLoyaltyData $loyaltyHl
* @return int|null
@@ -62,25 +62,25 @@ class OrderLoyaltyDataRepository extends AbstractRepository
if ($this->dataManager === null) {
return null;
}
-
+
$result = Serializer::serializeArray($loyaltyHl, OrderLoyaltyData::class);
-
+
unset($result['ID']);
-
+
$result = $this->dataManager::add($result);
-
+
if ($result->isSuccess()) {
return $result->getId();
}
-
+
return null;
} catch (Exception $exception) {
$this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
}
-
+
return null;
}
-
+
/**
* @param int $positionId
* @return \Intaro\RetailCrm\Model\Bitrix\OrderLoyaltyData|null
@@ -90,20 +90,23 @@ class OrderLoyaltyDataRepository extends AbstractRepository
if ($this->dataManager === null) {
return null;
}
-
+
try {
$product = $this->dataManager::query()
->setSelect(['*'])
->where('UF_ITEM_POS_ID', '=', $positionId)
->fetch();
-
- /** @var OrderLoyaltyData $result */
+
+ if (false === $product) {
+ return null;
+ }
+
return Deserializer::deserializeArray($product, OrderLoyaltyData::class);
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
$this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
}
}
-
+
/**
* @param $orderId
*
@@ -161,24 +164,55 @@ class OrderLoyaltyDataRepository extends AbstractRepository
if ($this->dataManager === null) {
return false;
}
-
+
$productAr = Serializer::serializeArray($position, OrderLoyaltyData::class);
-
+
unset($productAr['ID']);
-
+
+ foreach ($productAr as $key => $value) {
+ if (null === $value) {
+ unset($productAr[$key]);
+ }
+ }
+
$result = $this->dataManager::update($position->id, $productAr);
-
+
if ($result->isSuccess()) {
return true;
}
-
+
} catch (Exception $exception) {
$this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
}
-
+
return false;
}
-
+
+ /**
+ * @param mixed $primary
+ * @return bool
+ */
+ public function delete($primary): bool
+ {
+ try {
+ if ($this->dataManager === null) {
+ return false;
+ }
+
+ $result = $this->dataManager::delete($primary);
+
+ if ($result->isSuccess()) {
+ return true;
+ }
+
+ } catch (Exception $exception) {
+ $this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
+ }
+
+ return false;
+
+ }
+
/**
* @param int $externalId
* @return float|null
@@ -189,22 +223,21 @@ class OrderLoyaltyDataRepository extends AbstractRepository
if ($this->dataManager === null) {
return null;
}
-
+
$result = $this->dataManager::query()
->setSelect(['UF_DEF_DISCOUNT'])
->where([
['UF_ITEM_POS_ID', '=', $externalId]
])
- ->fetch();
-
+ ->fetch();
+
if ($result !== false) {
return (float) $result['UF_DEF_DISCOUNT'];
}
-
} catch (SystemException | Exception $exception) {
$this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
}
-
+
return null;
}
}
diff --git a/intaro.retailcrm/lib/service/orderloyaltydataservice.php b/intaro.retailcrm/lib/service/orderloyaltydataservice.php
index 02fc9051..1d3bee45 100644
--- a/intaro.retailcrm/lib/service/orderloyaltydataservice.php
+++ b/intaro.retailcrm/lib/service/orderloyaltydataservice.php
@@ -85,6 +85,17 @@ class OrderLoyaltyDataService
*/
public static function createLoyaltyHlBlock(): void
{
+ $checkHl = HL\HighloadBlockTable::query()
+ ->addSelect('*')
+ ->addFilter('NAME', Constants::HL_LOYALTY_CODE)
+ ->addFilter('TABLE_NAME', Constants::HL_LOYALTY_TABLE_NAME)
+ ->exec()
+ ->fetch();
+
+ if (false !== $checkHl) {
+ return;
+ }
+
$result = HL\HighloadBlockTable::add([
'NAME' => Constants::HL_LOYALTY_CODE,
'TABLE_NAME' => Constants::HL_LOYALTY_TABLE_NAME,
@@ -170,18 +181,15 @@ class OrderLoyaltyDataService
return;
}
- $repository = new OrderLoyaltyDataRepository();
- $bitrixItems = $repository->getProductsByOrderId($orderId);
$loyaltyDiscount = 0;
/** @var OrderProduct $item */
foreach ($response->order->items as $item) {
- /** @var CodeValueModel $itemBitrixId */
- $itemBitrixId = $item->externalIds[0];
- /** @var OrderLoyaltyData $bitrixItem */
- $bitrixItem = $bitrixItems[$itemBitrixId->value];
-
- $loyaltyDiscount += ($item->discountTotal - $bitrixItem->defaultDiscount) * $item->quantity;
+ foreach ($item->discounts as $discount) {
+ if (in_array($discount->type, ['personal', 'loyalty_level'])) {
+ $loyaltyDiscount += $discount->amount;
+ }
+ }
}
$this->saveBonusAndDiscToOrderProps(
@@ -264,7 +272,33 @@ class OrderLoyaltyDataService
$repository = new OrderLoyaltyDataRepository();
foreach ($loyaltyHls as $loyaltyData) {
- $repository->add($loyaltyData);
+ $positionLpData = $repository->getOrderLpDataByPosition($loyaltyData->basketItemPositionId);
+
+ if (null !== $positionLpData) {
+ $loyaltyData->id = $positionLpData->id;
+ $repository->edit($loyaltyData);
+ } else {
+ $repository->add($loyaltyData);
+ }
+ }
+ }
+
+ /**
+ * Удаляет данные о ПЛ из HL-блока
+ *
+ * @param int[] $basketItemIds
+ * @return void
+ */
+ public function deleteLoyaltyInfoFromHl(array $basketItemIds): void
+ {
+ $repository = new OrderLoyaltyDataRepository();
+
+ foreach ($basketItemIds as $basketItemId) {
+ $positionLpData = $repository->getOrderLpDataByPosition($basketItemId);
+
+ if (null !== $positionLpData) {
+ $repository->delete($positionLpData->id);
+ }
}
}
@@ -465,6 +499,9 @@ class OrderLoyaltyDataService
'ru' => Loc::GetMessage('UF_DEF_DISCOUNT', null, 'ru'),
'en' => Loc::GetMessage('UF_DEF_DISCOUNT', null, 'en'),
],
+ 'SETTINGS' => [
+ 'PRECISION' => 2,
+ ],
],
'UF_CHECK_ID' => [
'ENTITY_ID' => $ufObject,
@@ -537,11 +574,14 @@ class OrderLoyaltyDataService
'ru' => Loc::GetMessage('UF_BONUS_COUNT', null, 'ru'),
'en' => Loc::GetMessage('UF_BONUS_COUNT', null, 'en'),
],
+ 'SETTINGS' => [
+ 'PRECISION' => 2,
+ ],
],
'UF_BONUS_COUNT_TOTAL' => [
'ENTITY_ID' => $ufObject,
'FIELD_NAME' => 'UF_BONUS_COUNT_TOTAL',
- 'USER_TYPE_ID' => 'integer',
+ 'USER_TYPE_ID' => 'double',
'MANDATORY' => 'N',
'EDIT_FORM_LABEL' => [
'ru' => Loc::GetMessage('UF_BONUS_COUNT_TOTAL', null, 'ru'),
@@ -555,6 +595,9 @@ class OrderLoyaltyDataService
'ru' => Loc::GetMessage('UF_BONUS_COUNT_TOTAL', null, 'ru'),
'en' => Loc::GetMessage('UF_BONUS_COUNT_TOTAL', null, 'en'),
],
+ 'SETTINGS' => [
+ 'PRECISION' => 2,
+ ],
],
];
}
diff --git a/intaro.retailcrm/updater.php b/intaro.retailcrm/updater.php
index 25903681..ede8cddc 100644
--- a/intaro.retailcrm/updater.php
+++ b/intaro.retailcrm/updater.php
@@ -910,6 +910,168 @@ class LoyaltyProgramUpdater
}
}
}
+
+
+ public function updateBonusInfoFieldForLp(): self
+ {
+ $bonusProps = CSaleOrderProps::GetList([], ['CODE' => 'LP_BONUS_INFO']);
+ $lang = Context::getCurrent()->getLanguage();
+ $lpBonusInfo = [
+ 'ru' => 'Бонусов списано',
+ 'en' => 'Bonuses charged'
+ ][$lang];
+ $updateInfo = [
+ 'NAME' => $lpBonusInfo,
+ 'DESCRIPTION' => $lpBonusInfo,
+ ];
+
+ while ($bonusProp = $bonusProps->Fetch())
+ {
+ CSaleOrderProps::Update($bonusProp['ID'], $updateInfo);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Обновление типов полей с бонусами и перенос информации
+ *
+ * @throws Main\ArgumentException
+ * @throws Main\ObjectPropertyException
+ * @throws Main\SystemException
+ */
+ public function updateBonusFieldsTypeInHl(): self
+ {
+ $hlblock = HL\HighloadBlockTable::query()
+ ->addSelect('*')
+ ->addFilter('NAME', 'LoyaltyProgramRetailCRM')
+ ->exec()
+ ->fetch();
+
+ if (isset($hlblock['ID'])) {
+ $ufObject = 'HLBLOCK_' . $hlblock['ID'];
+ $bonusCountField = CUserTypeEntity::GetList([], [
+ "ENTITY_ID" => $ufObject,
+ "FIELD_NAME" => 'UF_BONUS_COUNT',
+ ])->fetch();
+ $bonusTotalCountField = CUserTypeEntity::GetList([], [
+ "ENTITY_ID" => $ufObject,
+ "FIELD_NAME" => 'UF_BONUS_COUNT_TOTAL',
+ ])->fetch();
+
+ if ('integer' === $bonusCountField['USER_TYPE_ID'] && 'integer' === $bonusTotalCountField['USER_TYPE_ID']) {
+ $hlblockEntity = HL\HighloadBlockTable::compileEntity($hlblock);
+ $manager = $hlblockEntity->getDataClass();
+
+ $bonusHlblockData = $manager::query()
+ ->setSelect(['ID', 'UF_BONUS_COUNT', 'UF_BONUS_COUNT_TOTAL'])
+ ->setFilter(['!=UF_BONUS_COUNT' => 'NULL', 'LOGIC' => 'OR', '!=UF_BONUS_COUNT_TOTAL' => 'NULL'])
+ ->fetchAll();
+
+ $obUserField = new CUserTypeEntity();
+ $obUserField->Delete($bonusCountField['ID']);
+ $obUserField->Delete($bonusTotalCountField['ID']);
+
+ $newBonusFields = $this->getNewBonusHlFields($ufObject);
+
+ foreach ($newBonusFields as $newBonusField) {
+ $obUserField->Add($newBonusField);
+ }
+
+ foreach ($bonusHlblockData as $field) {
+ $manager::update($field['ID'], ['fields' => [
+ 'UF_BONUS_COUNT' => $field['UF_BONUS_COUNT'],
+ 'UF_BONUS_COUNT_TOTAL' => $field['UF_BONUS_COUNT_TOTAL'],
+ ],]);
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Обновление поля скидки по товару
+ *
+ * @throws Main\ArgumentException
+ * @throws Main\ObjectPropertyException
+ * @throws Main\SystemException
+ */
+ public function updateDefDiscountFieldTypeInHl(): self
+ {
+ $hlblock = HL\HighloadBlockTable::query()
+ ->addSelect('*')
+ ->addFilter('NAME', 'LoyaltyProgramRetailCRM')
+ ->exec()
+ ->fetch();
+
+ if (isset($hlblock['ID'])) {
+ $ufObject = 'HLBLOCK_' . $hlblock['ID'];
+ $defDiscountField = CUserTypeEntity::GetList([], [
+ "ENTITY_ID" => $ufObject,
+ "FIELD_NAME" => 'UF_DEF_DISCOUNT',
+ ])->fetch();
+
+ if (false !== $defDiscountField) {
+ $obUserField = new CUserTypeEntity();
+ $obUserField->Update($defDiscountField['ID'], [
+ 'SETTINGS' => [
+ 'PRECISION' => 2,
+ ],
+ ]);
+ }
+ }
+
+ return $this;
+ }
+
+ public function getNewBonusHlFields(string $ufObject): array
+ {
+ return [
+ 'UF_BONUS_COUNT' => [
+ 'ENTITY_ID' => $ufObject,
+ 'FIELD_NAME' => 'UF_BONUS_COUNT',
+ 'USER_TYPE_ID' => 'double',
+ 'MANDATORY' => 'N',
+ 'EDIT_FORM_LABEL' => [
+ 'ru' => 'Количество списываемых бонусов в позиции',
+ 'en' => 'Bonuses for writing off in position',
+ ],
+ 'LIST_COLUMN_LABEL' => [
+ 'ru' => 'Количество списываемых бонусов в позиции',
+ 'en' => 'Bonuses for writing off in position',
+ ],
+ 'LIST_FILTER_LABEL' => [
+ 'ru' => 'Количество списываемых бонусов в позиции',
+ 'en' => 'Bonuses for writing off in position',
+ ],
+ 'SETTINGS' => [
+ 'PRECISION' => 2,
+ ],
+ ],
+ 'UF_BONUS_COUNT_TOTAL' => [
+ 'ENTITY_ID' => $ufObject,
+ 'FIELD_NAME' => 'UF_BONUS_COUNT_TOTAL',
+ 'USER_TYPE_ID' => 'double',
+ 'MANDATORY' => 'N',
+ 'EDIT_FORM_LABEL' => [
+ 'ru' => 'Количество списываемых бонусов в заказе',
+ 'en' => 'Bonuses for writing off in order',
+ ],
+ 'LIST_COLUMN_LABEL' => [
+ 'ru' => 'Количество списываемых бонусов в заказе',
+ 'en' => 'Bonuses for writing off in order',
+ ],
+ 'LIST_FILTER_LABEL' => [
+ 'ru' => 'Количество списываемых бонусов в заказе',
+ 'en' => 'Bonuses for writing off in order',
+ ],
+ 'SETTINGS' => [
+ 'PRECISION' => 2,
+ ],
+ ],
+ ];
+ }
}
/**
@@ -924,13 +1086,9 @@ function update()
Loader::includeModule('highloadblock');
(new LoyaltyProgramUpdater())
- ->tryReplaceExportVars()
- ->addLoyaltyProgramEvents()
- ->CopyFiles()
- ->addLpUserFields()
- ->addAgreement()
- ->createLoyaltyHlBlock()
- ->addCustomersLoyaltyFields();
+ ->updateBonusInfoFieldForLp()
+ ->updateBonusFieldsTypeInHl()
+ ->updateDefDiscountFieldTypeInHl();
}
try {