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.
 
 
 
 
aliseptik/local/components/era/calculator/class.php

266 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();
}
}