Перейти к содержанию
Официальный форум поддержки Simpla

дополнительные чекбоксы в карточке товара


Рекомендуемые сообщения

CREATE TABLE `s_properties` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`product_id` int NOT NULL,
`name` varchar(255) NOT NULL,
`price` decimal(10,2) NOT NULL
) COMMENT='';

ALTER TABLE `s_properties`
ADD INDEX `product_id` (`product_id`);

ALTER TABLE `s_purchases`
ADD `properties` varchar(255) COLLATE 'utf8_general_ci' NOT NULL AFTER `variant_name`,
COMMENT='';

Выполняем запрос в php admin и добавляем новый файл в api/

 

Properties.php

 

Итак поехали, требовалась функция, чтоб к товару при добавлении можно было добавить доп услуги ( в моем случае ингридиенты) Для этого и было сделано данное дополнение. Результат смотрите на скриншотах. Выбранный чекбокс сумируется стоимости товара.

Данную разработку можно использовать " нужна ли упаковка" и виды упаковки. И т.д.

Разработка сырая. Тестировал находил некоторые нюансы.

 

это в админке

 

 

в карточке товара

 
 
В корзине
 

 

 

1. api/Simpla.php

находим строку:

'notify'     => 'Notify',

и вставляем 

 

'properties'     => 'Properties',

 

2. simpla/ProductAdmin.php

 

находим:

	// Связанные товары
	   	    		$query = $this->db->placehold('DELETE FROM __related_products WHERE product_id=?', $product->id);

выше  пишем:

 

 

// удаляем старые значения
					$this->properties->delete_property($product->id);
					// добавляем новые
					$new_properties_names = $this->request->post('new_properties_names');
					$new_properties_values = $this->request->post('new_properties_values');
					if(is_array($new_properties_names) && is_array($new_properties_values))
					{
						foreach($new_properties_names as $k=>$name)
						{
							$price = trim($new_properties_values[$k]);
							if(!empty($name) && !empty($price))
							{
								$this->properties->add_property( array('name' => $name, 'price' => $price, 'product_id' => $product->id ) );
							}
						}
					}
					
					// отображаем
					$properties = $this->properties->get_properties(array('product_id' => $product->id ));

тут же находим:

 

// Изображения товара
$images = $this->products->get_images(array('product_id'=>$product->id));

пишем ниже:

$properties = $this->properties->get_properties(array('product_id' => $product->id ));

тут же находим:

 

$this->design->assign('product', $product);

ниже ставим:

 

$this->design->assign('properties', $properties);

 

3. simpla/design/html/product.tpl

 

находим:

 

// Добавление нового свойства товара
	var new_feature = $('#new_feature').clone(true);
	$('#new_feature').remove().removeAttr('id');
	$('#add_new_feature').click(function() {
		$(new_feature).clone(true).appendTo('ul.new_features').fadeIn('slow').find("input[name*=new_feature_name]").focus();
		return false;		
	});

ниже пишем:

 

// добавление параметра
	var new_property = $('#new_property').clone(true);
	$('#new_property').remove();
	$('#add_new_property').click(function() {
		$(new_property).clone(true).appendTo('ul.new_properties').fadeIn('slow').find("input[name*=new_properties_name]").focus();
		return false;		
	});

4.view/ProductView.php

 

находим:

 

$comments = $this->comments->get_comments(array('type'=>'product', 'object_id'=>$product->id, 'approved'=>1, 'ip'=>$_SERVER['REMOTE_ADDR']));

ниже пишем:

 

$properties = $this->properties->get_properties( array('product_id' => $product->id) );
		$this->design->assign('properties', $properties);

 

5. design/default/html/product.tpl  (default - используемая тема шаблона)

 

находим:

 

<input type="submit" class="button" value="в корзину" data-result-text="добавлено"/>

выше вставляем:

 

<div id="properties">
			{foreach $properties as $val}
				<label"><input type="checkbox" name="properties[$product->id]" value="{$val->id}">{$val->name} (+{$val->price|convert} {$currency->sign|escape})</label>
			{/foreach}
			</div>

6. design/default/js/ajax_cart.js  (default - используемая тема шаблона)

 

