1
0
Fork 0
mirror of synced 2025-04-20 01:21:01 +00:00

Lp sale arder ajax

This commit is contained in:
Alex Lushpai 2020-10-23 10:20:12 +03:00 committed by GitHub
commit 6f0f3723e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 335 additions and 39 deletions

View file

@ -1,6 +1,13 @@
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die();
}
use Bitrix\Main\ArgumentException;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\SystemException;
use Intaro\RetailCrm\Component\Constants;
use Intaro\RetailCrm\Repository\PaySystemActionRepository;
/**
* @var array $arParams
@ -8,13 +15,59 @@ use Bitrix\Main\Localization\Loc;
* @var $APPLICATION CMain
*/
if ($arParams["SET_TITLE"] == "Y")
{
$APPLICATION->SetTitle(Loc::getMessage("SOA_ORDER_COMPLETE"));
if ($arParams["SET_TITLE"] == "Y") {
$APPLICATION->SetTitle(Loc::getMessage("SOA_ORDER_COMPLETE"));
}
?>
<? if (!empty($arResult["ORDER"])): ?>
<?php if (!empty($arResult["ORDER"])): ?>
<?php
$order = Bitrix\Sale\Order::load($arResult["ORDER"]['ID']);
$paymentCollection = $order->getPaymentCollection();
/** @var \Bitrix\Sale\Payment $payment */
foreach ($paymentCollection as $payment) {
$isPaid = $payment->isPaid();
$checkId = $payment->getField('COMMENTS');
try {
$paySystemAction = PaySystemActionRepository::getFirstByWhere(
['*'],
[
[
'ID',
'=',
$payment->getField('PAY_SYSTEM_ID'),
],
]
);
} catch (ObjectPropertyException | ArgumentException | SystemException $e) {
AddMessage2Log($e->getMessage());
}
//если есть бонусная оплата и она не оплачена, то отрисовываем форму введения кода верификации
$isPaid = false;//TODO заглушка - убрать после теста
if (isset($paySystemAction)
&& !$isPaid
&& !empty($checkId)
&& $paySystemAction->get('CODE') === Constants::BONUS_PAYMENT_CODE
) {
?>
<div id="orderConfirm">
<b><?=GetMessage('CONFIRM_MESSAGE')?></b><br>
<div id="orderVerificationCodeBlock">
<b><?=GetMessage('SEND_VERIFICATION_CODE')?></b><br>
<label for="orderVerificationCode"></label>
<input type="text" id="orderVerificationCode" placeholder="<?=GetMessage('VERIFICATION_CODE')?>">
<input type="button" onclick="sendVerificationCode(<?=$arResult["ORDER"]['ID']?>, '<?=$checkId?>')" value="<?=GetMessage('SEND')?>"/>
</div>
<div id="msg"></div>
</div>
<br><br>
<?php
}
}
?>
<table class="sale_order_full_table">
<tr>
@ -23,11 +76,6 @@ if ($arParams["SET_TITLE"] == "Y")
"#ORDER_DATE#" => $arResult["ORDER"]["DATE_INSERT"]->toUserTime()->format('d.m.Y H:i'),
"#ORDER_ID#" => $arResult["ORDER"]["ACCOUNT_NUMBER"]
))?>
<? if (!empty($arResult['ORDER']["PAYMENT_ID"])): ?>
<?=Loc::getMessage("SOA_PAYMENT_SUC", array(
"#PAYMENT_ID#" => $arResult['PAYMENT'][$arResult['ORDER']["PAYMENT_ID"]]['ACCOUNT_NUMBER']
))?>
<? endif ?>
<? if ($arParams['NO_PERSONAL'] !== 'Y'): ?>
<br /><br />
<?=Loc::getMessage('SOA_ORDER_SUC1', ['#LINK#' => $arParams['PATH_TO_PERSONAL']])?>
@ -128,4 +176,4 @@ if ($arParams["SET_TITLE"] == "Y")
</tr>
</table>
<? endif ?>
<? endif ?>

View file

@ -142,4 +142,6 @@ $MESS["HOW_MANY_BONUSES_TO_SPEND"] = 'Сколько бонусов потрат
$MESS["BONUS_TOTAL"] = 'Всего бонусов:';
$MESS["YOU_CAN_SPEND"] = 'Можно потратить:';
$MESS["CALCULATION_ERROR"] = 'Не удалось рассчитать количество доступных бонусов.';
$MESS["CONFIRM_MESSAGE"] = 'Для завершения процедуры списания бонусов, введите код верификации';
$MESS["SEND"] = 'Отправить';

