ысчитываем цену с акционной скидкой $discountPercent = str_replace(",", ".", $discountPercent); $discountPrice = $price[0]['PRICE'] * ($discountPercent / 100); $priceDiscount = $price[0]['PRICE'] - $discountPrice; error_log("DEBUG: Применяем акционную скидку: базовая цена={$price[0]['PRICE']}, процент=$discountPercent, цена со скидкой=$priceDiscount"); return array( 'PRODUCT_ID' => $productID, 'DISCOUNT_PRICE' => $priceDiscount, 'RESULT_PRICE' => array( "PRICE_TYPE_ID" => $price[0]['ID'], 'BASE_PRICE' => $priceDiscount, 'DISCOUNT_PRICE' => $priceDiscount, 'DISCOUNT' => $discountPrice, 'PERCENT' => $discountPercent, 'CURRENCY' => "RUB", 'VAT_INCLUDED' => "Y", ) ); } // Если IgnoreMaxDisc не установлен, работаем со старой логикой с группами пользователей // Получаем группы пользователя $userGroups = $USER->GetUserGroupArray(); // Определяем максимальную скидку из бонусных групп $bonusDiscounts = [ 'BONUS_SYSTEM_1' => 1, 'BONUS_SYSTEM_2' => 2, 'BONUS_SYSTEM_3' => 3, 'BONUS_SYSTEM_4' => 4, 'BONUS_SYSTEM_5' => 5, 'BONUS_SYSTEM_6' => 6, 'BONUS_SYSTEM_7' => 7 ]; $maxBonusDiscount = 0; $isInBonusGroup = false; foreach ($bonusDiscounts as $groupStringID => $discount) { $groupFilter = ['STRING_ID' => $groupStringID]; $rsGroups = CGroup::GetList($by = "id", $order = "asc", $groupFilter); if ($arGroup = $rsGroups->Fetch()) { if (in_array($arGroup['ID'], $userGroups)) { $isInBonusGroup = true; $maxBonusDiscount = max($maxBonusDiscount, $discount); } } } // Если пользователь не состоит ни в одной бонусной группе, устанавливаем скидку 0% if (!$isInBonusGroup) { $maxBonusDiscount = 0; } // Получаем процент скидки с товара $discountPercent = false; $db_props = CIBlockElement::GetProperty(113, $productID, array("sort" => "asc"), array("CODE" => "MAKSIMALNAYA_SKIDKA_PROTSENT", 'ACTIVE' => 'Y')); if ($ar_props = $db_props->Fetch()) { $discountPercent = $ar_props["VALUE"]; } // Если процент скидки не установлен, возвращаем true if ($discountPercent === false) { return true; } // Преобразуем процент скидки из строки в число $discountPercent = floatval(str_replace(",", ".", $discountPercent)); // Применяем правильную скидку - минимальную из двух $finalDiscountPercent = $discountPercent > $maxBonusDiscount ? $maxBonusDiscount : $discountPercent; // Получаем цену товара $dbProductPrice = CPrice::GetListEx( array(), array("PRODUCT_ID" => $productID), false, false, array("*") ); $price = []; while ($arProductPrice = $dbProductPrice->GetNext()) { $price[] = $arProductPrice; } if (empty($price[0])) { return true; } // Высчитываем цену со скидкой $discountPrice = $price[0]['PRICE'] * ($finalDiscountPercent / 100); $priceDiscount = $price[0]['PRICE'] - $discountPrice; return array( 'PRODUCT_ID' => $productID, 'DISCOUNT_PRICE' => $priceDiscount, 'RESULT_PRICE' => array( "PRICE_TYPE_ID" => $price[0]['ID'], 'BASE_PRICE' => $priceDiscount, 'DISCOUNT_PRICE' => $priceDiscount, 'DISCOUNT' => $discountPrice, 'PERCENT' => $finalDiscountPercent, 'CURRENCY' => $price[0]['CURRENCY'], 'VAT_INCLUDED' => $price[0]['VAT_INCLUDED'], ) ); } //удаление онлайн оплаты если есть товар кторый требует консультации Bitrix\Main\EventManager::getInstance()->addEventHandler('sale', 'OnSaleComponentOrderCreated', 'OnSaleComponentOrderCreatedHandler'); function OnSaleComponentOrderCreatedHandler($order, &$arUserResult, $request, &$arParams, &$arResult, &$arDeliveryServiceAll, &$arPaySystemServiceAll) { $productIds = []; $basket = $order->getBasket(); $basketItems = $basket->getBasketItems(); foreach ($basketItems as $basketItem) { $productIds[] = $basketItem->getField('PRODUCT_ID'); } if(!empty($productIds)){ $delPaySystemOnline = false; $arSelect = Array("ID", "IBLOCK_ID", "PROPERTY_CONS_REQ");//IBLOCK_ID и ID обязательно должны быть указаны, см. описание arSelectFields выше $arFilter = Array("IBLOCK_ID"=>IntVal(113), "=ID"=>$productIds); $res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect); while($ob = $res->fetch()){ if($ob['PROPERTY_CONS_REQ_VALUE'] == 'Да'){ $delPaySystemOnline = true; break; } } if($delPaySystemOnline){ foreach ($arPaySystemServiceAll as $key => $payment){ if($payment['PAY_SYSTEM_ID'] == 17){ unset($arPaySystemServiceAll[$key]); } } } } } //если мы удалили чекнутую платежную систему то ставим чекед первой попавшейся Bitrix\Main\EventManager::getInstance()->addEventHandler('sale', 'OnSaleComponentOrderShowAjaxAnswer', 'OnSaleComponentOrderShowAjaxAnswerHandler'); function OnSaleComponentOrderShowAjaxAnswerHandler(&$arResult) { $productIds = []; foreach ($arResult['order']['GRID']['ROWS'] as $items){ $productIds[] = $items['data']['PRODUCT_ID']; } if(!empty($productIds)){ $delPaySystemOnline = false; $arSelect = Array("ID", "IBLOCK_ID", "PROPERTY_CONS_REQ");//IBLOCK_ID и ID обязательно должны быть указаны, см. описание arSelectFields выше $arFilter = Array("IBLOCK_ID"=>IntVal(113), "=ID"=>$productIds); $res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect); while($ob = $res->fetch()){ if($ob['PROPERTY_CONS_REQ_VALUE'] == 'Да'){ $delPaySystemOnline = true; break; } } if($delPaySystemOnline){ $emptyChecked = true; foreach ($arResult['order']['PAY_SYSTEM'] as $key => $payment){ if($payment['CHECKED'] == 'Y'){ $emptyChecked = false; } } if($emptyChecked){ $arResult['order']['PAY_SYSTEM'][0]['CHECKED'] = 'Y'; } } } } if($_SERVER["PHP_SELF"] == "/bitrix/tools/sale_ps_result.php" || $_SERVER["REQUEST_URI"] == "/bitrix/tools/sale_ps_result.php" || $_SERVER["SCRIPT_URL"] == "/bitrix/tools/sale_ps_result.php" || strpos($_SERVER['REMOTE_ADDR'], "77.75.") !== false) { AddEventHandler( "sale" , "OnSaleOrderPaid" , "onSaleOrderSavedPaid" ); //77.75. - айпишники юкассы } function onSaleOrderSavedPaid ( \Bitrix\Sale\Order $order ) { //обработка получения данных от YOOKASSA $json_data = file_get_contents('php://input'); $data = json_decode($json_data, true); AddMessage2Log('$json_data: ' . print_r($data, true),''); if (json_last_error() !== JSON_ERROR_NONE) { AddMessage2Log('Ошибка декодирования JSON YOOKASSA: ' . json_last_error_msg()); } else { //отработаем отправку чека в юкассу if (! $order ->isPaid() or $order ->isPaid()== false ) return ; // Обрабатываем только оплаченные заказы //Сформируем данные по чеку $order_id = $order->getId(); if (!Loader::includeModule('sale')) { die('Модуль "sale" не загружен'); } //массив чека $arReceipt = []; $arReceipt["payment_id"] = $data["object"]["id"]; $arReceipt["type"] = "payment"; $arReceipt["send"] = "true"; $arReceipt['tax_system_code'] = 2; $arReceipt['settlements'] = []; $arReceipt['settlements'][] = [ 'type' => 'cashless', 'amount' => [ 'value' => $data["object"]["amount"]["value"], 'currency' => $data["object"]["amount"]["currency"], ] ]; // Получение объекта заказа по его ID $order = Order::load($order_id); if ($order) { //массив с данными о покупателе $arCustomer = []; //получение данных о покупателе $propertyCollection = $order->getPropertyCollection(); // Перебор всех свойств заказа foreach ($propertyCollection as $property) { if ($property->getField('CODE') == 'EMAIL' || $property->getField('CODE') == 'E-Mail') { $arCustomer["email"] = $property->getValue(); } if ($property->getField('CODE') == 'PHONE') { //$arCustomer["phone"] = $property->getValue(); } if ($property->getField('CODE') == 'inn') { $arCustomer["inn"] = $property->getValue(); } if ($property->getField('CODE') == 'FIO' || $property->getField('CODE') == 'Name_org') { $arCustomer["full_name"] = $property->getValue(); } } $arReceipt['customer'] = $arCustomer; $deliveryPrice = $order->getDeliveryPrice(); if($deliveryPrice > 0) { $arDelivery = [ "description" => "Доставка", "amount" => [ "value" => $deliveryPrice, "currency" => "RUB" ], "vat_code" => 1, //без НДС "quantity" => 1, "measure" => "piece", "payment_subject" => "service", "payment_mode" => "full_payment" ]; } // Получение объекта корзины заказа $basket = $order->getBasket(); $basketItems = $basket->getBasketItems(); //массив с товарами корзины $arReceiptItems = []; // Получение товаров, их свойств и цен из корзины foreach ($basketItems as $basketItem) { $product_id = $basketItem->getProductId(); $product_name = $basketItem->getField('NAME'); $quantity = $basketItem->getQuantity(); $price = $basketItem->getPrice(); $currency = $basketItem->getCurrency(); $base_price = $basketItem->getBasePrice(); $discount_price = $basketItem->getDiscountPrice(); $arReceiptItems[$product_id] = [ "description" => $product_name, "amount" => [ "value" => $price, "currency" => $currency ], "vat_code" => 4, //НДС 20% "quantity" => $quantity, "measure" => "piece", "payment_subject" => "commodity", "payment_mode" => "full_payment" ]; if (!Loader::includeModule('iblock')) { die('Модуль "iblock" не загружен'); } $arSelect = Array("ID", "NAME", "IBLOCK_ID", "PROPERTY_SupplierName", "PROPERTY_SupplierINN"); $arFilter = Array("ID" => $product_id, "IBLOCK_ID" => 113); $res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect); if($arFields = $res->GetNext()) { $arReceiptItems[$product_id]["supplier"] = [ "name" => preg_replace('/[\x00-\x1F\x7F]/u', '', $arFields["PROPERTY_SUPPLIERNAME_VALUE"]), "inn" => $arFields["PROPERTY_SUPPLIERINN_VALUE"] ]; $arReceiptItems[$product_id]["agent_type"] = "agent"; } else { //нет в ИБ каталога, значит это УСЛУГА $arReceiptItems[$product_id]["vat_code"] = 1; $arReceiptItems[$product_id]["payment_subject"] = "service"; } } $arReceipt['items'] = []; foreach($arReceiptItems as $item) { $arReceipt['items'][] = $item; } if(is_array($arDelivery)) { $arReceipt['items'][] = $arDelivery; } } AddMessage2Log('$arReceipt: ' . print_r($arReceipt, true),''); AddMessage2Log('$arReceipt json_encode: ' . print_r(json_encode($arReceipt), true),''); //отправим чек в YOOKASSA if(!empty($arReceipt["payment_id"]) && !empty($arReceipt['items'])) { //доступы в YOOKASSA $shopId = '423311'; $secretKey = 'live_pz2y1jwcN4svDurXU6s7AK0wp_spGiy3ZUU2SqDC47c'; // Инициализация cURL $ch = curl_init('https://api.yookassa.ru/v3/receipts'); // Настройка опций cURL curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Idempotence-Key: ' . uniqid(), // Уникальный ключ для идемпотентности ]); curl_setopt($ch, CURLOPT_USERPWD, $shopId . ":" . $secretKey); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arReceipt)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Выполняем запрос и получаем ответ $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // Обработка ответа if ($httpCode == 200 || $httpCode == 201) { $receipt = json_decode($response, true); AddMessage2Log('Чек успешно зарегистрирован: ' . print_r($receipt, true),''); } else { AddMessage2Log('Ошибка при регистрации чека: ' . print_r($response, true),''); } } } }
[RuntimeException] 
Could not start session because headers have already been sent. "/home/bitrix/www/local/php_interface/init.php":1. (0)
/home/bitrix/www/bitrix/modules/main/lib/session/session.php:144
#0: Bitrix\Main\Session\Session->start
	/home/bitrix/www/bitrix/modules/main/lib/session/kernelsessionproxy.php:47
#1: Bitrix\Main\Session\KernelSessionProxy->start
	/home/bitrix/www/bitrix/modules/main/include.php:181
#2: require_once(string)
	/home/bitrix/www/bitrix/modules/main/include/prolog_before.php:19
#3: require_once(string)
	/home/bitrix/www/bitrix/modules/main/include/prolog.php:10
#4: require_once(string)
	/home/bitrix/www/bitrix/header.php:1
#5: require(string)
	/home/bitrix/www/catalog/index.php:2
#6: include_once(string)
	/home/bitrix/www/bitrix/modules/main/include/urlrewrite.php:178
#7: include_once(string)
	/home/bitrix/www/bitrix/urlrewrite.php:2
----------