находим:

if($(this).find('input[name=variant]:checked').size()>0)
		variant = $(this).find('input[name=variant]:checked').val();
	if($(this).find('select[name=variant]').size()>0)
		variant = $(this).find('select').val();

ниже пишем:

 

var properties = new Array();
		$(this).find("input[name='properties[]']:checked").each(function (i, o) { 
			properties.push( $(o).val() ); 
		});

тут же ищем:

 

data: {variant: variant},

заменяем на :

 

data: {variant: variant, properties: properties},

 

7. api/Cart.php

 

находим код:

 

public function add_item($variant_id, $amount = 1)
	{ 
		$amount = max(1, $amount);
	
		if(isset($_SESSION['shopping_cart'][$variant_id]))
      		$amount = max(1, $amount+$_SESSION['shopping_cart'][$variant_id]);

		// Выберем товар из базы, заодно убедившись в его существовании
		$variant = $this->variants->get_variant($variant_id);

		// Если товар существует, добавим его в корзину
		if(!empty($variant) && ($variant->stock>0) )
		{
			// Не дадим больше чем на складе
			$amount = min($amount, $variant->stock);
	     
			$_SESSION['shopping_cart'][$variant_id] = intval($amount); 
		}
	}

заменяем на:

 

public function add_item($variant_id, $amount = 1, $properties = array() )
	{ 
		$amount = max(1, $amount);
	
		if(isset($_SESSION['shopping_cart'][$variant_id]))
      		$amount = max(1, $amount+$_SESSION['shopping_cart'][$variant_id]);

		// Выберем товар из базы, заодно убедившись в его существовании
		$variant = $this->variants->get_variant($variant_id);

		// Если товар существует, добавим его в корзину
		if(!empty($variant) && ($variant->stock>0) )
		{
			// Не дадим больше чем на складе
			$amount = min($amount, $variant->stock);
	     
			$_SESSION['shopping_cart'][$variant_id] = intval($amount); 
			
			if( !empty( $properties ) ) {
				foreach( $properties as $p ) {
					$property = $this->properties->get_property( $p );
					$_SESSION['shopping_properties'][$variant_id][] = array('id' => $property->id, 'name' => $property->name, 'price' => $property->price);
				}
			}
			
			
		}
	}

В этом же файле заменяем всю функцию 

 

public function get_cart() 
{ 
	... 
}

на 

 

public function get_cart()
	{
		$cart = new stdClass();
		$cart->purchases = array();
		$cart->total_price = 0;
		$cart->total_products = 0;
		$cart->coupon = null;
		$cart->discount = 0;
		$cart->coupon_discount = 0;

		// Берем из сессии список variant_id=>amount
		if(!empty($_SESSION['shopping_cart']))
		{
			$session_items = $_SESSION['shopping_cart'];
			
			$session_properties = $_SESSION['shopping_properties'];

			
			$variants = $this->variants->get_variants(array('id'=>array_keys($session_items)));
			if(!empty($variants))
			{
 
				foreach($variants as $variant)
				{

					if( !empty( $session_properties[$variant->id] ) ) {
						$price = 0;
						foreach( $session_properties[$variant->id] as $i )
							$price += $i['price'];
							
						$variant->price = $variant->price+$price;
					}
					
					$items[$variant->id] = new stdClass();
					$items[$variant->id]->variant = $variant;
					$items[$variant->id]->amount = $session_items[$variant->id];
					
					$items[$variant->id]->properties = $session_properties[$variant->id];
					
					$products_ids[] = $variant->product_id;
				}
	
				$products = array();
				foreach($this->products->get_products(array('id'=>$products_ids, 'limit' => count($products_ids))) as $p)
					$products[$p->id]=$p;
				
				$images = $this->products->get_images(array('product_id'=>$products_ids));
				foreach($images as $image)
					$products[$image->product_id]->images[$image->id] = $image;
			
				$properties_price = 0;
				foreach($items as $variant_id=>$item)
				{
					$purchase = null;
					if(!empty($products[$item->variant->product_id]))
					{
						$purchase = new stdClass();
						$purchase->product = $products[$item->variant->product_id];						
						$purchase->variant = $item->variant;
						$purchase->amount = $item->amount;

						$purchase->properties = $item->properties;
						if( $item->properties )
							foreach( $item->properties as $i )
								$properties_price += $i['price'];

						$cart->purchases[] = $purchase;
						$cart->total_price += $item->variant->price*$item->amount;
						$cart->total_products += $item->amount;
					}
				}
				
				// Пользовательская скидка
				$cart->discount = 0;
				if(isset($_SESSION['user_id']) && $user = $this->users->get_user(intval($_SESSION['user_id'])))
					$cart->discount = $user->discount;
					
				$cart->total_price *= (100-$cart->discount)/100;
				
				// Скидка по купону
				if(isset($_SESSION['coupon_code']))
				{
					$cart->coupon = $this->coupons->get_coupon($_SESSION['coupon_code']);
					if($cart->coupon && $cart->coupon->valid && $cart->total_price>=$cart->coupon->min_order_price)
					{
						if($cart->coupon->type=='absolute')
						{
							// Абсолютная скидка не более суммы заказа
							$cart->coupon_discount = $cart->total_price>$cart->coupon->value?$cart->coupon->value:$cart->total_price;
							$cart->total_price = max(0, $cart->total_price-$cart->coupon->value);
						}
						else
						{
							$cart->coupon_discount = $cart->total_price * ($cart->coupon->value)/100;
							$cart->total_price = $cart->total_price-$cart->coupon_discount;
						}
					}
					else
					{
						unset($_SESSION['coupon_code']);
					}
				}
				
			}
		}
			
		return $cart;
	}