View file

@ -96,6 +96,9 @@ BX.namespace('BX.Sale.OrderAjaxComponent');
init: function(parameters) {
this.initializePrimaryFields();
this.willBeCredited = parameters.willBeCredited || 0;
this.bonusCurrency = parameters.bonusCurrency || '# руб.';
this.result = parameters.result || {};
this.prepareLocations(parameters.locations);
this.params = parameters.params || {};
@ -131,6 +134,7 @@ BX.namespace('BX.Sale.OrderAjaxComponent');
this.propsHiddenBlockNode = BX(parameters.propsBlockId + '-hidden');
this.loyaltyStatus = parameters.loyaltyStatus;
this.personalLoyaltyStatus = parameters.personalLoyaltyStatus;
if (this.result.SHOW_AUTH) {
this.authBlockNode.style.display = '';
@ -8304,10 +8308,19 @@ BX.namespace('BX.Sale.OrderAjaxComponent');
this.totalInfoBlockNode.appendChild(this.createTotalUnit(discText + ':', total.DISCOUNT_PRICE_FORMATED, {highlighted: true}));
}
//добавление строки с бонусами
if (this.result.TOTAL.BONUS_PAYMENT !== undefined && this.result.TOTAL.BONUS_PAYMENT > 0) {
const bonusPayment = this.result.TOTAL.BONUS_PAYMENT.toString();
this.totalInfoBlockNode.appendChild(this.createTotalUnit('Бонусы:', bonusPayment, {highlighted: true}));
//проверяем включена ли ПЛ и участвует ли в ней данный пользователь
if (this.personalLoyaltyStatus === '1' && this.loyaltyStatus === 'Y') {
//добавление строки с бонусами
if (this.result.TOTAL.BONUS_PAYMENT !== undefined && this.result.TOTAL.BONUS_PAYMENT > 0) {
let bonusPayment = this.bonusCurrency
.replace('&#8381;', '₽')
.replace('&euro;', '€')
.replace('&#8372;', '¥')
.replace('#', this.result.TOTAL.BONUS_PAYMENT.toString());
this.totalInfoBlockNode.appendChild(this.createTotalUnit('Бонусная скидка:', bonusPayment));
}
this.totalInfoBlockNode.appendChild(this.createTotalUnit('Будет начислено бонусов:', this.willBeCredited, {highlighted: true}));
}
if (this.options.showPayedFromInnerBudget)

View file

@ -1,20 +1,24 @@
<?php
use Bitrix\Currency\CurrencyLangTable;
use Bitrix\Main\Loader;
use Intaro\RetailCrm\Component\ConfigProvider;
use Intaro\RetailCrm\Service\LoyaltyService;
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die();
}
/**
* @var array $arParams
* @var array $arResult
* @var array $arParams
* @var array $arResult
* @var SaleOrderAjax $component
*/
Loader::includeModule('intaro.retailcrm');
$arResult['LOYALTY_STATUS'] = ConfigProvider::getLoyaltyProgramStatus();
$arResult['PERSONAL_LOYALTY_STATUS'] = LoyaltyService::getLoyaltyPersonalStatus();
//TODO Закомментированно до появления реального апи
//TODO добавить проверку на участие покупателя в программе лояльности (таска 68813)
@ -25,10 +29,22 @@ if ($calculate->success) {
$arResult['AVAILABLE_BONUSES'] = $calculate->order->bonusesChargeTotal;
$arResult['TOTAL_BONUSES_COUNT'] = $calculate->order->loyaltyAccount->amount;
$arResult['LP_CALCULATE_SUCCESS'] = $calculate->success;
$arResult['WILL_BE_CREDITED'] = $calculate->order->bonusesCreditTotal;
}*/
//TODO убрать заглушку после появления реальных методов
$arResult['LP_CALCULATE_SUCCESS'] = true;
$arResult['AVAILABLE_BONUSES'] = 300;
$arResult['TOTAL_BONUSES_COUNT'] = 600;
$component = $this->__component;
$arResult['AVAILABLE_BONUSES'] = 300; //доступно
$arResult['TOTAL_BONUSES_COUNT'] = 600; //всего на счету
$arResult['WILL_BE_CREDITED'] = 245; //будет начислено
$component = $this->__component;
$component::scaleImages($arResult['JS_DATA'], $arParams['SERVICES_IMAGES_SCALING']);
$currency = CurrencyLangTable::query()
->setSelect(['FORMAT_STRING'])
->where([
['CURRENCY', '=', RetailcrmConfigProvider::getCurrencyOrDefault()],
['LID', '=', 'LANGUAGE_ID'],
])
->fetch();
$arResult['BONUS_CURRENCY'] = $currency['FORMAT_STRING'];

View file

@ -20,3 +20,32 @@ $(document).ready(function() {
$('#bonus-input').on('keydown', _.debounce(makeAjaxRequest, 1000));
});
function sendVerificationCode(orderId, checkId) {
const verificationCode = $('#orderVerificationCode').val();
BX.ajax.runAction('intaro:retailcrm.api.loyalty.order.sendVerificationCode',
{
data: {
sessid: BX.bitrix_sessid(),
verificationCode: verificationCode,
orderId: orderId,
checkId: checkId
}
}
).then(
function(response) {
if (response.data.status === 'error' && response.data.msg !== undefined) {
const msg = $('#msg');
msg.text(response.data.msg);
msg.css('color', response.data.msgColor);
}
if (response.data.status === 'success') {
const msgBlock = $('#orderConfirm');
msgBlock.text(response.data.msg);
msgBlock.css('color', response.data.msgColor);
}
}
)
}

View file

@ -425,7 +425,7 @@ if (strlen($request->get('ORDER_ID')) > 0) {
<? endif ?>
<!-- INTARO BONUS BLOCK -->
<? if ($arResult['LOYALTY_STATUS'] === 'Y' ): ?>
<? if ($arResult['LOYALTY_STATUS'] === 'Y' && $arResult['PERSONAL_LOYALTY_STATUS'] === true): ?>
<div id="bx-soa-intaro" data-visited="true" class="bx-soa-section bx-selected">
<div class="bx-soa-section-title-container">
<h2 class="bx-soa-section-title col-sm-9">
@ -572,6 +572,8 @@ if (strlen($request->get('ORDER_ID')) > 0) {
siteID: '<?=CUtil::JSEscape($component->getSiteId())?>',
ajaxUrl: '<?=CUtil::JSEscape($component->getPath() . '/ajax.php')?>',
templateFolder: '<?=CUtil::JSEscape($templateFolder)?>',
willBeCredited: '<?=$arResult['WILL_BE_CREDITED']?>',
bonusCurrency: '<?=$arResult['BONUS_CURRENCY']?>',
propertyValidation: true,
showWarnings: true,
pickUpMap: {
@ -592,16 +594,17 @@ if (strlen($request->get('ORDER_ID')) > 0) {
zoom: 7
}
},
orderBlockId: 'bx-soa-order',
authBlockId: 'bx-soa-auth',
basketBlockId: 'bx-soa-basket',
regionBlockId: 'bx-soa-region',
paySystemBlockId: 'bx-soa-paysystem',
deliveryBlockId: 'bx-soa-delivery',
pickUpBlockId: 'bx-soa-pickup',
propsBlockId: 'bx-soa-properties',
totalBlockId: 'bx-soa-total',
loyaltyStatus: '<?=$arResult['LOYALTY_STATUS']?>'
orderBlockId: 'bx-soa-order',
authBlockId: 'bx-soa-auth',
basketBlockId: 'bx-soa-basket',
regionBlockId: 'bx-soa-region',
paySystemBlockId: 'bx-soa-paysystem',
deliveryBlockId: 'bx-soa-delivery',
pickUpBlockId: 'bx-soa-pickup',
propsBlockId: 'bx-soa-properties',
totalBlockId: 'bx-soa-total',
loyaltyStatus: '<?=$arResult['LOYALTY_STATUS']?>',
personalLoyaltyStatus: '<?=$arResult['PERSONAL_LOYALTY_STATUS']?>'
});
</script>
<script>

View file

@ -71,4 +71,5 @@ class Constants
public const CORPORATE_CONTRAGENT_TYPE = 'legal-entity';
public const LOYALTY_PROGRAM_TOGGLE = 'loyalty_program_toggle';
public const CLIENT_ID = 'client_id';
public const BONUS_PAYMENT_CODE = 'INTARO_BONUS';
}

