Исправление работы со скидками (#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
|
## 2022-06-17 v.6.0.6
|
||||||
- Замена устаревшего jQuery метода
|
- Замена устаревшего jQuery метода
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@
|
|||||||
<field id="order_product.quantity" group="item">quantity</field>
|
<field id="order_product.quantity" group="item">quantity</field>
|
||||||
<field id="order_product.status" group="item">status</field>
|
<field id="order_product.status" group="item">status</field>
|
||||||
<field id="order_product.discount_total" group="item">discountTotal</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.status" group="payment">status</field>
|
||||||
<field id="payments.type" group="payment">type</field>
|
<field id="payments.type" group="payment">type</field>
|
||||||
|
@ -564,6 +564,9 @@
|
|||||||
},
|
},
|
||||||
"content": {
|
"content": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"privilegeType": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,10 @@ use Bitrix\Sale\Location\Search\Finder;
|
|||||||
use Bitrix\Sale\Order;
|
use Bitrix\Sale\Order;
|
||||||
use Bitrix\Sale\OrderUserProperties;
|
use Bitrix\Sale\OrderUserProperties;
|
||||||
use Bitrix\Sale\Payment;
|
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\ManagerService;
|
||||||
|
use Intaro\RetailCrm\Service\OrderLoyaltyDataService;
|
||||||
use Intaro\RetailCrm\Component\ConfigProvider;
|
use Intaro\RetailCrm\Component\ConfigProvider;
|
||||||
use Intaro\RetailCrm\Component\Constants;
|
use Intaro\RetailCrm\Component\Constants;
|
||||||
use Intaro\RetailCrm\Component\Handlers\EventsHandlers;
|
use Intaro\RetailCrm\Component\Handlers\EventsHandlers;
|
||||||
@ -251,6 +254,9 @@ class RetailCrmHistory
|
|||||||
|
|
||||||
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
$api = new RetailCrm\ApiClient(RetailcrmConfigProvider::getApiUrl(), RetailcrmConfigProvider::getApiKey());
|
||||||
|
|
||||||
|
/* @var OrderLoyaltyDataService $orderLoyaltyDataService */
|
||||||
|
$orderLoyaltyDataService = ServiceLocator::get(OrderLoyaltyDataService::class);
|
||||||
|
|
||||||
$historyFilter = array();
|
$historyFilter = array();
|
||||||
$historyStart = COption::GetOptionString(self::$MODULE_ID, self::$CRM_ORDER_HISTORY);
|
$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);
|
$optionDiscRound = COption::GetOptionString(self::$MODULE_ID, self::$CRM_DISCOUNT_ROUND, 0);
|
||||||
|
|
||||||
|
$editBasketInfo = [];
|
||||||
|
$deleteBasketInfo = [];
|
||||||
|
$bonusesChargeTotal = null;
|
||||||
|
|
||||||
foreach ($order['items'] as $product) {
|
foreach ($order['items'] as $product) {
|
||||||
if ($collectItems[$product['offer']['externalId']]['quantity']) {
|
if ($collectItems[$product['offer']['externalId']]['quantity']) {
|
||||||
$product['quantity'] = $collectItems[$product['offer']['externalId']]['quantity'];
|
$product['quantity'] = $collectItems[$product['offer']['externalId']]['quantity'];
|
||||||
@ -1029,13 +1039,12 @@ class RetailCrmHistory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($product['delete']) {
|
if ($product['delete'] && $collectItems[$product['offer']['externalId']]['quantity'] <= 0) {
|
||||||
if ($collectItems[$product['offer']['externalId']]['quantity'] <= 0) {
|
$deleteBasketInfo[] = $item->getBasketCode();
|
||||||
$item->delete();
|
$item->delete();
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ($product['quantity']) {
|
if ($product['quantity']) {
|
||||||
$item->setFieldNoDemand('QUANTITY', $product['quantity']);
|
$item->setFieldNoDemand('QUANTITY', $product['quantity']);
|
||||||
@ -1065,6 +1074,25 @@ class RetailCrmHistory
|
|||||||
|
|
||||||
$item->setField('PRICE', $price);
|
$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);
|
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)) {
|
if (!empty($newHistoryPayments)) {
|
||||||
foreach ($newOrder->getPaymentCollection() as $orderPayment) {
|
foreach ($newOrder->getPaymentCollection() as $orderPayment) {
|
||||||
if (array_key_exists($orderPayment->getField('XML_ID'), $newHistoryPayments)) {
|
if (array_key_exists($orderPayment->getField('XML_ID'), $newHistoryPayments)) {
|
||||||
|
@ -98,11 +98,6 @@ class RetailCrmOrder
|
|||||||
|
|
||||||
$order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arOrder['PERSON_TYPE_ID']];
|
$order['contragent']['contragentType'] = $arParams['optionsContragentType'][$arOrder['PERSON_TYPE_ID']];
|
||||||
|
|
||||||
if ($methodApi === 'ordersEdit') {
|
|
||||||
$order['discountManualAmount'] = 0;
|
|
||||||
$order['discountManualPercent'] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//fields
|
//fields
|
||||||
foreach ($arOrder['PROPS']['properties'] as $prop) {
|
foreach ($arOrder['PROPS']['properties'] as $prop) {
|
||||||
if (!empty($arParams['optionsLegalDetails'])
|
if (!empty($arParams['optionsLegalDetails'])
|
||||||
@ -284,7 +279,7 @@ class RetailCrmOrder
|
|||||||
) {
|
) {
|
||||||
/** @var LoyaltyService $service */
|
/** @var LoyaltyService $service */
|
||||||
$service = ServiceLocator::get(LoyaltyService::class);
|
$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']) {
|
} elseif ($product['BASE_PRICE'] >= $product['PRICE']) {
|
||||||
$item['discountManualAmount'] = self::getDiscountManualAmount($product);
|
$item['discountManualAmount'] = self::getDiscountManualAmount($product);
|
||||||
$item['initialPrice'] = (double) $product['BASE_PRICE'];
|
$item['initialPrice'] = (double) $product['BASE_PRICE'];
|
||||||
@ -355,6 +350,14 @@ class RetailCrmOrder
|
|||||||
$order['payments'] = $payments;
|
$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
|
//send
|
||||||
if (function_exists('retailCrmBeforeOrderSend')) {
|
if (function_exists('retailCrmBeforeOrderSend')) {
|
||||||
$newResOrder = retailCrmBeforeOrderSend($order, $arOrder);
|
$newResOrder = retailCrmBeforeOrderSend($order, $arOrder);
|
||||||
@ -380,10 +383,6 @@ class RetailCrmOrder
|
|||||||
|
|
||||||
Logger::getInstance()->write($order, 'orderSend');
|
Logger::getInstance()->write($order, 'orderSend');
|
||||||
|
|
||||||
if (ConfigProvider::getLoyaltyProgramStatus() === 'Y' && LoyaltyAccountService::getLoyaltyPersonalStatus()) {
|
|
||||||
$order['privilegeType'] = 'loyalty_level';
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var \Intaro\RetailCrm\Component\ApiClient\ClientAdapter $client */
|
/** @var \Intaro\RetailCrm\Component\ApiClient\ClientAdapter $client */
|
||||||
$client = ClientFactory::createClientAdapter();
|
$client = ClientFactory::createClientAdapter();
|
||||||
|
|
||||||
|
@ -1 +1,4 @@
|
|||||||
- Замена устаревшего jQuery метода
|
- Исправлены ошибки задвоения скидок при обмене данными
|
||||||
|
- Скорректирована работа с общей скидкой по заказу, она более не переносится в скидку по товару в CRM
|
||||||
|
- Скорректирована передача бонусов и персональных скидок
|
||||||
|
- Исправлены типы полей скидок в HL-блоке программы лояльности
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$arModuleVersion = [
|
$arModuleVersion = [
|
||||||
'VERSION' => '6.0.6',
|
'VERSION' => '6.1.0',
|
||||||
'VERSION_DATE' => '2022-06-17 12:00:00'
|
'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\Api\Response\Order\Loyalty\OrderLoyaltyApplyResponse;
|
||||||
use Intaro\RetailCrm\Model\Bitrix\OrderLoyaltyData;
|
use Intaro\RetailCrm\Model\Bitrix\OrderLoyaltyData;
|
||||||
use Intaro\RetailCrm\Service\CookieService;
|
use Intaro\RetailCrm\Service\CookieService;
|
||||||
use Intaro\RetailCrm\Service\LoyaltyService;
|
|
||||||
use Intaro\RetailCrm\Service\OrderLoyaltyDataService;
|
|
||||||
use Logger;
|
use Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,9 +48,7 @@ class LoyaltyDataBuilder implements BuilderInterface
|
|||||||
/** @var OrderLoyaltyData[] $data */
|
/** @var OrderLoyaltyData[] $data */
|
||||||
private $data;
|
private $data;
|
||||||
|
|
||||||
/**
|
/** @var float|null */
|
||||||
* @var float
|
|
||||||
*/
|
|
||||||
private $bonusCountTotal;
|
private $bonusCountTotal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,13 +60,19 @@ class LoyaltyDataBuilder implements BuilderInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param int[] $basketItemIds
|
||||||
|
*
|
||||||
* @return \Intaro\RetailCrm\Component\Builder\BuilderInterface
|
* @return \Intaro\RetailCrm\Component\Builder\BuilderInterface
|
||||||
*/
|
*/
|
||||||
public function build(): BuilderInterface
|
public function build(array $basketItemIds = []): BuilderInterface
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
/** @var BasketItemBase $basketItem */
|
/** @var BasketItemBase $basketItem */
|
||||||
foreach ($this->order->getBasket() as $key => $basketItem) {
|
foreach ($this->order->getBasket() as $key => $basketItem) {
|
||||||
|
if (!empty($basketItemIds) && !in_array($basketItem->getId(), $basketItemIds)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$loyaltyHl = new OrderLoyaltyData();
|
$loyaltyHl = new OrderLoyaltyData();
|
||||||
$loyaltyHl->orderId = $this->order->getId();
|
$loyaltyHl->orderId = $this->order->getId();
|
||||||
$loyaltyHl->itemId= $basketItem->getProductId();
|
$loyaltyHl->itemId= $basketItem->getProductId();
|
||||||
@ -82,6 +84,9 @@ class LoyaltyDataBuilder implements BuilderInterface
|
|||||||
$loyaltyHl->defaultDiscount
|
$loyaltyHl->defaultDiscount
|
||||||
= $this->calculateItemsInput[$loyaltyHl->basketItemPositionId]['SHOP_ITEM_DISCOUNT'] ?? null;
|
= $this->calculateItemsInput[$loyaltyHl->basketItemPositionId]['SHOP_ITEM_DISCOUNT'] ?? null;
|
||||||
|
|
||||||
|
$loyaltyHl->bonusCount
|
||||||
|
= $this->calculateItemsInput[$loyaltyHl->basketItemPositionId]['BONUSES_CHARGE'] ?? null;
|
||||||
|
|
||||||
$this->addBonusInfo($loyaltyHl, $key);
|
$this->addBonusInfo($loyaltyHl, $key);
|
||||||
|
|
||||||
$this->data[] = $loyaltyHl;
|
$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;
|
$this->bonusCountTotal = $bonusCountTotal;
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ class EventsHandlers
|
|||||||
? json_decode(htmlspecialchars_decode($_POST['calculate-items-input']), true)
|
? json_decode(htmlspecialchars_decode($_POST['calculate-items-input']), true)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
if ($isNewOrder && $isLoyaltyOn) {
|
if ($isNewOrder && $isLoyaltyOn && ($isDataForLoyaltyDiscount || $isBonusInput)) {
|
||||||
self::$disableSaleHandler = true;
|
self::$disableSaleHandler = true;
|
||||||
|
|
||||||
$hlInfoBuilder = new LoyaltyDataBuilder();
|
$hlInfoBuilder = new LoyaltyDataBuilder();
|
||||||
@ -204,7 +204,7 @@ class EventsHandlers
|
|||||||
|
|
||||||
$hlInfoBuilder->setApplyResponse($applyBonusResponse);
|
$hlInfoBuilder->setApplyResponse($applyBonusResponse);
|
||||||
$loyaltyBonusMsg = $bonusFloat;
|
$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_DEF_DISCOUNT'] = 'Shop discount';
|
||||||
$MESS ['UF_ITEM_POS_ID'] = 'Basket position ID';
|
$MESS ['UF_ITEM_POS_ID'] = 'Basket position ID';
|
||||||
$MESS ['UF_CHECK_ID'] = 'Verification code 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_DISCOUNT_INFO'] = 'Personal discount';
|
||||||
$MESS ['LP_ORDER_GROUP_NAME'] = 'Loyalty program';
|
$MESS ['LP_ORDER_GROUP_NAME'] = 'Loyalty program';
|
||||||
$MESS ['UF_QUANTITY'] = 'Quantity in the basket';
|
$MESS ['UF_QUANTITY'] = 'Quantity in the basket';
|
||||||
|
@ -4,7 +4,7 @@ $MESS ['UF_ITEM_ID'] = 'ID товара';
|
|||||||
$MESS ['UF_DEF_DISCOUNT'] = 'Скидка магазина';
|
$MESS ['UF_DEF_DISCOUNT'] = 'Скидка магазина';
|
||||||
$MESS ['UF_ITEM_POS_ID'] = 'ID позиции в корзине';
|
$MESS ['UF_ITEM_POS_ID'] = 'ID позиции в корзине';
|
||||||
$MESS ['UF_CHECK_ID'] = 'ID проверочного кода';
|
$MESS ['UF_CHECK_ID'] = 'ID проверочного кода';
|
||||||
$MESS ['LP_BONUS_INFO'] = 'Бонусов начислено';
|
$MESS ['LP_BONUS_INFO'] = 'Бонусов списано';
|
||||||
$MESS ['LP_DISCOUNT_INFO'] = 'Персональная скидка';
|
$MESS ['LP_DISCOUNT_INFO'] = 'Персональная скидка';
|
||||||
$MESS ['LP_ORDER_GROUP_NAME'] = 'Программа лояльности';
|
$MESS ['LP_ORDER_GROUP_NAME'] = 'Программа лояльности';
|
||||||
$MESS ['UF_QUANTITY'] = 'Количество в корзине';
|
$MESS ['UF_QUANTITY'] = 'Количество в корзине';
|
||||||
|
@ -73,6 +73,16 @@ class OrderProduct extends AbstractApiModel
|
|||||||
*/
|
*/
|
||||||
public $quantity;
|
public $quantity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Набор итоговых скидок на товарную позицию
|
||||||
|
*
|
||||||
|
* @var array $discounts
|
||||||
|
*
|
||||||
|
* @Mapping\Type("array<Intaro\RetailCrm\Model\Api\Order\OrderProductDiscountItem>")
|
||||||
|
* @Mapping\SerializedName("discounts")
|
||||||
|
*/
|
||||||
|
public $discounts;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Итоговая денежная скидка на единицу товара c учетом всех скидок на товар и заказ
|
* Итоговая денежная скидка на единицу товара 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\Type("integer")
|
||||||
* @Mapping\SerializedName("UF_QUANTITY")
|
* @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")
|
* @Mapping\SerializedName("UF_BONUS_COUNT")
|
||||||
*/
|
*/
|
||||||
public $bonusCount;
|
public $bonusCount;
|
||||||
@ -129,9 +129,9 @@ class OrderLoyaltyData
|
|||||||
/**
|
/**
|
||||||
* Количество списываемых бонусов по всему заказу
|
* Количество списываемых бонусов по всему заказу
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var float
|
||||||
*
|
*
|
||||||
* @Mapping\Type("integer")
|
* @Mapping\Type("float")
|
||||||
* @Mapping\SerializedName("UF_BONUS_COUNT_TOTAL")
|
* @Mapping\SerializedName("UF_BONUS_COUNT_TOTAL")
|
||||||
*/
|
*/
|
||||||
public $bonusCountTotal;
|
public $bonusCountTotal;
|
||||||
|
@ -97,7 +97,10 @@ class OrderLoyaltyDataRepository extends AbstractRepository
|
|||||||
->where('UF_ITEM_POS_ID', '=', $positionId)
|
->where('UF_ITEM_POS_ID', '=', $positionId)
|
||||||
->fetch();
|
->fetch();
|
||||||
|
|
||||||
/** @var OrderLoyaltyData $result */
|
if (false === $product) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Deserializer::deserializeArray($product, OrderLoyaltyData::class);
|
return Deserializer::deserializeArray($product, OrderLoyaltyData::class);
|
||||||
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
|
} catch (ObjectPropertyException | ArgumentException | SystemException $exception) {
|
||||||
$this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
|
$this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
|
||||||
@ -166,6 +169,12 @@ class OrderLoyaltyDataRepository extends AbstractRepository
|
|||||||
|
|
||||||
unset($productAr['ID']);
|
unset($productAr['ID']);
|
||||||
|
|
||||||
|
foreach ($productAr as $key => $value) {
|
||||||
|
if (null === $value) {
|
||||||
|
unset($productAr[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$result = $this->dataManager::update($position->id, $productAr);
|
$result = $this->dataManager::update($position->id, $productAr);
|
||||||
|
|
||||||
if ($result->isSuccess()) {
|
if ($result->isSuccess()) {
|
||||||
@ -179,6 +188,31 @@ class OrderLoyaltyDataRepository extends AbstractRepository
|
|||||||
return false;
|
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
|
* @param int $externalId
|
||||||
* @return float|null
|
* @return float|null
|
||||||
@ -200,7 +234,6 @@ class OrderLoyaltyDataRepository extends AbstractRepository
|
|||||||
if ($result !== false) {
|
if ($result !== false) {
|
||||||
return (float) $result['UF_DEF_DISCOUNT'];
|
return (float) $result['UF_DEF_DISCOUNT'];
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (SystemException | Exception $exception) {
|
} catch (SystemException | Exception $exception) {
|
||||||
$this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
|
$this->logger->write($exception->getMessage(), Constants::LOYALTY_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,17 @@ class OrderLoyaltyDataService
|
|||||||
*/
|
*/
|
||||||
public static function createLoyaltyHlBlock(): void
|
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([
|
$result = HL\HighloadBlockTable::add([
|
||||||
'NAME' => Constants::HL_LOYALTY_CODE,
|
'NAME' => Constants::HL_LOYALTY_CODE,
|
||||||
'TABLE_NAME' => Constants::HL_LOYALTY_TABLE_NAME,
|
'TABLE_NAME' => Constants::HL_LOYALTY_TABLE_NAME,
|
||||||
@ -170,18 +181,15 @@ class OrderLoyaltyDataService
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$repository = new OrderLoyaltyDataRepository();
|
|
||||||
$bitrixItems = $repository->getProductsByOrderId($orderId);
|
|
||||||
$loyaltyDiscount = 0;
|
$loyaltyDiscount = 0;
|
||||||
|
|
||||||
/** @var OrderProduct $item */
|
/** @var OrderProduct $item */
|
||||||
foreach ($response->order->items as $item) {
|
foreach ($response->order->items as $item) {
|
||||||
/** @var CodeValueModel $itemBitrixId */
|
foreach ($item->discounts as $discount) {
|
||||||
$itemBitrixId = $item->externalIds[0];
|
if (in_array($discount->type, ['personal', 'loyalty_level'])) {
|
||||||
/** @var OrderLoyaltyData $bitrixItem */
|
$loyaltyDiscount += $discount->amount;
|
||||||
$bitrixItem = $bitrixItems[$itemBitrixId->value];
|
}
|
||||||
|
}
|
||||||
$loyaltyDiscount += ($item->discountTotal - $bitrixItem->defaultDiscount) * $item->quantity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->saveBonusAndDiscToOrderProps(
|
$this->saveBonusAndDiscToOrderProps(
|
||||||
@ -264,9 +272,35 @@ class OrderLoyaltyDataService
|
|||||||
$repository = new OrderLoyaltyDataRepository();
|
$repository = new OrderLoyaltyDataRepository();
|
||||||
|
|
||||||
foreach ($loyaltyHls as $loyaltyData) {
|
foreach ($loyaltyHls as $loyaltyData) {
|
||||||
|
$positionLpData = $repository->getOrderLpDataByPosition($loyaltyData->basketItemPositionId);
|
||||||
|
|
||||||
|
if (null !== $positionLpData) {
|
||||||
|
$loyaltyData->id = $positionLpData->id;
|
||||||
|
$repository->edit($loyaltyData);
|
||||||
|
} else {
|
||||||
$repository->add($loyaltyData);
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $personId
|
* @param $personId
|
||||||
@ -465,6 +499,9 @@ class OrderLoyaltyDataService
|
|||||||
'ru' => Loc::GetMessage('UF_DEF_DISCOUNT', null, 'ru'),
|
'ru' => Loc::GetMessage('UF_DEF_DISCOUNT', null, 'ru'),
|
||||||
'en' => Loc::GetMessage('UF_DEF_DISCOUNT', null, 'en'),
|
'en' => Loc::GetMessage('UF_DEF_DISCOUNT', null, 'en'),
|
||||||
],
|
],
|
||||||
|
'SETTINGS' => [
|
||||||
|
'PRECISION' => 2,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
'UF_CHECK_ID' => [
|
'UF_CHECK_ID' => [
|
||||||
'ENTITY_ID' => $ufObject,
|
'ENTITY_ID' => $ufObject,
|
||||||
@ -537,11 +574,14 @@ class OrderLoyaltyDataService
|
|||||||
'ru' => Loc::GetMessage('UF_BONUS_COUNT', null, 'ru'),
|
'ru' => Loc::GetMessage('UF_BONUS_COUNT', null, 'ru'),
|
||||||
'en' => Loc::GetMessage('UF_BONUS_COUNT', null, 'en'),
|
'en' => Loc::GetMessage('UF_BONUS_COUNT', null, 'en'),
|
||||||
],
|
],
|
||||||
|
'SETTINGS' => [
|
||||||
|
'PRECISION' => 2,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
'UF_BONUS_COUNT_TOTAL' => [
|
'UF_BONUS_COUNT_TOTAL' => [
|
||||||
'ENTITY_ID' => $ufObject,
|
'ENTITY_ID' => $ufObject,
|
||||||
'FIELD_NAME' => 'UF_BONUS_COUNT_TOTAL',
|
'FIELD_NAME' => 'UF_BONUS_COUNT_TOTAL',
|
||||||
'USER_TYPE_ID' => 'integer',
|
'USER_TYPE_ID' => 'double',
|
||||||
'MANDATORY' => 'N',
|
'MANDATORY' => 'N',
|
||||||
'EDIT_FORM_LABEL' => [
|
'EDIT_FORM_LABEL' => [
|
||||||
'ru' => Loc::GetMessage('UF_BONUS_COUNT_TOTAL', null, 'ru'),
|
'ru' => Loc::GetMessage('UF_BONUS_COUNT_TOTAL', null, 'ru'),
|
||||||
@ -555,6 +595,9 @@ class OrderLoyaltyDataService
|
|||||||
'ru' => Loc::GetMessage('UF_BONUS_COUNT_TOTAL', null, 'ru'),
|
'ru' => Loc::GetMessage('UF_BONUS_COUNT_TOTAL', null, 'ru'),
|
||||||
'en' => Loc::GetMessage('UF_BONUS_COUNT_TOTAL', null, 'en'),
|
'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');
|
Loader::includeModule('highloadblock');
|
||||||
|
|
||||||
(new LoyaltyProgramUpdater())
|
(new LoyaltyProgramUpdater())
|
||||||
->tryReplaceExportVars()
|
->updateBonusInfoFieldForLp()
|
||||||
->addLoyaltyProgramEvents()
|
->updateBonusFieldsTypeInHl()
|
||||||
->CopyFiles()
|
->updateDefDiscountFieldTypeInHl();
|
||||||
->addLpUserFields()
|
|
||||||
->addAgreement()
|
|
||||||
->createLoyaltyHlBlock()
|
|
||||||
->addCustomersLoyaltyFields();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user