в этом же файле находим

 

unset($_SESSION['shopping_cart']);

и ниже пишем 

 

unset($_SESSION['shopping_properties']);

 

тут же находим 

 

unset($_SESSION['shopping_cart'][$variant_id]); 

и ниже вставляем 

 

unset($_SESSION['shopping_properties']);

 

9. ajax/cart.php

 

находим:

 

$simpla->cart->add_item($simpla->request->get('variant', 'integer'), $simpla->request->get('amount', 'integer'));

и меняем на :

 

$simpla->cart->add_item($simpla->request->get('variant', 'integer'), $simpla->request->get('amount', 'integer'), $simpla->request->get('properties'));

 

10. view/CartView.php

 

находим:

 

$this->cart->add_item($variant_id, $this->request->get('amount', 'integer'));

 

меняем на:

 

$this->cart->add_item($variant_id, $this->request->get('amount', 'integer'), $this->request->get('properties'));

 

11. design/default/html/cart.tpl (default - используемая тема шаблона)

 

после 

 

<td class="name">
		<a href="products/{$purchase->product->url}">{$purchase->product->name|escape}</a>
		{$purchase->variant->name|escape}	

 

пишем

 

<div>
			{if $purchase->properties}
				{foreach $purchase->properties as $property}
					{$property['name']} (+{$property['price']|convert} {$currency->sign|escape}) <br>
				{/foreach}
			{/if}
		</div>

 

12. api\Orders.php

 

