parent
432d45208b
commit
416955477b
@ -0,0 +1,265 @@ |
||||
<?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(); |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); |
||||
/** @var array $arParams */ |
||||
/** @var array $arResult */ |
||||
|
||||
if (!empty($arResult['ITEMS'])): |
||||
foreach ($arResult['ITEMS'] as $item): ?> |
||||
<div class="product"> |
||||
<a class="product__image" href="<?=$item['DETAIL_PAGE_URL']?>">
|
||||
<img src="<?=$item['PREVIEW_PICTURE']?>" alt="<?=$item['NAME']?>">
|
||||
</a> |
||||
<div class="product__data"> |
||||
<?php if(isset($item['RATING'])): ?> |
||||
<div class="product__rating rating rating--<?=$item['RATING']?>"><?=$item['RATING']?>/5</div>
|
||||
<?php endif; ?> |
||||
<div class="product__info"> |
||||
<a class="product__title" href="<?=$item['DETAIL_PAGE_URL']?>"><?=$item['NAME']?></a>
|
||||
<?php if(!empty($item['PREVIEW_TEXT'])): ?> |
||||
<p class="product__text"><?=$item['PREVIEW_TEXT']?></p>
|
||||
<?php endif; ?> |
||||
</div> |
||||
<div class="product__info"> |
||||
<?php if(!empty($item['PEOPLE_COUNT'])): ?> |
||||
<p class="product__text">Пользователей: <span><?=$item['PEOPLE_COUNT']?></span></p>
|
||||
<?php endif; ?> |
||||
<?php if(!empty($item['PERFORMANCE'])): ?> |
||||
<p class="product__text">Производительность: <span><?=$item['PERFORMANCE']?> м³/сут</span></p>
|
||||
<?php endif; ?> |
||||
<?php if(!empty($item['RESET'])): ?> |
||||
<p class="product__text">Залповый сброс: <span><?=$item['RESET']?> л</span></p>
|
||||
<?php endif; ?> |
||||
<?php if(!empty($item['POWER'])): ?> |
||||
<p class="product__text">Питание: <span><?=$item['POWER']?></span></p>
|
||||
<?php endif; ?> |
||||
</div> |
||||
<?php if(!empty($item['PRICE'])): ?> |
||||
<div class="product__price"><?=number_format($item['PRICE'], 0, '.', ' ')?> ₽</div>
|
||||
<?php endif; ?> |
||||
<div class="product__btns"> |
||||
<button class="button button--orange" onclick="addToCart(<?=$item['ID']?>)">Купить</button>
|
||||
<button class="button button--outline">Купить с установкой</button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<?php endforeach; |
||||
else: ?> |
||||
<div class="product__order"> |
||||
<h3 class="product__order-title section-title">Нужен септик для бизнеса?</h3> |
||||
<div class="product__order-info">Наш менеджер свяжется с вами в ближайшее время</div> |
||||
<form action="#"> |
||||
<input type="text" class="input" placeholder="Ваше имя"> |
||||
<input type="tel" class="input" placeholder="Номер телефона"> |
||||
<button class="button button--orange" type="submit">Заказать звонок</button> |
||||
<div class="product__order-sub">Нажимая кнопку «Заказать звонок», вы подтверждаете свое согласие на обработку <a href="#">персональных данных</a></div> |
||||
</form> |
||||
</div> |
||||
<?php endif; ?>
|
@ -0,0 +1,383 @@ |
||||
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); |
||||
/** @var array $arParams */ |
||||
/** @var array $arResult */ |
||||
/** @global CMain $APPLICATION */ |
||||
/** @global CUser $USER */ |
||||
/** @global CDatabase $DB */ |
||||
/** @var CBitrixComponentTemplate $this */ |
||||
/** @var string $templateName */ |
||||
/** @var string $templateFile */ |
||||
/** @var string $templateFolder */ |
||||
/** @var string $componentPath */ |
||||
/** @var CBitrixComponent $component */ |
||||
?> |
||||
|
||||
<section class="calc section-inner container"> |
||||
<h1 class="calc__title">Рассчитать септик онлайн</h1> |
||||
<form action="" method="POST" id="calculator-form"> |
||||
<input type="hidden" name="calculate" value="Y"> |
||||
<div class="calc__form"> |
||||
<h2 class="calc__form-title">Участок, септик</h2> |
||||
<div class="calc__form-top"> |
||||
<div class="select"> |
||||
<div class="select__name">Почва</div> |
||||
<select name="soil" id="soil" class="js-calc-field"> |
||||
<option value="">Выберите тип почвы</option> |
||||
<?php foreach ($arResult['SOIL_TYPES'] as $code => $soil): ?> |
||||
<option value="<?=$code?>"><?=$soil['NAME']?></option>
|
||||
<?php endforeach; ?> |
||||
</select> |
||||
</div> |
||||
|
||||
<div class="select"> |
||||
<div class="select__name">Количество людей</div> |
||||
<select name="people" id="people" class="js-calc-field"> |
||||
<option value="">Выберите количество человек</option> |
||||
<?php foreach ($arResult['PEOPLE_COUNT'] as $code => $people): ?> |
||||
<option value="<?=$code?>"><?=$people['NAME']?></option>
|
||||
<?php endforeach; ?> |
||||
</select> |
||||
</div> |
||||
|
||||
<div class="select"> |
||||
<div class="select__name">Проживание</div> |
||||
<select name="living" id="living" class="js-calc-field"> |
||||
<option value="">Выберите тип проживания</option> |
||||
<?php foreach ($arResult['LIVING_TYPES'] as $code => $type): ?> |
||||
<option value="<?=$code?>"><?=$type['NAME']?></option>
|
||||
<?php endforeach; ?> |
||||
</select> |
||||
</div> |
||||
|
||||
<div class="select"> |
||||
<div class="select__name">Глубина залегания труб</div> |
||||
<select name="ground_water" id="ground_water" class="js-calc-field"> |
||||
<option value="">Выберите уровень грунтовых вод</option> |
||||
<?php foreach ($arResult['GROUND_WATER'] as $code => $water): ?> |
||||
<option value="<?=$code?>"><?=$water['NAME']?></option>
|
||||
<?php endforeach; ?> |
||||
</select> |
||||
</div> |
||||
</div> |
||||
<div class="calc__top-item"> |
||||
<input class="visually-hidden" type="checkbox" name="with_ground_water" id="ground_water_check"> |
||||
<label class="switcher" for="ground_water_check">Высокие грунтовые воды</label> |
||||
</div> |
||||
|
||||
</div> |
||||
|
||||
<div class="calc__form"> |
||||
<h2 class="calc__form-title">Залповый сброс</h2> |
||||
<div class="calc__form-bottom"> |
||||
<div class="calc__form-groups"> |
||||
<div class="calc__group"> |
||||
<div class="calc__switcher"> |
||||
<input class="visually-hidden" type="checkbox" name="bath" id="calc-bath"> |
||||
<label class="switcher" for="calc-bath">Ванна, 200л</label> |
||||
</div> |
||||
<div class="calc__radios"> |
||||
<input class="visually-hidden" type="radio" name="bath" value="1" id="bath-1" checked> |
||||
<label class="radio" for="bath-1">1</label> |
||||
<input class="visually-hidden" type="radio" name="bath" value="2" id="bath-2"> |
||||
<label class="radio" for="bath-2">2</label> |
||||
<input class="visually-hidden" type="radio" name="bath" value="3" id="bath-3"> |
||||
<label class="radio" for="bath-3">3</label> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="calc__group"> |
||||
<div class="calc__switcher"> |
||||
<input class="visually-hidden" type="checkbox" name="toilet" id="calc-toilet"> |
||||
<label class="switcher" for="calc-toilet">Унитаз, 10л</label> |
||||
</div> |
||||
<div class="calc__radios"> |
||||
<input class="visually-hidden" type="radio" name="toilet" value="1" id="toilet-1" checked> |
||||
<label class="radio" for="toilet-1">1</label> |
||||
<input class="visually-hidden" type="radio" name="toilet" value="2" id="toilet-2"> |
||||
<label class="radio" for="toilet-2">2</label> |
||||
<input class="visually-hidden" type="radio" name="toilet" value="3" id="toilet-3"> |
||||
<label class="radio" for="toilet-3">3</label> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="calc__group"> |
||||
<div class="calc__switcher"> |
||||
<input class="visually-hidden" type="checkbox" name="sink" id="calc-sink"> |
||||
<label class="switcher" for="calc-sink">Раковина, 20л</label> |
||||
</div> |
||||
<div class="calc__radios"> |
||||
<input class="visually-hidden" type="radio" name="sink" value="1" id="sink-1" checked> |
||||
<label class="radio" for="sink-1">1</label> |
||||
<input class="visually-hidden" type="radio" name="sink" value="2" id="sink-2"> |
||||
<label class="radio" for="sink-2">2</label> |
||||
<input class="visually-hidden" type="radio" name="sink" value="3" id="sink-3"> |
||||
<label class="radio" for="sink-3">3</label> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="calc__group"> |
||||
<div class="calc__switcher"> |
||||
<input class="visually-hidden" type="checkbox" name="shower" id="calc-shower"> |
||||
<label class="switcher" for="calc-shower">Душ, 50л</label> |
||||
</div> |
||||
<div class="calc__radios"> |
||||
<input class="visually-hidden" type="radio" name="shower" value="1" id="shower-1" checked> |
||||
<label class="radio" for="shower-1">1</label> |
||||
<input class="visually-hidden" type="radio" name="shower" value="2" id="shower-2"> |
||||
<label class="radio" for="shower-2">2</label> |
||||
<input class="visually-hidden" type="radio" name="shower" value="3" id="shower-3"> |
||||
<label class="radio" for="shower-3">3</label> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="calc__group"> |
||||
<div class="calc__switcher"> |
||||
<input class="visually-hidden" type="checkbox" name="bidet" id="calc-bidet"> |
||||
<label class="switcher" for="calc-bidet">Биде, 10л</label> |
||||
</div> |
||||
<div class="calc__radios"> |
||||
<input class="visually-hidden" type="radio" name="bidet" value="1" id="bidet-1" checked> |
||||
<label class="radio" for="bidet-1">1</label> |
||||
<input class="visually-hidden" type="radio" name="bidet" value="2" id="bidet-2"> |
||||
<label class="radio" for="bidet-2">2</label> |
||||
<input class="visually-hidden" type="radio" name="bidet" value="3" id="bidet-3"> |
||||
<label class="radio" for="bidet-3">3</label> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="calc__group"> |
||||
<div class="calc__switcher"> |
||||
<input class="visually-hidden" type="checkbox" name="jacuzzi" id="calc-jacuzzi"> |
||||
<label class="switcher" for="calc-jacuzzi">Джакузи, 400л</label> |
||||
</div> |
||||
<div class="calc__radios"> |
||||
<input class="visually-hidden" type="radio" name="jacuzzi" value="1" id="jacuzzi-1" checked> |
||||
<label class="radio" for="jacuzzi-1">1</label> |
||||
<input class="visually-hidden" type="radio" name="jacuzzi" value="2" id="jacuzzi-2"> |
||||
<label class="radio" for="jacuzzi-2">2</label> |
||||
<input class="visually-hidden" type="radio" name="jacuzzi" value="3" id="jacuzzi-3"> |
||||
<label class="radio" for="jacuzzi-3">3</label> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="calc__group"> |
||||
<div class="calc__switcher"> |
||||
<input class="visually-hidden" type="checkbox" name="washer" id="calc-washer"> |
||||
<label class="switcher" for="calc-washer">Стиральная машина, 50л</label> |
||||
</div> |
||||
<div class="calc__radios"> |
||||
<input class="visually-hidden" type="radio" name="washer" value="1" id="washer-1" checked> |
||||
<label class="radio" for="washer-1">1</label> |
||||
<input class="visually-hidden" type="radio" name="washer" value="2" id="washer-2"> |
||||
<label class="radio" for="washer-2">2</label> |
||||
<input class="visually-hidden" type="radio" name="washer" value="3" id="washer-3"> |
||||
<label class="radio" for="washer-3">3</label> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="calc__group"> |
||||
<div class="calc__switcher"> |
||||
<input class="visually-hidden" type="checkbox" name="dishwasher" id="calc-dishwasher"> |
||||
<label class="switcher" for="calc-dishwasher">Посудомойка, 50л</label> |
||||
</div> |
||||
<div class="calc__radios"> |
||||
<input class="visually-hidden" type="radio" name="dishwasher" value="1" id="dishwasher-1" checked> |
||||
<label class="radio" for="dishwasher-1">1</label> |
||||
<input class="visually-hidden" type="radio" name="dishwasher" value="2" id="dishwasher-2"> |
||||
<label class="radio" for="dishwasher-2">2</label> |
||||
<input class="visually-hidden" type="radio" name="dishwasher" value="3" id="dishwasher-3"> |
||||
<label class="radio" for="dishwasher-3">3</label> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="calc__sum"> |
||||
<h3 class="calc__sum-title">Примерная стоимость монтажа</h3> |
||||
<div class="calc__sum-price" id="installation-price"> |
||||
<?=$arResult['INSTALLATION_PRICE_MIN']?> ₽ - <?=$arResult['INSTALLATION_PRICE_MAX']?> ₽
|
||||
</div> |
||||
<div class="calc__sum-desc">Точную цену можно узнать после консультации</div> |
||||
<button class="button button--orange" type="button" data-action="order-install">Заказать монтаж</button> |
||||
</div> |
||||
</div> |
||||
<div class="calc__actions"> |
||||
<button type="submit" class="button button--orange">Рассчитать</button> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</section> |
||||
<section class="sale sale--calc section-inner container" id="calculator-container" style="display: none;"> |
||||
<h2 class="section-title">Подходящие септики в нашем каталоге</h2> |
||||
<div class="sale__wrap"> |
||||
<div class="sale__products" id="calculator-results"> |
||||
<?php if (!empty($arResult['ITEMS'])): ?> |
||||
<?php foreach ($arResult['ITEMS'] as $item): ?> |
||||
<div class="product"> |
||||
<pre style="background: #f5f5f5; padding: 10px; overflow: auto; max-height: 300px;"> |
||||
<?php print_r($item); ?> |
||||
</pre> |
||||
<a class="product__image" href="<?=$item['DETAIL_PAGE_URL']?>">
|
||||
<img src="<?=$item['PREVIEW_PICTURE']?>" alt="<?=$item['NAME']?>">
|
||||
</a> |
||||
<div class="product__data"> |
||||
<?php if(isset($item['RATING'])): ?> |
||||
<div class="product__rating rating rating--<?=$item['RATING']?>"><?=$item['RATING']?>/5</div>
|
||||
<?php endif; ?> |
||||
<div class="product__info"> |
||||
<a class="product__title" href="<?=$item['DETAIL_PAGE_URL']?>"><?=$item['NAME']?></a>
|
||||
<?php if(!empty($item['PREVIEW_TEXT'])): ?> |
||||
<p class="product__text"><?=$item['PREVIEW_TEXT']?></p>
|
||||
<?php endif; ?> |
||||
</div> |
||||
<div class="product__info"> |
||||
<?php if(!empty($item['PEOPLE_COUNT'])): ?> |
||||
<p class="product__text">Пользователей: <span><?=$item['PEOPLE_COUNT']?></span></p>
|
||||
<?php endif; ?> |
||||
<?php if(!empty($item['PERFORMANCE'])): ?> |
||||
<p class="product__text">Производительность: <span><?=$item['PERFORMANCE']?> м³/сут</span></p>
|
||||
<?php endif; ?> |
||||
<?php if(!empty($item['RESET'])): ?> |
||||
<p class="product__text">Залповый сброс: <span><?=$item['RESET']?> л</span></p>
|
||||
<?php endif; ?> |
||||
<?php if(!empty($item['POWER'])): ?> |
||||
<p class="product__text">Питание: <span><?=$item['POWER']?></span></p>
|
||||
<?php endif; ?> |
||||
</div> |
||||
<?php if(!empty($item['PRICE'])): ?> |
||||
<div class="product__price"><?=number_format($item['PRICE'], 0, '.', ' ')?> ₽</div>
|
||||
<?php endif; ?> |
||||
<div class="product__btns"> |
||||
<button class="button button--orange" onclick="addToCart(<?=$item['ID']?>)">Купить</button>
|
||||
<button class="button button--outline">Купить с установкой</button> |
||||
</div> |
||||
<?php if(!empty($item['REVIEWS'])): ?> |
||||
<div class="product__reviews"> |
||||
<h3>Отзывы:</h3> |
||||
<?php foreach($item['REVIEWS'] as $review): ?> |
||||
<div class="review"> |
||||
<div class="review__header"> |
||||
<span class="review__author"><?=$review['NAME']?></span>
|
||||
<span class="review__city"><?=$review['CITY']?></span>
|
||||
<span class="review__date"><?=$review['DATE']?></span>
|
||||
<span class="review__rating"><?=$review['RATING']?>/5</span>
|
||||
</div> |
||||
<div class="review__content"> |
||||
<h4><?=$review['HEADER']?></h4>
|
||||
<p><?=$review['TEXT']?></p>
|
||||
</div> |
||||
</div> |
||||
<?php endforeach; ?> |
||||
</div> |
||||
<?php endif; ?> |
||||
</div> |
||||
</div> |
||||
<?php endforeach; ?> |
||||
<?php endif; ?> |
||||
</div> |
||||
</div> |
||||
</section> |
||||
|
||||
<script> |
||||
document.addEventListener('DOMContentLoaded', function() { |
||||
const form = document.getElementById('calculator-form'); |
||||
const resultsContainer = document.getElementById('calculator-results'); |
||||
const calculatorContainer = document.getElementById('calculator-container'); |
||||
|
||||
function validateForm() { |
||||
const selects = form.querySelectorAll('select'); |
||||
for (let select of selects) { |
||||
if (select.name === 'ground_water') continue; |
||||
if (!select.value) { |
||||
alert('Пожалуйста, заполните все поля'); |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
function updateResults(e) { |
||||
e.preventDefault(); |
||||
|
||||
if (!validateForm()) { |
||||
return; |
||||
} |
||||
|
||||
// Считаем объем только по отмеченным чекбоксам |
||||
const deviceVolumes = { |
||||
bath: 200, |
||||
toilet: 10, |
||||
sink: 20, |
||||
shower: 50, |
||||
bidet: 10, |
||||
jacuzzi: 400, |
||||
washer: 50, |
||||
dishwasher: 50 |
||||
}; |
||||
let totalVolume = 0; |
||||
const devices = Object.keys(deviceVolumes); |
||||
devices.forEach(device => { |
||||
const checkbox = document.getElementById(`calc-${device}`); |
||||
if (checkbox && checkbox.checked) { |
||||
totalVolume += deviceVolumes[device]; |
||||
} |
||||
}); |
||||
|
||||
// Собираем только нужные поля |
||||
const formData = new FormData(); |
||||
formData.append('ajax', 'Y'); |
||||
formData.append('calculate', 'Y'); |
||||
formData.append('soil', document.getElementById('soil').value); |
||||
formData.append('people', document.getElementById('people').value); |
||||
formData.append('living', document.getElementById('living').value); |
||||
formData.append('ground_water', document.getElementById('ground_water').value); |
||||
formData.append('volume', totalVolume); |
||||
|
||||
// Логи |
||||
console.log('Calculated total volume:', totalVolume); |
||||
console.log('--- FormData to send ---'); |
||||
for (let pair of formData.entries()) { |
||||
console.log(pair[0]+ ': ' + pair[1]); |
||||
} |
||||
console.log('------------------------'); |
||||
|
||||
fetch('', { |
||||
method: 'POST', |
||||
body: formData |
||||
}) |
||||
.then(response => response.json()) |
||||
.then(data => { |
||||
if (data.items) { |
||||
calculatorContainer.style.display = 'block'; |
||||
resultsContainer.innerHTML = data.items; |
||||
} else { |
||||
calculatorContainer.style.display = 'none'; |
||||
} |
||||
|
||||
if (data.installation_price) { |
||||
const priceElement = document.getElementById('installation-price'); |
||||
if (priceElement) { |
||||
priceElement.textContent = data.installation_price; |
||||
} |
||||
} |
||||
}) |
||||
.catch(error => { |
||||
console.error('Error:', error); |
||||
calculatorContainer.style.display = 'none'; |
||||
}); |
||||
} |
||||
|
||||
// Добавляем обработчик отправки формы |
||||
form.addEventListener('submit', updateResults); |
||||
}); |
||||
</script> |
||||
|
||||
<style> |
||||
.calc__actions { |
||||
margin-top: 20px; |
||||
text-align: center; |
||||
} |
||||
|
||||
.calc__actions .button { |
||||
min-width: 200px; |
||||
} |
||||
</style> |
@ -0,0 +1,11 @@ |
||||
<?php |
||||
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); |
||||
|
||||
$arComponentDescription = array( |
||||
"NAME" => "HTML-карта сайта", |
||||
"DESCRIPTION" => "Автоматическая html-карта сайта с древовидной структурой.", |
||||
"ICON" => "", |
||||
"PATH" => array( |
||||
"ID" => "era" |
||||
), |
||||
); |
@ -0,0 +1,6 @@ |
||||
<?php |
||||
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); |
||||
|
||||
$arComponentParameters = array( |
||||
"PARAMETERS" => array() |
||||
); |
@ -0,0 +1,25 @@ |
||||
<?php |
||||
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); |
||||
|
||||
use Bitrix\Main\Loader; |
||||
use Bitrix\Iblock\SectionTable; |
||||
use Bitrix\Iblock\ElementTable; |
||||
|
||||
class HtmlMapComponent extends CBitrixComponent |
||||
{ |
||||
public function executeComponent() |
||||
{ |
||||
// Получаем структуру сайта (разделы, фильтры) |
||||
$this->arResult['TREE'] = $this->getSiteTree(); |
||||
$this->includeComponentTemplate(); |
||||
} |
||||
|
||||
private function getSiteTree() |
||||
{ |
||||
// TODO: Реализовать сбор структуры сайта, разделов, фильтров |
||||
// Пример: получить разделы каталога |
||||
$tree = []; |
||||
// ... |
||||
return $tree; |
||||
} |
||||
} |
@ -0,0 +1,25 @@ |
||||
<?if(!defined("B_PROLOG_INCLUDED")||B_PROLOG_INCLUDED!==true)die(); ?> |
||||
<div class="html-map"> |
||||
<h1>HTML-карта сайта</h1> |
||||
<?php if (!empty($arResult['TREE'])): ?> |
||||
<ul class="html-map__list"> |
||||
<?php foreach ($arResult['TREE'] as $item): ?> |
||||
<li> |
||||
<a href="<?=$item['URL']?>"><?=$item['TITLE']?></a>
|
||||
<?php if (!empty($item['CHILDREN'])): ?> |
||||
<ul> |
||||
<?php foreach ($item['CHILDREN'] as $child): ?> |
||||
<li> |
||||
<a href="<?=$child['URL']?>"><?=$child['TITLE']?></a>
|
||||
<!-- и так далее, до 4 уровня --> |
||||
</li> |
||||
<?php endforeach; ?> |
||||
</ul> |
||||
<?php endif; ?> |
||||
</li> |
||||
<?php endforeach; ?> |
||||
</ul> |
||||
<?php else: ?> |
||||
<p>Карта сайта пуста.</p> |
||||
<?php endif; ?> |
||||
</div> |
@ -0,0 +1,5 @@ |
||||
<? |
||||
return array( |
||||
"NAME" => "Услуги (кастомный шаблон)", |
||||
"DESCRIPTION" => "Шаблон для компонента bitrix:news (услуги)", |
||||
); |
@ -0,0 +1,43 @@ |
||||
.services-list { |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
gap: 24px; |
||||
} |
||||
.service-item { |
||||
border: 1px solid #e0e0e0; |
||||
border-radius: 8px; |
||||
padding: 16px; |
||||
width: 300px; |
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.04); |
||||
background: #fff; |
||||
display: flex; |
||||
flex-direction: column; |
||||
align-items: flex-start; |
||||
} |
||||
.service-item h2 { |
||||
font-size: 1.2em; |
||||
margin: 0 0 8px 0; |
||||
} |
||||
.service-item img { |
||||
max-width: 100%; |
||||
border-radius: 4px; |
||||
margin-bottom: 8px; |
||||
} |
||||
.service-desc { |
||||
margin-bottom: 8px; |
||||
color: #444; |
||||
} |
||||
.service-price { |
||||
font-weight: bold; |
||||
color: #1a7f37; |
||||
margin-bottom: 8px; |
||||
} |
||||
.service-item a { |
||||
margin-top: auto; |
||||
color: #1976d2; |
||||
text-decoration: none; |
||||
font-weight: 500; |
||||
} |
||||
.service-item a:hover { |
||||
text-decoration: underline; |
||||
} |
@ -0,0 +1,21 @@ |
||||
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?> |
||||
<div class="services-list"> |
||||
<?foreach( |
||||
$arResult["ITEMS"] as $arItem):?> |
||||
<div class="service-item"> |
||||
<h2><?=$arItem["NAME"]?></h2>
|
||||
<?if($arItem["PREVIEW_PICTURE"]):?> |
||||
<img src="<?=$arItem["PREVIEW_PICTURE"]["SRC"]?>" alt="<?=$arItem["NAME"]?>">
|
||||
<?endif;?> |
||||
<div class="service-desc"> |
||||
<?=$arItem["PREVIEW_TEXT"]?> |
||||
</div> |
||||
<?if($arItem["PROPERTIES"]["PRICE"]["VALUE"]):?> |
||||
<div class="service-price"> |
||||
Цена: <?=$arItem["PROPERTIES"]["PRICE"]["VALUE"]?> |
||||
</div> |
||||
<?endif;?> |
||||
<a href="<?=$arItem["DETAIL_PAGE_URL"]?>">Подробнее</a>
|
||||
</div> |
||||
<?endforeach;?> |
||||
</div> |
@ -0,0 +1,126 @@ |
||||
<?php |
||||
$eventType = new CEventType; |
||||
$eventMessage = new CEventMessage; |
||||
|
||||
// Проверяем существование типа почтового события |
||||
$eventTypeResult = $eventType->GetList(array("TYPE_ID" => "CONSULTATION_REQUEST")); |
||||
if (!$eventTypeResult->Fetch()) { |
||||
// Создаем тип почтового события |
||||
$eventType->Add(array( |
||||
"EVENT_NAME" => "CONSULTATION_REQUEST", |
||||
"NAME" => "Заявка на консультацию", |
||||
"LID" => "ru", |
||||
"DESCRIPTION" => "#NAME# - Имя клиента\n#PHONE# - Телефон\n#EMAIL_TO# - Email получателя" |
||||
)); |
||||
} |
||||
|
||||
// Проверяем существование шаблона |
||||
$eventMessageResult = $eventMessage->GetList( |
||||
array(), |
||||
array("TYPE_ID" => "CONSULTATION_REQUEST") |
||||
); |
||||
if (!$eventMessageResult->Fetch()) { |
||||
// Создаем шаблон почтового события |
||||
$eventMessage->Add(array( |
||||
"ACTIVE" => "Y", |
||||
"EVENT_NAME" => "CONSULTATION_REQUEST", |
||||
"LID" => SITE_ID, |
||||
"EMAIL_FROM" => "#DEFAULT_EMAIL_FROM#", |
||||
"EMAIL_TO" => "#EMAIL_TO#", |
||||
"SUBJECT" => "Новая заявка на консультацию", |
||||
"BODY_TYPE" => "html", |
||||
"MESSAGE" => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
||||
<html> |
||||
<head> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
||||
</head> |
||||
<body> |
||||
<p>Поступила новая заявка на консультацию!</p> |
||||
|
||||
<p><b>Имя клиента:</b> #NAME#</p> |
||||
<p><b>Телефон:</b> #PHONE#</p> |
||||
|
||||
<br/> |
||||
<p>Сообщение сгенерировано автоматически.</p> |
||||
</body> |
||||
</html>' |
||||
)); |
||||
} |
||||
|
||||
// === Настройка почтового события для новых заказов === |
||||
$eventTypeResult = $eventType->GetList(array("TYPE_ID" => "SALE_NEW_ORDER_CUSTOM")); |
||||
if (!$eventTypeResult->Fetch()) { |
||||
// Создаем тип почтового события |
||||
$eventType->Add(array( |
||||
"EVENT_NAME" => "SALE_NEW_ORDER_CUSTOM", |
||||
"NAME" => "Новый заказ", |
||||
"LID" => "ru", |
||||
"DESCRIPTION" => "#ORDER_ID# - Номер заказа\n#ORDER_DATE# - Дата заказа\n#USER_NAME# - Имя покупателя\n#USER_PHONE# - Телефон\n#USER_EMAIL# - Email\n#PRICE# - Сумма заказа\n#CURRENCY# - Валюта\n#EMAIL# - Email получателя" |
||||
)); |
||||
} |
||||
|
||||
// Проверяем существование шаблона |
||||
$eventMessageResult = $eventMessage->GetList( |
||||
array(), |
||||
array("TYPE_ID" => "SALE_NEW_ORDER_CUSTOM") |
||||
); |
||||
if (!$eventMessageResult->Fetch()) { |
||||
// Создаем шаблон почтового события |
||||
$eventMessage->Add(array( |
||||
"ACTIVE" => "Y", |
||||
"EVENT_NAME" => "SALE_NEW_ORDER_CUSTOM", |
||||
"LID" => SITE_ID, |
||||
"EMAIL_FROM" => "#DEFAULT_EMAIL_FROM#", |
||||
"EMAIL_TO" => "#EMAIL#", |
||||
"SUBJECT" => "Новый заказ #ORDER_ID#", |
||||
"BODY_TYPE" => "html", |
||||
"MESSAGE" => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
||||
<html> |
||||
<head> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
||||
</head> |
||||
<body> |
||||
<h2>Поступил новый заказ!</h2> |
||||
|
||||
<p><b>Номер заказа:</b> #ORDER_ID#</p> |
||||
<p><b>Дата заказа:</b> #ORDER_DATE#</p> |
||||
<p><b>Имя покупателя:</b> #USER_NAME#</p> |
||||
<p><b>Телефон:</b> #USER_PHONE#</p> |
||||
<p><b>Email:</b> #USER_EMAIL#</p> |
||||
<p><b>Сумма заказа:</b> #PRICE# #CURRENCY#</p> |
||||
|
||||
<br/> |
||||
<p>Перейти к заказу в административной панели</p> |
||||
<p>Сообщение сгенерировано автоматически.</p> |
||||
</body> |
||||
</html>' |
||||
)); |
||||
} |
||||
|
||||
// === Обработка формы консультации из футера === |
||||
if ( |
||||
$_SERVER['REQUEST_METHOD'] === 'POST' && |
||||
isset($_POST['consultation_form']) && |
||||
!empty($_POST['name']) && |
||||
!empty($_POST['phone']) |
||||
) { |
||||
CEvent::Send( |
||||
"CONSULTATION_REQUEST", |
||||
SITE_ID, |
||||
array( |
||||
"NAME" => htmlspecialchars($_POST['name']), |
||||
"PHONE" => htmlspecialchars($_POST['phone']), |
||||
"EMAIL_TO" => COption::GetOptionString("main", "email_from") |
||||
) |
||||
); |
||||
// Можно добавить редирект или JSON-ответ, если это ajax |
||||
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { |
||||
header('Content-Type: application/json'); |
||||
echo json_encode(["success" => true]); |
||||
exit; |
||||
} else { |
||||
// Обычный редирект после отправки |
||||
header('Location: ' . $_SERVER['HTTP_REFERER']); |
||||
exit; |
||||
} |
||||
} |
Loading…
Reference in new issue