Исправление работы со скидками (#258)
This commit is contained in:
parent
9b1e641b16
commit
96e5bce336
@ -1,3 +1,9 @@
|
||||
## 2022-06-28 v.6.1.0
|
||||
- Исправлены ошибки дублирования скидок при обмене данными
|
||||
- Скорректирована работа с общей скидкой по заказу, она более не переносится в скидку по товару в CRM
|
||||
- Скорректирована передача бонусов и персональных скидок
|
||||
- Исправлены типы полей скидок в HL-блоке программы лояльности
|
||||
|
||||
## 2022-06-17 v.6.0.6
|
||||
- Замена устаревшего jQuery метода
|
||||
|
||||
|
@ -81,6 +81,8 @@
|
||||
<field id="order_product.quantity" group="item">quantity</field>
|
||||
<field id="order_product.status" group="item">status</field>
|
||||
<field id="order_product.discount_total" group="item">discountTotal</field>
|
||||
<field id="order_product.bonuses_charge" group="item">bonusesCharge</field>
|
||||
<field id="order_product.bonuses_credit" group="item">bonusesCredit</field>
|
||||
|
||||
<field id="payments.status" group="payment">status</field>
|
||||
<field id="payments.type" group="payment">type</field>
|
||||
|
@ -564,6 +564,9 @@
|
||||
},
|
||||
"content": {
|
||||
"type": "string"
|
||||
},
|
||||
"privilegeType": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -1 +1,4 @@
|
||||
- Замена устаревшего jQuery метода
|
||||
- Исправлены ошибки задвоения скидок при обмене данными
|
||||
- Скорректирована работа с общей скидкой по заказу, она более не переносится в скидку по товару в CRM
|
||||
- Скорректирована передача бонусов и персональных скидок
|
||||
- Исправлены типы полей скидок в HL-блоке программы лояльности
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
$arModuleVersion = [
|
||||
'VERSION' => '6.0.6',
|
||||
'VERSION_DATE' => '2022-06-17 12:00:00'
|
||||
'VERSION' => '6.1.0',
|
||||
'VERSION_DATE' => '2022-06-28 11:00:00'
|
||||
];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//Если бонусов нет, но скидка по ПЛ есть
|
||||
|
@ -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';
|
||||
|
@ -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'] = 'Количество в корзине';
|
||||
|
@ -73,6 +73,16 @@ class OrderProduct extends AbstractApiModel
|
||||
*/
|
||||
public $quantity;
|
||||
|
||||
/**
|
||||
* Набор итоговых скидок на товарную позицию
|
||||
*
|
||||
* @var array $discounts
|
||||
*
|
||||
* @Mapping\Type("array<Intaro\RetailCrm\Model\Api\Order\OrderProductDiscountItem>")
|
||||
* @Mapping\SerializedName("discounts")
|
||||
*/
|
||||
public $discounts;
|
||||
|
||||
/**
|
||||
* Итоговая денежная скидка на единицу товара c учетом всех скидок на товар и заказ
|
||||
*
|
||||
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP version 7.1
|
||||
*
|
||||
* @category Integration
|
||||
* @package Intaro\RetailCrm\Model\Api
|
||||
* @author RetailCRM <integration@retailcrm.ru>
|
||||
* @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;
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user