найти:

 

	{
		$purchase = (object)$purchase;
		if(!empty($purchase->variant_id))
		{
			$variant = $this->variants->get_variant($purchase->variant_id);
			if(empty($variant))
				return false;
			$product = $this->products->get_product(intval($variant->product_id));
			if(empty($product))
				return false;
		}	

ниже вставить:

 

$price = 0;
		if( !empty( $_SESSION['shopping_properties'][intval($variant_id)] ) ) {
			foreach( $_SESSION['shopping_properties'][intval($variant_id)] as $i ) 
				$variant->price = $variant->price += $i['price'];
		}

13. view\CartView.php

 

находим:

 

$this->orders->add_purchase(array('order_id'=>$order_id, 'variant_id'=>intval($variant_id), 'amount'=>intval($amount)));

заменяем на

 

$properties_text = '';
				if( $properties = $_SESSION['shopping_properties'][intval($variant_id)] ) {
					foreach( $properties as $property )
						$properties_text[] = $property['name'];
				}
				if( $properties_text ) $properties_text = implode( '|||', $properties_text );
				
	    		$this->orders->add_purchase(array('order_id'=>$order_id, 'variant_id'=>intval($variant_id), 'amount'=>intval($amount), 'properties'=> $properties_text ));

 

14. design/default/html/order.tpl (default - используемая тема шаблона)

 

находим :

 

{if $order->paid && $purchase->variant->attachment}
			<a class="download_attachment" href="order/{$order->url}/{$purchase->variant->attachment}">скачать файл</a>
		{/if}

ниже пишем:

 

	{assign var="result" value="|||"|explode:$purchase->properties}
		{if $result}
		<div style="font-size: 13px;">
		{foreach $result as $r}
			<br>+ {$r}
		{/foreach}
		</div>
		{/if}

 

15. simpla/design/html/order.tpl

 

находим :

 

{if $purchase->product}
				<a class="related_product_name" href="index.php?module=ProductAdmin&id={$purchase->product->id}&return={$smarty.server.REQUEST_URI|urlencode}">{$purchase->product_name}</a>
				{else}
				{$purchase->product_name}				
				{/if}

 

ниже пишем:

 

{assign var="result" value="|||"|explode:$purchase->properties}
				{if $result}
				<div style="font-size: 13px;">
				{foreach $result as $r}
					<br>+ {$r}
				{/foreach}
				</div>
				{/if}

 

16. simpla/design/html/product.tpl

 

находим:

 

<!-- Изображения товара -->	
		<div class="block layer images">
			<h2>Изображения товара
			<a href="#" id=images_wizard><img src="design/images/wand.png" alt="Подобрать автоматически" title="Подобрать автоматически"/></a>
			</h2>
			<ul>{foreach $product_images as $image}<li>
					<a href='#' class="delete"><img src='design/images/cross-circle-frame.png'></a>
					<img src="{$image->filename|resize:100:100}" alt="" />
					<input type=hidden name='images[]' value='{$image->id}'>
				</li>{/foreach}</ul>
			<div id=dropZone>
				<div id=dropMessage>Перетащите файлы сюда</div>
				<input type="file" name="dropped_images[]" multiple class="dropInput">
			</div>
			<div id="add_image"></div>
			<span class=upload_image><i class="dash_link" id="upload_image">Добавить изображение</i></span> или <span class=add_image_url><i class="dash_link" id="add_image_url">загрузить из интернета</i></span>
		</div>

ниже пишем:

 

<div class="block layer" {if !$categories}style='display:none;'{/if}>
			<h2>Параметры товара</h2>
			
			<ul class="prop_ul">
				{foreach $properties as $property}
					<li><input style="width: 300px; margin-right: 15px" type=text value="{$property->name}" name=new_properties_names[]><input style="width: 100px;"  class="simpla_inp" type="text" name=new_properties_values[] value="{$property->price}" /></li>
				{/foreach}
			</ul>

			<ul class=new_properties>
				<li id=new_property><input style="width: 300px; margin-right: 15px" type=text name=new_properties_names[]><input style="width: 100px;"  class="simpla_inp" type="text" name=new_properties_values[] /></li>
			</ul>
			<span class="add"><i class="dash_link" id="add_new_property">Добавить новый параметр</i></span>
			<input class="button_green button_save" type="submit" name="" value="Сохранить" />			
		</div>

 

Изменено пользователем Kami
Ссылка на сообщение
Поделиться на другие сайты

спасибо за работу, мельком глянул, возможно будет полезно

 

1. вот это вроде нигде не используется у вас: https://yadi.sk/i/V87A9l3O3MJbYs

соответственно итоговая цена $cart->total_price без учета дополнений. т.к. $properties_price никуда не добавляется

 

2. этот кусок https://yadi.sk/i/CTc2v_N83MJc7H я так понял из ф-и delete_item, он удалит товар из корзины и все ваши дополнения ВСЕХ товаров. нужно

unset($_SESSION['shopping_properties'][$variant_id]);

 

3. если добавить товар с одними опциями(дополнениями) а затем добавить тот же товар с другими опциями, то в корзине в итоге будет 1 товар со всеми дополнениями, а должно быть два товара с разными опциями, хотя возможно так было задумано

Изменено пользователем mishanya
Ссылка на сообщение
Поделиться на другие сайты

спасибо за работу, мельком глянул, возможно будет полезно

 

1. вот это вроде нигде не используется у вас: https://yadi.sk/i/V87A9l3O3MJbYs

соответственно итоговая цена $cart->total_price без учета дополнений. т.к. $properties_price никуда не добавляется

 

2. этот кусок https://yadi.sk/i/CTc2v_N83MJc7H я так понял из ф-и delete_item, он удалит товар из корзины и все ваши дополнения ВСЕХ товаров. нужно

unset($_SESSION['shopping_properties'][$variant_id]);

 

3. если добавить товар с одними опциями(дополнениями) а затем добавить тот же товар с другими опциями, то в корзине в итоге будет 1 товар со всеми дополнениями, а должно быть два товара с разными опциями, хотя возможно так было задумано

 

во втором пункте случайно 2 раза продублировал одно и тоже.

по поводу третьего пункта. Сейчас думаю как это дело разделить. 

Ссылка на сообщение
Поделиться на другие сайты

Уж очень знакомый код!

Признавайтесь где взяли.

Вы вообще в курсе что правилами форума запрещено выкладывать платные доработки авторов в свободный доступ и\или перепродавать их?

Ссылка на сообщение
Поделиться на другие сайты

Уж очень знакомый код!

Признавайтесь где взяли.

Вы вообще в курсе что правилами форума запрещено выкладывать платные доработки авторов в свободный доступ и\или перепродавать их?

 

Пф, мимо проходите.

Ссылка на сообщение
Поделиться на другие сайты

В дополнение к уже найденным ошибкам добавлю еще одну, весьма критичную:

 

4. Если открыть товар в админке и просто пересохранить его,  то текущие свойства товара удалятся и тут же затем запишутся заново. На вид вроде бы все то же самое, но ID свойств станут совсем другими. Это приведет к тому, что у ранее сделанных заказов с таким товаром все свойства будут утеряны.

Ссылка на сообщение
Поделиться на другие сайты

отличное решение... а про совмещение, надо разделять. да

тоже про это подумал, еще читая сверху ....

обожаю заполнять по разному товары и баги ловить на всех ходах.

тяжело быть перфекционистом ...

 

ps не обращайте внимания на нокстера.. он вечно, мимо проходя накинет с лопаты кусок мнения.

а если не платят.. ещё и добавит :) 