View file

@ -19,11 +19,11 @@ use Bitrix\Main\Event;
use Bitrix\Main\HttpRequest;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\SystemException;
use Bitrix\Sale\Internals\PaymentTable;
use Bitrix\Sale\Order;
use Bitrix\Sale\PaySystem\Manager;
use Exception;
use Intaro\RetailCrm\Component\ConfigProvider;
use Intaro\RetailCrm\Component\Constants;
use Intaro\RetailCrm\Repository\PaySystemActionRepository;
use Intaro\RetailCrm\Service\LoyaltyService;
@ -104,7 +104,7 @@ class EventsHandlers
}
/**
* Обработчик события, вызываемого при обновлении заказа
* Обработчик события, вызываемого при обновлении еще не сохраненного заказа
*
* @param \Bitrix\Sale\Order $order
* @param array $arUserResult
@ -155,7 +155,9 @@ class EventsHandlers
$response = $service->sendBonusPayment($orderId, $bonusCount);
//TODO - заглушка до появления api на стороне CRM. После появления реального апи - убрать следующую строку
$response->success=true;
$response->success = true;
$response->verification->checkId = 'проверочный код.';
//конец заглушки
if ($response->success) {
try {
@ -163,11 +165,34 @@ class EventsHandlers
$paymentCollection = $order->getPaymentCollection();
if ($bonusPaySystem !== null) {
if (count($paymentCollection) === 1) {
/** @var \Bitrix\Sale\Payment $payment */
foreach ($paymentCollection as $payment){
$oldSum = $payment->getField('SUM');
$payment->setField('SUM', $oldSum - $bonusCount);
break;
}
}
$service = Manager::getObjectById($bonusPaySystem->getId());
$newPayment = $paymentCollection->createItem($service);
$newPayment->setField('SUM', $bonusCount);
$newPayment->setPaid('Y');
//если верификация необходима, но не пройдена
if (isset($response->verification, $response->verification->checkId)
&& !isset($response->verification->verifiedAt)
) {
$newPayment->setPaid('N');
$newPayment->setField('COMMENTS', $response->verification->checkId);
}
//если верификация не нужна
if (!isset($response->verification)) {
$newPayment->setPaid('Y');
}
$order->save();
}
} catch (ObjectPropertyException | ArgumentException | SystemException | Exception $e) {

View file

@ -85,7 +85,7 @@ class AdminPanel extends Controller
}
return [
'status' => $status,
'status' => isset($status) ? $status : false,
];
}
}

