Малый бизнес, а нужен еще один тип цен

Редакция "Малый бизнес" позволяет иметь только один тип цен, но что делать, если нужно два? Вариантов много, начиная со скрещивания демо-версии редакции "Бизнес" с текущей редакцией вплоть до повышения редакции. 
Первый вариант мне не очень нравится, есть некоторая вероятность нарваться на проблемы с обновлениями. 
Второй вариант кажется неразумным - из-за одного типа цен платить двойную стоимость лицензии, это уж слишком. 

Внимание! Использование обработчика onGetOptimalPrice может быть более простым вариантом!

А суть задачи такая - на сайте заведены товары с оптовым типом цен ["BASE"], а теперь понадобилась розница. То есть пользователь регистрируется и видит по умолчанию розничный тип цен, а получив права на доступ к оптовым ценам видит уже их. 

Первое что я делаю - завожу группу пользователей "Оптовые цены" и добавляю пользователям параметры ИНН, КПП, название организации - по их заполнению будет приниматься решение администратором о внесении пользователя в группу "Оптовые цены". 

Затем в инфоблоке каталога добавляю новое свойство "RETAIL_PRICE". 

Далее, что касается отображения цен в каталоге. В моем случае цены можно посмотреть только в карточке товара. Поэтому в result_modifier.php компонента прописываю такой код:
global $USER;
$arGroups = CUser::GetUserGroup($USER->GetID());
$arResult["OPT"] = (in_array(5, $arGroups)) ? true : false;

Это позволит нам по ключу "OPT" определить, имеет ли пользователь доступ к оптовым ценам. А в template.php я пишу примерно так:
<?if($USER->IsAuthorized()):?>
   <?if($arResult["OPT"]): // if user has access to opt price?>
      <b>Цена за шт.:</b> <?=$arResult["OFFERS"][$keyOff]["PRICES"]["BASE"]["PRINT_VALUE_VAT"];?>
   <?elseif($iPrice = $arResult["PROPERTIES"]["RETAIL_PRICE"]["VALUE"]):?>
      <b>Цена за шт.:</b> <?=number_format($iPrice, 2, '.', ' ');?> руб.
   <?endif;?>
<?endif;?>

Цены показываем только авторизованным пользователям. 

Второе сложнее - нужно отредактировать компонент корзины (sale.basket.basket), что бы пользователь видел правильные цены. Здесь result_modifier.php получается немного больше, т.к. нужно отменить вывод нового свойства:
global $USER;
$arGroups = CUser::GetUserGroup($USER->GetID());
$arResult["OPT"] = (in_array(5, $arGroups)) ? true : false;

// Del retail price from headers
foreach($arResult["GRID"]["HEADERS"] as $id => $arHeader) {
   if($arHeader["id"] == "PROPERTY_RETAIL_PRICE_VALUE") {
      unset($arResult["GRID"]["HEADERS"][$id]);
   }
}

// Calc full sum
if(!$arResult["OPT"]) {
   $iPriceSum = 0;
   
   foreach($arResult["GRID"]["ROWS"] as $k=>$arItem) {
      if($arItem["DELAY"] == "N" && $arItem["CAN_BUY"] == "Y") {
         $iPriceSum += $arItem["QUANTITY"] * $arItem["PROPERTY_RETAIL_PRICE_VALUE"];
      }
   }
}
$arResult["allSum_FORMATED"] = number_format($iPriceSum, 0, '.', ' ')." руб.";

А в template.php, точнее basket_items.php (в basket_items_delayed.php делаю тоже самое):
<?if($arResult["OPT"]):?>
   <div class="current_price" id="current_price_<?=$arItem["ID"]?>" data-price="<?=$arItem["PRICE"]?>">
      <?=$arItem["PRICE_FORMATED"]?>
   </div>

   <?if ($bPriceType && strlen($arItem["NOTES"]) > 0):?>
      <div class="type_price"><?=GetMessage("SALE_TYPE")?></div>
      <div class="type_price_value"><?=$arItem["NOTES"]?></div>
   <?endif;?>

<?elseif($arItem["PROPERTY_RETAIL_PRICE_VALUE"]):?>
   <div class="current_price" id="current_price_<?=$arItem["ID"]?>" data-price="<?=$arItem["PROPERTY_RETAIL_PRICE_VALUE"]?>">
      <?=number_format($arItem["PROPERTY_RETAIL_PRICE_VALUE"]*$arItem["QUANTITY"], 0, '.', ' ');?> руб.
   </div>

   <?if ($bPriceType && strlen($arItem["NOTES"]) > 0):?>
      <div class="type_price"><?=GetMessage("SALE_TYPE")?></div>
      <div class="type_price_value">Розничная цена</div>
   <?endif;?>
   
<?endif;?>

А вот теперь задачка посложнее. Когда пользователь меняет количество товара через AJAX запрашиваются новые данные и обновляются, в конечно итоге внешний вид корзины меняется функцией updateBasketTable из файла script.js шаблона корзины. Я бы предпочел её переписать, но из соображений совместимости просто допишу свой код в конец функции, по счастливому стечению обстоятельств на jQuery :) просто с BX пока не разобрался... или не разбирался. Итак, вот что я пишу:
if (BX('PRICE_WITHOUT_DISCOUNT'))
      BX('PRICE_WITHOUT_DISCOUNT').innerHTML = (res['BASKET_DATA']['PRICE_WITHOUT_DISCOUNT'] != res['BASKET_DATA']['allSum_FORMATED']) ? res['BASKET_DATA']['PRICE_WITHOUT_DISCOUNT'].replace(/\s/g, ' ') : '';
   
   // For retail updated. My function
   var iPriceFull = 0;
   
   $("#basket_items .item-line").each(function() {
      var qPrice      = $(this).find(".current_price"),
         iCount      = $(this).find(".counter input").val(),
         iPrice      = parseFloat(qPrice.attr("data-price")),
         iPriceThis   = iCount * iPrice,
         sPriceThis   = String(iPriceThis),
         sPriceThisF   = sPriceThis.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ') + " руб.";
      
      iPriceFull  = iPriceFull + iPriceThis;
      
      $(this).find(".current_price").text(sPriceThisF);
   });
   
   var sPriceFull   = String(iPriceFull),
      sPriceFullF   = sPriceFull.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ') + " руб.";
   
   $("#allSum_FORMATED").text(sPriceFullF);
}

Теперь осталось оформить аналогичным образом шаблон компонента sale.order.ajax и в целом готово. Да, заказы на сайте будут собираться с оптовыми ценами. Но мы можем через обработчик дописать в комментарий к заказу, что заказ был сделан по розничным ценам.