noxter реально с завышенной самооценкой. живёт в кругу, где ему позволяют быть главным 

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

Изменено пользователем ST_RU
Ссылка на сообщение
Поделиться на другие сайты

отличное решение... а про совмещение, надо разделять. да

тоже про это подумал, еще читая сверху ....

обожаю заполнять по разному товары и баги ловить на всех ходах.

 

ps не обращайте внимания на нокстера.. он вечно, мимо проходя накинет с лопаты кусок мнения.

а если не платят.. ещё и добавит :)

noxter реально с завышенной самооценкой ... не пуганный 

Я знаю чье это дополнение, при чем авторское и платное, а ТС тупо выложил его.

Неужели тут настолько глупые люди сидят что не понимают о чем идёт речь с первого раза?

Ссылка на сообщение
Поделиться на другие сайты

я не помню этот код... да и пусть будет.

вообще, надо было wiki по Simpla сделать с самого начала

опять же сотрут

Изменено пользователем ST_RU
Ссылка на сообщение
Поделиться на другие сайты

Я знаю чье это дополнение, при чем авторское и платное, а ТС тупо выложил его.

Неужели тут настолько глупые люди сидят что не понимают о чем идёт речь с первого раза?

 

Интересно было бы узнать ссылочку на это авторское и платное дополнение. А так - флуд один...

Изменено пользователем loxter
Ссылка на сообщение
Поделиться на другие сайты

Интересно было бы узнать ссылочку на это авторское и платное дополнение. А так - флуд один...

Возможно будет лучше чтобы сам автор отписался.
Ссылка на сообщение
Поделиться на другие сайты

Возможно будет лучше чтобы сам автор отписался.

