Jump to content
  • Новые сообщения

    • Добрый день! Нужно сделать авторизацию на сайте через смс, а также сохранить вход через почту. Нужно сделать как на ozon.ru. Сколько будет стоить? 

    • В 11.11.2014 в 01:51, ExtraBash сказал:

      Итак вот оно, ребята, новое решение. Третье, обратите внимание!

       

      Нашли несколько несовершенств, связанных с использованием сортировок и иных местах,
      где товар должен учитываться в новой валюте, а все еще спрашивается с базы напрямую в старой.
      На ум пришло новое очень простое решение - хранить в переменной цены именно пересчитанную, 
      а в админке вводить валютную.
       
      ----------------------------------------------------------------------------------------------------
      Если кому нужна установка, тк. несколько человек уже обращались,
      пишите в скайп - abashyrov, цена ориентировочно - 1000р.
      Или могу вам дать доступ на готовые файлы от версии 2.3.6. - 500р.
      Или делаете по инструкции, должно все получиться - Бесплатно.
      ----------------------------------------------------------------------------------------------------
       
      Для тех, кто не знает - нужно сделать, чтобы каждый товар мог быть введен в любой валюте,
      чтобы менять только курс. Повторю, что поставки из разных источников и 1 валюта
      для магазина становится не вариантом, товары будут вводиться в разных валютах.
       
      Поехали:
       
      1. Добавим в таблицу с вариантами товаров соответствующее поле.
      Таблица `s_variants` - новая колонка валюты - `currency`,
      а так-же две новые колонки для хранения исходной величины цены без пересчета в валюту.
      
      
      ALTER TABLE  `s_variants` ADD `currency` TEXT, 
      ADD `base_compare_price` FLOAT( 14, 2 ) AFTER  `compare_price`,
      ADD  `base_price` FLOAT( 14, 2 ) AFTER  `price`

       

       

      2. Так как мы хотим сделать выбор валюты нужно вывести варианты. Я сделал вывод вариантов выпадающим списком в админках товара и товаров. Для этого в первую очередь нужно вызвать список валют в соответствующие шаблоны админки.
      Новое - добавил пересчитанную скидочную цену, все цены - реальные input, которые запишутся в базу,
      переложил пересчет цены при изменении валюты в jquery, не только при перезагрузке изменится сумма.
      Продукт:
       
      Продукты:
       
       
       
      2.1. В файле /api/Variants.php поправим запросы в базу:
      get_variants
      
      
      $query = $this->db->placehold("SELECT v.id, v.product_id , v.price, v.base_price as base_price, NULLIF(v.compare_price, 0) as compare_price, NULLIF(v.base_compare_price, 0) as base_compare_price, v.sku, IFNULL(v.stock, ?) as stock, (v.stock IS NULL) as infinity, v.currency as currency, v.name, v.attachment, v.position
      					FROM __variants AS v
      					WHERE 
      					1
      					$product_id_filter          
      					$variant_id_filter   
      					ORDER BY v.position       
      					", $this->settings->max_order_amount);

      get_variant

      
      
      $query = $this->db->placehold("SELECT v.id, v.product_id , v.price, v.base_price as base_price, NULLIF(v.compare_price, 0) as compare_price, NULLIF(v.base_compare_price, 0) as base_compare_price, v.sku, IFNULL(v.stock, ?) as stock, (v.stock IS NULL) as infinity, v.currency as currency, v.name, v.attachment
      					FROM __variants v WHERE id=?
      					LIMIT 1", $this->settings->max_order_amount, $id);

       

       

      2.2. В файлах /simpla/ProductAdmin.php и /simpla/ProductsAdmin.php добавим:

      
      
      // Все валюты
      $currencies = $this->money->get_currencies();
      $this->design->assign('currencies', $currencies); 
      Это даст нам доступ к массиву $currencies в шаблонах редактирования 1 товара и списка товаров.
      В массиве располагаются все валюты магазина по их id.

       

       

      2.3. Правка шаблона админки одного товара

      2.3.1. В файле /simpla/design/html/product.tpl добавим новые столбцы к варианту товара
      в div id="variants_block" > ul id="header" добавим:
      
      
      <ul id="header">
      	<li class="variant_move"></li>
      	<li class="variant_name">Название варианта</li>	
      	<li class="variant_sku">Артикул</li>	
      	<li class="variant_price">Цена в валюте</li>	
      	<li class="variant_discount">Старая</li>	
      	<li class="variant_currency">Валюта</li>
      	<li class="variant_main_currency">В {$currency->sign}</li>
      	<li class="variant_main_currency">Старая В {$currency->sign}</li>
      	<li class="variant_amount">Кол-во</li>
      </ul>

      Затем новая часть для конкретного варианта:

      
      
      <li class="variant_price"><input name="variants[base_price][]"         type="text"   
      value="{if $variant->base_price}{$variant->base_price|escape}{else}{$variant->price|escape}{/if}" /></li>
      <li class="variant_discount">  <input name="variants[base_compare_price][]" type="text"   value="{if $variant->base_compare_price}{$variant->base_compare_price|escape}{else}{$variant->compare_price|escape}{/if}" /></li>
      <li class="variant_currency">
      	<select type="text" name="variants[currency][]">
      		{foreach $currencies as $c}
      			<option
      			{if $variant->currency}
      				{if $variant->currency == $c->id}
      					selected
      				{/if}
      			{else}
      				{if $currency->id == $c->id}
      					selected
      				{/if}
      			{/if} mnozhitel="{$c->rate_to/$c->rate_from}" value="{$c->id}">{$c->code}  ({$c->rate_to/$c->rate_from})</option>
      		{/foreach}
      	</select>
      </li>
      <li class="variant_main_currency"><div class="op_cover"></div><input name="variants[price][]" type="text"   value="{if $variant->currency}{if $variant->base_price}{$variant->base_price*$currencies[$variant->currency]->rate_to/$currencies[$variant->currency]->rate_from|escape}{else}{$variant->price*$currencies[$variant->currency]->rate_to/$currencies[$variant->currency]->rate_from|escape}{/if}{else}{$variant->price}{/if}" /></li>
      <li class="variant_main_currency_discount"><div class="op_cover"></div><input name="variants[compare_price][]" type="text"   value="{if $variant->currency}{if $variant->base_compare_price}{$variant->base_compare_price*$currencies[$variant->currency]->rate_to/$currencies[$variant->currency]->rate_from|escape}{else}{$variant->compare_price*$currencies[$variant->currency]->rate_to/$currencies[$variant->currency]->rate_from|escape}{/if}{else}{$variant->compare_price}{/if}" /></li>
      

       

      2.3.2. В том-же файле добавим jquery код - наверху страницы, часть кода, 
      отвечающая за события вниз функции после загрузки, функцию отдельно к функциям:
      
      
      //Пересчет цен товара и скидочных цен
      $('.variant_currency > select').change(function(){
      	recount_Price( this );
      });
      $('.variant_price > input, .variant_discount > input').focusout(function(){
      	recount_Price($(this).parents('ul').find('.variant_currency > select'));
      });

      Чуть ниже, после закрытия функции, где лежат остальные функции:

      
      
      //Пересчет цен товара и скидочных цен
      function recount_Price(selected_curr){
          var mnozhitel = $("option:selected", selected_curr).attr('mnozhitel');
          var ul = $(selected_curr).parents('ul');
          var Counted_price = 
          parseFloat($(ul).find('.variant_price > input').val()) * parseFloat(mnozhitel);
          $(ul).find('.variant_main_currency > input').val(Counted_price);
          Counted_price = parseFloat($(ul).find('.variant_discount > input').val()) * parseFloat(mnozhitel);
          $(ul).find('.variant_main_currency_discount > input').val(Counted_price);
      };

       

      2.3.3. Добавим новые стили в /simpla/design/css/style.css:

      
      
      .variant_currency {
      width: 111px;
      }
      .variant_currency > select {
      padding: 4px;
      height: 27px;
      }
      li.variant_main_currency, .variant_main_currency_discount {
      width: 93px;
      text-align: left;
      margin-right: 19px;
      }
      li.variant_main_currency input, .variant_main_currency_discount input {
          width: 87px;
          background-color: rgb(223, 223, 223);
          border: 2px solid lightgrey;
      }
      .op_cover {
          position: absolute;
          width: 93px;
          height: 27px;
      }
      #variants_block li.variant_download {
          width: 50px;
      }

       

       

      2.4. Добавим аналогичный функционал в шаблон для нескольких товаров
      2.4.1. Правим /simpla/design/html/products.tpl - внутри div.variants mtyztv гд на новый,
      тут выводятся валюты, два окошка input, всё красиво, все дела
      
      
      <ul>
      {foreach $product->variants as $variant}
      <li {if !$variant@first}class="variant" style="display:none;"{/if}>
      	<i title="{$variant->name|escape}">{$variant->name|escape|truncate:30:'…':true:true}</i>
      	
      	<input class="price {if $variant->compare_price>0}compare_price{/if}" 
      	type="text" 
      	name="base_price[{$variant->id}]" 
      	value="{if $variant->base_price}{$variant->base_price}{else}{$variant->price}{/if}" 
      	{if $variant->base_compare_price>0}title="Старая цена — {$variant->base_compare_price} {$currency->sign}"{elseif $variant->compare_price>0}title="Старая цена — {$variant->compare_price} {$currency->sign}"{/if} />
      	
      	<select class="products_currency" type="text" name="v_currency[{$variant->id}]">
      		{foreach $currencies as $c}
      			<option
      			{if $variant->currency}
      				{if $variant->currency == $c->id}
      					selected
      				{/if}
      			{else}
      				{if $currency->id == $c->id}
      					selected
      				{/if}
      			{/if}  mnozhitel="{$c->rate_to/$c->rate_from}" value="{$c->id}">{$c->code}  ({$c->rate_to/$c->rate_from})</option>
      		{/foreach}
      	</select>
      	<br/>
      	
              <div class="old_wrap">
      	<div class="old_price">
      	<div class="op_cover"
      	{if $variant->compare_price>0}title="Старая цена — {$variant->compare_price} {$currency->sign}"{elseif $variant->base_compare_price>0}title="Старая цена — {$variant->base_compare_price} {$currency->sign}"{/if}></div>
      	<input  
      	type="text" 
      	name="price[{$variant->id}]" 
      	value="{if $variant->currency}{if $variant->base_price}{$variant->base_price*$currencies[$variant->currency]->rate_to/$currencies[$variant->currency]->rate_from|escape}{else}{$variant->price*$currencies[$variant->currency]->rate_to/$currencies[$variant->currency]->rate_from|escape}{/if}{else}{$variant->price}{/if}"/>	
      	</div>
      	
      	<input class="stock" type="text" name="stock[{$variant->id}]" value="{if $variant->infinity}?{else}{$variant->stock}{/if}" /><span class="v_unit">{$settings->units}</span>
              </div>
      </li>
      {/foreach}
      </ul>

      Внутри div#action добавим новый пункт для массового изменения валюты

      
      
      <span id="select">
      <select class="action_sel" name="action">
      	<option value="enable">Сделать видимыми</option>
      	<option value="disable">Сделать невидимыми</option>
      	<option value="set_featured">Сделать рекомендуемым</option>
      	<option value="unset_featured">Отменить рекомендуемый</option>
      	<option value="duplicate">Создать дубликат</option>
      	{if $pages_count>1}
      	<option value="move_to_page">Переместить на страницу</option>
      	{/if}
      	{if $categories|count>1}
      	<option value="move_to_category">Переместить в категорию</option>
      	{/if}
      	{if $brands|count>0}
      	<option value="move_to_brand">Указать бренд</option>
      	{/if}
      	<option value="delete">Удалить</option>
      	<option value="change_currency">Изменить валюту</option>
      </select>
      
      <select disabled class="currencies_sel" name="currencies" style="display: none;">
      	<option disabled selected value="0">Не менять</option>
      	{foreach $currencies as $c}
      		<option value="{$c->id}">{$c->code} ({if $c->code != "RUR"}{$c->rate_to}{else}1{/if})</option>
      	{/foreach}
      </select>
      

       

      2.4.2. В том-же файле /simpla/design/html/products.tpl добавим нужные скрипты внизу:

      
      
      // Работа с валютами
      	$('input.price').focusout(function() {
      		recount_Price( $(this).parents('li').find('select.products_currency'));
      	});
      	
      	$('select.products_currency').change(function() {
      		recount_Price(this);
      	});
      
      	function recount_Price(selected_curr){
      		var mnozhitel = $("option:selected", selected_curr).attr('mnozhitel');
      		var base_price = $(selected_curr).parents('li').find('input.price').val();
      		var price_container = $(selected_curr).parents('li').find('.old_price > input');
      		var Counted_price = parseFloat(base_price) * parseFloat(mnozhitel);
      		price_container.val(Counted_price);
      	};
      	
      	$('select.action_sel').change(function (){
      	if ($("option:selected", this).val() == "change_currency")
      		{
      			$("select.currencies_sel").fadeIn();
      			$("select.currencies_sel").prop( "disabled", false );
      		}
      	else 
      		{
      			$("select.currencies_sel").fadeOut();
      			$("select.currencies_sel").prop( "disabled", true );
      		}
      	});
      	 
      	$('select.currencies_sel').change(function () {
      	if ($("option:selected", this).val() != "0")
      	{
      		var sel_opt = ( "'" + $("option:selected", this).val() + "'" ) ;
      		$( '.row' ).each(function() {
      			if ($(this).find('input[type="checkbox"]').prop("checked"))
      			{
      				$(this).find('li').each(function() {
      				    var row_sel = $(this).find('select.products_currency');
      					$("option[value=" + sel_opt + "]", row_sel).prop("selected", true);
      					row_sel.change();
      				});
      			}
      		});
      	}
      	});

       

      2.4.3. Правим обработку переменных в /simpla/ProductsAdmin.php

      
      
      // Сохранение цен и наличия
      			$prices = $this->request->post('price');
      			$base_prices = $this->request->post('base_price');
      			$stocks = $this->request->post('stock');
      			$v_currencies = $this->request->post('v_currency');
      		
      			foreach($prices as $id=>$price)
      			{
      				$base_price = $base_prices[$id];
      				$stock = $stocks[$id];
      				$v_currency = $v_currencies[$id];
      				if($stock == '?' || $stock == '')
      					$stock = null;
      					
      				$this->variants->update_variant($id, array('price'=>$price, 'base_price'=>$base_price,'stock'=>$stock, 'currency'=>$v_currency));
      			}

       

      2.4.4. Добавим новые стили в /simpla/design/css/style.css:

      
      
      .old_price > input {
          float: left;
          width: 80px;
          text-align: right;
          background-color: rgb(223, 223, 223);
          border: 2px solid lightgrey;
      }
      .old_price > .op_cover {
          width: 84px;
          height: 21px;
      }
      #list .variants ul .stock {
          float: left;
          margin-left: 6px;
      }
      select.products_currency {
          height: 22px;
          padding: 2px;
          margin-bottom: 5px;
      }
      span.v_unit {
          float: left;
          margin-top: 3px;
      }
      .old_wrap {
           float: right;
          width: 182px;
      }

       

       

      2.5. Решение проблемы обновления расчетных цен на сайте.

      (кто использовал старое - Функцию update_currency в api/Money.php меняем на стандартную)


      Будем менять /simpla/CurrencyAdmin.php

       

      При обновлении измененной валюты обновим и все варианты с такой-же валютой,

      начало и конец заменяемого кода обрамлены неизменными частями кода, обратите внимание, в 2.3.6

      самое начало кода выглядит не совсем так, так что отчеркрутое слешами не советую копировать:

      
      
      foreach($this->request->post('currency') as $n=>$va)
      	foreach($va as $i=>$v)
      		$currencies[$i]->$n = $v;
      
      //////////////////////////////////////////////////////////////
      
      $currencies_ids = array();
      foreach($currencies as $currency)
      {
      	if($currency->id)
      	{
      		$this->money->update_currency($currency->id, $currency);
      		$this->db->query("UPDATE __variants SET price=base_price*? WHERE currency=?"  , $currency->rate_to/$currency->rate_from, $currency->id);
      	}
      	else
      		$currency->id = $this->money->add_currency($currency);
      	$currencies_ids[] = $currency->id;
      }
      
      //////////////////////////////////////////////////////////////
      
      // Удалить непереданные валюты
      $query = $this->db->placehold('DELETE FROM __currencies WHERE id NOT IN(?@)', $currencies_ids);
      $this->db->query($query);

       

       

       

      3. Импорт - Экспорт
      Осталась небольшая часть, как сделать импорт и экспорт сия чуда.
      Очень просто.
       
      3.1. Правим /simpla/ajax/export.php - добавляем новую колонку для экспорта в
      объявлении массива $columns_names:
      
      
      	private $columns_names = array(
      			'category'=>         'Категория',
      			'name'=>             'Товар',
      			'price'=>            'Цена',
      			'currency'=>         'Валюта',
      			'url'=>              'Адрес',
      			'visible'=>          'Видим',
      			'featured'=>         'Рекомендуемый',
      			'brand'=>            'Бренд',
      			'variant'=>          'Вариант',
      			'compare_price'=>    'Старая цена',
      			'sku'=>              'Артикул',
      			'stock'=>            'Склад',
      			'meta_title'=>       'Заголовок страницы',
      			'meta_keywords'=>    'Ключевые слова',
      			'meta_description'=> 'Описание страницы',
      			'annotation'=>       'Аннотация',
      			'body'=>             'Описание',
      			'images'=>           'Изображения'
      			);

      Ниже добавляем аналогично данные в соответствующую переменную, обратите внимание на цену:

      
      
      if(isset($products[$variant->product_id]))
      {
      	$v                    = array();
      	$v['variant']         = $variant->name;
      	$v['price']           = $variant->price;
      	$v['currency'] 		  = $variant->currency;
      		
      	if ($variant->base_price)
      		$v['price']           = $variant->base_price;
      	else
      		$v['price']           = $variant->price;
      		
      	if ($variant->base_price)
      		$v['base_compare_price']           = $variant->base_compare_price;
      	else
      		$v['compare_price']   = $variant->compare_price;
      		
      	$v['sku']             = $variant->sku;
      	$v['stock']           = $variant->stock;
      	if($variant->infinity)
      		$v['stock']           = '';
      	$products[$variant->product_id]['variants'][] = $v;
      }

       

      3.2. Правим /simpla/ajax/import.php - колонки:

      
      
      	// Соответствие полей в базе и имён колонок в файле
      	private $columns_names = array(
      			'name'=>             array('product', 'name', 'товар', 'название', 'наименование'),
      			'url'=>              array('url', 'адрес'),
      			'visible'=>          array('visible', 'published', 'видим'),
      			'featured'=>         array('featured', 'hit', 'хит', 'рекомендуемый'),
      			'category'=>         array('category', 'категория'),
      			'brand'=>            array('brand', 'бренд'),
      			'variant'=>          array('variant', 'вариант'),
      			'price'=>            array('price', 'цена'),
      			'currency'=>         array('currency', 'валюта'),
      			'compare_price'=>    array('compare price', 'старая цена'),
      			'sku'=>              array('sku', 'артикул'),
      			'stock'=>            array('stock', 'склад', 'на складе'),
      			'meta_title'=>       array('meta title', 'заголовок страницы'),
      			'meta_keywords'=>    array('meta keywords', 'ключевые слова'),
      			'meta_description'=> array('meta description', 'описание страницы'),
      			'annotation'=>       array('annotation', 'аннотация', 'краткое описание'),
      			'description'=>      array('description', 'описание'),
      			'images'=>           array('images', 'изображения')
      			); 

      Ниже заменяем обработки price и compare_price и добавляем обработку валют и цен, что позволит записать сразу во все 4 переменные необходимые данные, сразу пересчитывая из нужной валюты:

      
      
      // Подготовим вариант товара
      if(isset($item['variant']))
      	$variant['name'] = trim($item['variant']);
      	
      if(isset($item['currency']))
      	if($item['currency'] == '')
      		$variant['currency'] = null;
      	else
      		{
      		$variant['currency'] = str_replace(',', '.', trim($item['currency']));
      		$currency = $this->money->get_currency(intval($variant['currency']));
      		}
      
      if(isset($item['price']))
      	{
      	$variant['base_price'] = str_replace(',', '.', trim($item['price']));
      	if ($currency)
      		$variant['price'] = floatval($variant['base_price'])*$currency->rate_to/$currency->rate_from;
      	else 
      		$variant['price'] = $variant['base_price'];
      	}
      
      if(isset($item['compare_price']))
      	{
      	$variant['base_compare_price'] = str_replace(',', '.', trim($item['compare_price']));
      	if ($currency)
      		$variant['compare_price'] = floatval($variant['base_compare_price'])*$currency->rate_to/$currency->rate_from;
      	else 
      		$variant['compare_price'] = $variant['base_compare_price'];
      	}

       

      В файле импорта добавляется всего одна колонка - Валюта, все остальное как было.

      Цены писать НЕ пересчитанные.

      Обратите внимание, что валюты у вас уже должны быть на сайте и следите за айди валюты.

          

       

      Всё, на этом всё.
      У меня все прекрасно работает, если чего - пишите.

      Данный код использует максимум стандартного из симплы,
      поэтому все сортировки и все дела работают.
      Спасибо Kors за найденные несовершенства.

      ------------------------------------------------------------

      Продали клиенту, или порадовались сами - буду рад, если поделитесь бабулями - +7 937 204-69-07 Киви

      Жесть, вместо того чтобы добавить 1 поле по которому просто делать сортировку и хранить там одно значение (цену в рублях например), сделано 2 поля + куча ненужных правок кода. По умолчанию в этом модуле, в админке, даже есть поле с ценой в рублях, им и можно обновлять базу, но кто-то не ищет легких путей.

      Edited by a13x
    • 18 минут назад, shooroop сказал:

      автомобиль = мотор = кожанный салон/велюровый салон ?

      красавчик, ты меня понимаешь ?

       

      p.s. смалики с 1-ого раза не ставятся, косяк форума

      Edited by a13x
    • 2 часа назад, a13x сказал:

      шаблонизатор = смарти = шаблон?

      автомобиль = мотор = кожанный салон/велюровый салон ?

    • 1 час назад, Noxter сказал:

      Почти оно.

      что не так?

  • Новые темы

  1. Simpla CMS

    1. Новости Simpla CMS

      Официальные новости от автора Simpla CMS

      1.2k
      posts
    2. Предложения по развитию Simpla CMS

      Обсуждение идей и предложений по дальнейшему развитию Simpla

      433
      posts
    3. Общие вопросы по функционалу и дизайну

      Здесь обсуждаются общие вопросы, которые касаются CMS Simpla

      60.2k
      posts
    4. Готовые решения

      В этом разделе выложены готовые бесплатные решения (доработки).

      10.7k
      posts
    5. Безопасность

      В разделе освещаются вопросы связанные с безопасностью Simpla CMS. Уязвимости, проблемы с разделением прав и прочее

      7.5k
      posts
  2. Дизайн и шаблоны

    1. Бесплатные шаблоны

      В этой категории выкладываем бесплатные шаблоны.

      726
      posts
    2. Платные шаблоны

      В этой категории выкладываем платные шаблоны.

      2.5k
      posts
  3. Платные модули и услуги

    1. Платные модули и услуги

      Готовые платные модули от программистов и дизайнеров: Модули, шаблоны, доработки, программы

      3.9k
      posts
    2. Отзывы о исполнителях и заказчиках (ex. Фриланс)

      Обсуждение исполнителей и заказчиков, "черные" списки форума и всё что связанно с фрилансом

      1.4k
      posts
    3. Продвижение и поисковая оптимизация (SEO)

      Вопросы и платные услуги по тематике SEO

      470
      posts
  4. Разное

    1. 442
      posts
    2. Обсуждение хостингов

      Обсуждение хостинг-компаний. Название обсуждения должно быть названием хостинга.

      309
      posts
    3. Разные скрипты магазинов

      Обсуждение различных движков магазинов

      373
      posts
×
×
  • Create New...