View file

@ -0,0 +1,137 @@
<?php
/**
* PHP version 7.1
*
* @category Integration
* @package Intaro\RetailCrm\Controller\Loyalty
* @author retailCRM <integration@retailcrm.ru>
* @license MIT
* @link http://retailcrm.ru
* @see http://retailcrm.ru/docs
*/
namespace Intaro\RetailCrm\Controller\Loyalty;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ArgumentNullException;
use Bitrix\Main\Engine\ActionFilter\Authentication;
use Bitrix\Main\Engine\ActionFilter\HttpMethod;
use Bitrix\Main\Engine\Controller;
use Bitrix\Main\Loader;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\Request;
use Bitrix\Main\SystemException;
use Exception;
use Intaro\RetailCrm\Component\Constants;
use Intaro\RetailCrm\Component\ServiceLocator;
use Intaro\RetailCrm\Repository\PaySystemActionRepository;
use Intaro\RetailCrm\Service\UserVerificationService;
use Bitrix\Sale\Order as BitrixOrder;
/**
* Class AdminPanel
* @package Intaro\RetailCrm\Controller\Loyalty
*/
class Order extends Controller
{
/** @var UserVerificationService */
private $service;
/**
* AdminPanel constructor.
*
* @param \Bitrix\Main\Request|null $request
*/
public function __construct(Request $request = null)
{
$this->service = ServiceLocator::get(UserVerificationService::class);
parent::__construct($request);
}
/**
* @param string $verificationCode
* @param int $orderId
* @param string $checkId
* @return array
*/
public function sendVerificationCodeAction(string $verificationCode, int $orderId, string $checkId): array
{
$response = $this->service->confirmVerification($verificationCode, $checkId);
if ($response !== null
&& $response->success
&& isset($response->verification->verifiedAt)
&& !empty($response->verification->verifiedAt)
) {
try {
Loader::includeModule('sale');
$order = BitrixOrder::load($orderId);
if (!$order) {
AddMessage2Log('Ошибка списания бонусов (не удалось получить объект Order) по заказу №' . $orderId);
return [
'status' => 'error',
'msg' => 'Ошибка',
'msgColor' => 'brown',
];
}
$paymentCollection = $order->getPaymentCollection();
/** @var \Bitrix\Sale\Payment $payment */
foreach ($paymentCollection as $payment) {
$isPaid = $payment->isPaid();
try {
$paySystemAction = PaySystemActionRepository::getFirstByWhere(
['*'],
[
['ID', '=', $payment->getField('PAY_SYSTEM_ID')],
]
);
} catch (ObjectPropertyException | ArgumentException | SystemException $e) {
AddMessage2Log($e->getMessage());
}
if (isset($paySystemAction)
&& !$isPaid
&& $paySystemAction->get('CODE') === Constants::BONUS_PAYMENT_CODE
) {
$payment->setPaid('Y');
$order->save();
}
}
} catch (Exception | ArgumentNullException $exception) {
AddMessage2Log($exception->getMessage());
}
return [
'status' => 'success',
'msg' => 'Бонусы успешно списаны',
'msgColor' => 'green',
];
}
return [
'status' => 'error',
'msg' => 'Ошибка',
'msgColor' => 'brown',
];
}
/**
* @return \array[][]
*/
public function sendVerificationCode(): array
{
return [
'sendSms' => [
'-prefilters' => [
new Authentication,
new HttpMethod(['GET']),
],
],
];
}
}