Безусловно, это было бы лучше всего. 

Но для этого надо соблюдение как минимум двух условий: 1) выложена действительно разработка автора, 2) автору не  стыдно признать массу багов в разработке.

А пока очень сомнительно, что хотя бы одно из условий соблюдено.

 

И Ваши претензии к ТС - явно бег впереди паровоза...

Ссылка на сообщение
Поделиться на другие сайты

Повременим.

Но я уверен в том, что это та разработка и автора я знаю.

Сейчас ее перепродают везде где только можно при чем за копейки.

Ссылка на сообщение
Поделиться на другие сайты

А я тоже видел это дополнение... а баги из-за кривоватого выдергивания, просто не все части дополнения нашли...

Ссылка на сообщение
Поделиться на другие сайты

а баги из-за кривоватого выдергивания, просто не все части дополнения нашли...

 

Отнюдь. Баги из-за того, что изначально было запланировано весьма примитивно. Например, замечание 3 из #2 - явно автор не догадывается, что в заказе может быть ДВА одинаковых варианта с разными свойствами.

 

А я тоже видел это дополнение...

 

Дали бы ссылку, чтоб не было лишь распространение слухов...

 

Ссылка на сообщение
Поделиться на другие сайты

 

Отнюдь. Баги из-за того, что изначально было запланировано весьма примитивно. Например, замечание 3 из #2 - явно автор не догадывается, что в заказе может быть ДВА одинаковых варианта с разными свойствами.

 

 

Дали бы ссылку, чтоб не было лишь распространение слухов...

 

 

сутки не было, а срачу Товарищ Нокстер навел. 

Ссылку на авторское решение. И пусть автор мне напишет. Будем сидеть и сравнивать какие строчки у нас похожи.

Ссылка на сообщение
Поделиться на другие сайты
  • 1 год спустя...

спасибо за работу, мельком глянул, возможно будет полезно

 

1. вот это вроде нигде не используется у вас: https://yadi.sk/i/V87A9l3O3MJbYs

соответственно итоговая цена $cart->total_price без учета дополнений. т.к. $properties_price никуда не добавляется

 

2. этот кусок https://yadi.sk/i/CTc2v_N83MJc7H я так понял из ф-и delete_item, он удалит товар из корзины и все ваши дополнения ВСЕХ товаров. нужно

unset($_SESSION['shopping_properties'][$variant_id]);

 

3. если добавить товар с одними опциями(дополнениями) а затем добавить тот же товар с другими опциями, то в корзине в итоге будет 1 товар со всеми дополнениями, а должно быть два товара с разными опциями, хотя возможно так было задумано

Можете ещё раз скинуть 1ый пункт? Файл удалён

Ссылка на сообщение
Поделиться на другие сайты
  • 3 недели спустя...
  • 7 месяцев спустя...

Как обычно у меня есть.

 

скорей всего цена будет 50 у.е. + , я уже понял что тут все доработки от 50 долларов и выше, доходит до 400-500. CMS удобна , но тот же опенкарт предлагает множество модулей гораздо дешевле и с поддержкой отличной. 

Скорей всего это будет первый и последний проект на Simpla / Движок умер

Ссылка на сообщение
Поделиться на другие сайты

скорей всего цена будет 50 у.е. + , я уже понял что тут все доработки от 50 долларов и выше, доходит до 400-500. CMS удобна , но тот же опенкарт предлагает множество модулей гораздо дешевле и с поддержкой отличной. 

Скорей всего это будет первый и последний проект на Simpla / Движок умер

Ну так вперёд на форум опенкарта, чего здесь слюни разводить?

P.S. Я никакой цены не называл.

Ссылка на сообщение
Поделиться на другие сайты

Ну так вперёд на форум опенкарта, чего здесь слюни разводить?

P.S. Я никакой цены не называл.

 

я поэтому и указал "скорей всего"  , озвучьте цену, думаю лишней не будет.

Ссылка на сообщение
Поделиться на другие сайты

я поэтому и указал "скорей всего"  , озвучьте цену, думаю лишней не будет.

Составьте ЧЁТКОЕ ТЗ, тогда и нулей в цене лишних не будет...
Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...