Jump to content

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


Recommended Posts

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>

 

Edited by Kami
Link to post
Share on other sites

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

 

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 товар со всеми дополнениями, а должно быть два товара с разными опциями, хотя возможно так было задумано

Edited by mishanya
Link to post
Share on other sites

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

 

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 раза продублировал одно и тоже.

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

Link to post
Share on other sites

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

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

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

Link to post
Share on other sites

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

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

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

 

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

Link to post
Share on other sites

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

 

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

Link to post
Share on other sites

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

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

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

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

 

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

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

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

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

Edited by ST_RU
Link to post
Share on other sites

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

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

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

 

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

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

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

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

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

Link to post
Share on other sites

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

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

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

Edited by ST_RU
Link to post
Share on other sites

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

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

 

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

Edited by loxter
Link to post
Share on other sites

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

Возможно будет лучше чтобы сам автор отписался.
Link to post
Share on other sites

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

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

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

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

 

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

Link to post
Share on other sites

Повременим.

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

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

Link to post
Share on other sites

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

Link to post
Share on other sites

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

 

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

 

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

 

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

 

Link to post
Share on other sites

 

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

 

 

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

 

 

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

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

Link to post
Share on other sites
  • 1 year later...

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

 

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ый пункт? Файл удалён

Link to post
Share on other sites
  • 3 weeks later...
  • 7 months later...

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

 

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

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

Link to post
Share on other sites

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

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

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

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

Link to post
Share on other sites

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

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

 

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

Link to post
Share on other sites

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

Составьте ЧЁТКОЕ ТЗ, тогда и нулей в цене лишних не будет...
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...