View file

@ -32,6 +32,7 @@ class AdminPanel extends Controller
/**
* AdminPanel constructor.
*
* @param \Bitrix\Main\Request|null $request
*/
public function __construct(Request $request = null)

View file

@ -12,6 +12,8 @@
namespace Intaro\RetailCrm\Model\Api\Response;
use Intaro\RetailCrm\Model\Api\AbstractApiModel;
use Intaro\RetailCrm\Component\Json\Mapping;
/**
* Class AbstractApiResponseModel

View file

@ -14,12 +14,19 @@ namespace Intaro\RetailCrm\Service;
use Bitrix\Catalog\GroupTable;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ArgumentNullException;
use Bitrix\Main\Loader;
use Bitrix\Main\LoaderException;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\SystemException;
use Bitrix\Sale\Order;
use CUser;
use Exception;
use Intaro\RetailCrm\Component\Factory\ClientFactory;
use Intaro\RetailCrm\Model\Api\Request\Loyalty\LoyaltyCalculateRequest;
use Intaro\RetailCrm\Model\Api\Request\Order\Loyalty\OrderLoyaltyApplyRequest;
use Intaro\RetailCrm\Model\Api\SerializedOrderProduct;
use Intaro\RetailCrm\Repository\PaySystemActionRepository;
/**
* Class LoyaltyService
@ -41,6 +48,17 @@ class LoyaltyService
$this->client = ClientFactory::createClientAdapter();
}
/*
* Возвращает статус пользователя в системе лояльности
*/
public static function getLoyaltyPersonalStatus(): bool
{
global $USER;
$userFields = CUser::GetByID($USER->GetID())->Fetch();
return isset($userFields['UF_EXT_REG_PL_INTARO']) && $userFields['UF_EXT_REG_PL_INTARO'] === '1';
}
/**
* @param int $orderId
* @param int $bonusCount

View file

@ -14,6 +14,7 @@ namespace Intaro\RetailCrm\Service;
use Exception;
use Intaro\RetailCrm\Component\Factory\ClientFactory;
use Intaro\RetailCrm\Model\Api\Request\SmsVerification\SmsVerificationConfirmRequest;
use Intaro\RetailCrm\Model\Api\Response\SmsVerification\SmsVerificationConfirmResponse;
use Intaro\RetailCrm\Model\Api\Response\SmsVerification\SmsVerificationStatusRequest;
use Intaro\RetailCrm\Model\Api\SmsVerificationConfirm;
@ -56,7 +57,7 @@ class UserVerificationService
* @param string $checkId Идентификатор проверки кода
* @return \Intaro\RetailCrm\Model\Api\Response\SmsVerification\SmsVerificationConfirmResponse|null
*/
public function confirmVerification(string $code, string $checkId)
public function confirmVerification(string $code, string $checkId): ?SmsVerificationConfirmResponse
{
$request = new SmsVerificationConfirmRequest();
$request->verification = new SmsVerificationConfirm();