You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
9.7 KiB
265 lines
9.7 KiB
<?php
|
|
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
|
|
|
|
use Bitrix\Main\Loader;
|
|
use Bitrix\Iblock\ElementTable;
|
|
|
|
class EraCalculatorComponent extends CBitrixComponent
|
|
{
|
|
private $iblockId;
|
|
private $isAjax = false;
|
|
|
|
public function onPrepareComponentParams($arParams)
|
|
{
|
|
$this->iblockId = $arParams['IBLOCK_ID'];
|
|
|
|
// Добавляем параметры для работы с ценами
|
|
if (!isset($arParams['PRICE_CODE']))
|
|
$arParams['PRICE_CODE'] = array();
|
|
|
|
if (!isset($arParams['PRICE_VAT_INCLUDE']))
|
|
$arParams['PRICE_VAT_INCLUDE'] = 'Y';
|
|
|
|
if (!isset($arParams['CONVERT_CURRENCY']))
|
|
$arParams['CONVERT_CURRENCY'] = 'N';
|
|
|
|
if (!isset($arParams['CURRENCY_ID']))
|
|
$arParams['CURRENCY_ID'] = '';
|
|
|
|
return $arParams;
|
|
}
|
|
|
|
public function executeComponent()
|
|
{
|
|
if (!Loader::includeModule('iblock')) {
|
|
ShowError('Модуль iblock не установлен');
|
|
return;
|
|
}
|
|
|
|
if (!Loader::includeModule('catalog')) {
|
|
ShowError('Модуль catalog не установлен');
|
|
return;
|
|
}
|
|
|
|
// Проверяем, является ли запрос AJAX
|
|
$this->isAjax = $this->request->get('ajax') === 'Y';
|
|
|
|
// Получаем все значения для почвы
|
|
$this->arResult['SOIL_TYPES'] = $this->getPropertyEnumValues(58);
|
|
|
|
// Получаем все значения для количества человек
|
|
$this->arResult['PEOPLE_COUNT'] = $this->getPropertyEnumValues(28);
|
|
|
|
// Получаем значения для типа проживания
|
|
$this->arResult['LIVING_TYPES'] = $this->getPropertyEnumValues(61);
|
|
|
|
// Получаем значения для грунтовых вод
|
|
$this->arResult['GROUND_WATER'] = $this->getPropertyEnumValues(57);
|
|
|
|
if ($this->request->isPost() && ($this->request->getPost('calculate') === 'Y' || $this->isAjax)) {
|
|
$this->processCalculation();
|
|
}
|
|
|
|
if ($this->isAjax) {
|
|
$this->sendAjaxResponse();
|
|
} else {
|
|
$this->includeComponentTemplate();
|
|
}
|
|
}
|
|
|
|
private function getPropertyEnumValues($propertyId)
|
|
{
|
|
$result = [];
|
|
$property_enums = CIBlockPropertyEnum::GetList(
|
|
["SORT" => "ASC"],
|
|
["PROPERTY_ID" => $propertyId]
|
|
);
|
|
while($enum_fields = $property_enums->GetNext()) {
|
|
$result[$enum_fields["XML_ID"]] = [
|
|
'ID' => $enum_fields["ID"],
|
|
'NAME' => $enum_fields["VALUE"],
|
|
'XML_ID' => $enum_fields["XML_ID"]
|
|
];
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
private function calculateInstallationPrice($volume)
|
|
{
|
|
// Базовая стоимость установки
|
|
$basePrice = 35000;
|
|
|
|
// Увеличиваем стоимость в зависимости от объема
|
|
$priceIncrease = floor($volume / 50) * 5000;
|
|
|
|
$minPrice = $basePrice + $priceIncrease;
|
|
$maxPrice = $minPrice + 10000;
|
|
|
|
return number_format($minPrice, 0, '.', ' ') . ' ₽ - ' . number_format($maxPrice, 0, '.', ' ') . ' ₽';
|
|
}
|
|
|
|
private function calculateVolume($request)
|
|
{
|
|
$totalVolume = 0;
|
|
|
|
// Массив объемов для каждого прибора
|
|
$volumes = [
|
|
'bath' => 200,
|
|
'toilet' => 10,
|
|
'sink' => 20,
|
|
'shower' => 50,
|
|
'bidet' => 10,
|
|
'jacuzzi' => 400,
|
|
'washer' => 50,
|
|
'dishwasher' => 50
|
|
];
|
|
|
|
// Проходим по каждому прибору
|
|
foreach ($volumes as $device => $volume) {
|
|
// Проверяем, включен ли прибор
|
|
if ($request->get($device) === 'Y') {
|
|
// Получаем количество приборов (1, 2 или 3)
|
|
$count = (int)$request->get($device . '_count');
|
|
if ($count > 0 && $count <= 3) {
|
|
$totalVolume += $volume * $count;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $totalVolume;
|
|
}
|
|
|
|
private function processCalculation()
|
|
{
|
|
$request = $this->request->getPostList();
|
|
|
|
// Логируем все пришедшие данные
|
|
AddMessage2Log(print_r($request->toArray(), true), 'CALC_LOG: REQUEST');
|
|
|
|
// Получаем объем из POST
|
|
$volume = (int)$request->get('volume');
|
|
if ($volume <= 0) {
|
|
$volume = $this->calculateVolume($request); // fallback
|
|
}
|
|
|
|
// Логируем рассчитанный объем
|
|
AddMessage2Log('Calculated volume: ' . $volume, 'CALC_LOG: VOLUME');
|
|
|
|
$soil = $request->get('soil');
|
|
$people = $request->get('people');
|
|
$living = $request->get('living');
|
|
$ground_water = $request->get('ground_water');
|
|
|
|
// Формируем фильтр для выборки товаров
|
|
$filter = [
|
|
'IBLOCK_ID' => $this->iblockId,
|
|
'ACTIVE' => 'Y'
|
|
];
|
|
|
|
// Добавляем фильтр по почве если выбрано
|
|
if ($soil && isset($this->arResult['SOIL_TYPES'][$soil])) {
|
|
$filter['PROPERTY_58'] = $this->arResult['SOIL_TYPES'][$soil]['ID'];
|
|
}
|
|
|
|
// Добавляем фильтр по количеству человек если выбрано
|
|
if ($people && isset($this->arResult['PEOPLE_COUNT'][$people])) {
|
|
$filter['PROPERTY_28'] = $this->arResult['PEOPLE_COUNT'][$people]['ID'];
|
|
}
|
|
|
|
// Добавляем фильтр по типу проживания если выбрано
|
|
if ($living && isset($this->arResult['LIVING_TYPES'][$living])) {
|
|
$filter['PROPERTY_61'] = $this->arResult['LIVING_TYPES'][$living]['ID'];
|
|
}
|
|
|
|
// Добавляем фильтр по грунтовым водам если выбрано
|
|
if ($ground_water && isset($this->arResult['GROUND_WATER'][$ground_water])) {
|
|
$filter['PROPERTY_57'] = $this->arResult['GROUND_WATER'][$ground_water]['ID'];
|
|
}
|
|
|
|
// Логируем итоговый фильтр
|
|
AddMessage2Log(print_r($filter, true), 'CALC_LOG: FILTER');
|
|
|
|
// Добавляем фильтр по залповому сбросу
|
|
if ($volume > 0) {
|
|
$filter['>PROPERTY_SBROS_NUM'] = $volume;
|
|
}
|
|
|
|
// Получаем товары
|
|
$elements = CIBlockElement::GetList(
|
|
['SORT' => 'ASC'],
|
|
$filter,
|
|
false,
|
|
['nPageSize' => 3],
|
|
['*', 'PROPERTY_*']
|
|
);
|
|
|
|
$this->arResult['ITEMS'] = [];
|
|
$prices = [];
|
|
|
|
while ($element = $elements->GetNextElement()) {
|
|
$fields = $element->GetFields();
|
|
$properties = $element->GetProperties();
|
|
|
|
// Получаем все картинки
|
|
if($fields['PREVIEW_PICTURE']) {
|
|
$fields['PREVIEW_PICTURE'] = CFile::GetPath($fields['PREVIEW_PICTURE']);
|
|
}
|
|
|
|
// Формируем массив с полной информацией о товаре
|
|
$item = [
|
|
'ID' => $fields['ID'],
|
|
'NAME' => $fields['NAME'],
|
|
'PREVIEW_PICTURE' => $fields['PREVIEW_PICTURE'],
|
|
'PREVIEW_TEXT' => $fields['PREVIEW_TEXT'],
|
|
'DETAIL_PAGE_URL' => $fields['DETAIL_PAGE_URL'],
|
|
'PRICE' => $properties['ATT_OLD_PRICE']['VALUE'],
|
|
'PEOPLE_COUNT' => $properties['PEOPLE_COUNT']['VALUE'],
|
|
'PERFORMANCE' => $properties['PERFORMANCE']['VALUE'],
|
|
'RESET' => $properties['SBROS_NUM']['VALUE'],
|
|
'POWER' => $properties['POWER']['VALUE'],
|
|
'RATING' => $properties['REV_RATING']['VALUE'][0]
|
|
];
|
|
|
|
// Добавляем цену в массив цен для расчета диапазона
|
|
if (!empty($item['PRICE'])) {
|
|
$prices[] = (float)$item['PRICE'];
|
|
}
|
|
|
|
$this->arResult['ITEMS'][] = $item;
|
|
}
|
|
|
|
// Логируем найденные товары
|
|
AddMessage2Log(print_r($this->arResult['ITEMS'], true), 'CALC_LOG: ITEMS');
|
|
|
|
// Устанавливаем диапазон цен из найденных товаров
|
|
if (!empty($prices)) {
|
|
$minPrice = min($prices);
|
|
$maxPrice = max($prices);
|
|
$this->arResult['INSTALLATION_PRICE'] = number_format($minPrice, 0, '.', ' ') . ' ₽ - ' . number_format($maxPrice, 0, '.', ' ') . ' ₽';
|
|
} else {
|
|
$this->arResult['INSTALLATION_PRICE'] = 'Цена по запросу';
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private function sendAjaxResponse()
|
|
{
|
|
global $APPLICATION;
|
|
|
|
$APPLICATION->RestartBuffer();
|
|
|
|
// Получаем HTML для товаров
|
|
ob_start();
|
|
$this->includeComponentTemplate('ajax');
|
|
$itemsHtml = ob_get_clean();
|
|
|
|
$response = [
|
|
'items' => $itemsHtml,
|
|
'installation_price' => $this->arResult['INSTALLATION_PRICE']
|
|
];
|
|
|
|
echo json_encode($response);
|
|
die();
|
|
}
|
|
}
|