Jump to content

Adding custom fields for combinations - PS1.6


sucemaya

Recommended Posts

Hello,

 

I need to add a new field to product combinations. The idea is to fill it from the backoffice, product combinations and then to show the value in product.tpl depending on the combination selected.

 

I have made some modifications based on the information explained in this topic (info is for PS 1.5): https://www.prestashop.com/forums/topic/256683-adding-customm-field-in-combination-tab/

 

In my PS 1.6.0.14 installation I have managed to successfully add the field and fill it from the backoffice (this is working fine). However, I cnt manage to show the value in the corresponding text box in the backoffice.

 

Here a description of the changes made, so maybe someone can help me (or it can also be useful for other people):

 

New field name is "plazo_envio"

 

First of all, I have added a new column to ps_product_attribute (and also to ps_product_attribute_shop, although I am not working in multistore mode) called "plazo_envio" and defined as a varchr(250).

 

- Modified combinations.tpl to include a text box for the new field:

<div class="form-group">
			<label class="control-label col-lg-3" for="attribute_plazo_envio">
				{l s='Texto plazo de envío'}
			</label>
			<div class="col-lg-5">
				<input maxlength="250" type="text" id="attribute_plazo_envio" name="attribute_plazo_envio" value="" />
			</div>
		</div>

- Modified Combination.php (added new property):

public $plazo_envio;
'plazo_envio' => 		array('type' => self::TYPE_STRING, 'size' => 250),

- Modified Product.php in order to include "plazo_envio":

	public function addCombinationEntity($wholesale_price, $price, $weight, $unit_impact, $ecotax, $quantity,
		$id_images, $reference, $plazo_envio, $id_supplier, $ean13, $default, $location = null, $upc = null, $minimal_quantity = 1,  array $id_shop_list = array(), $available_date = null)
	{
		$id_product_attribute = $this->addAttribute(
			$price, $weight, $unit_impact, $ecotax, $id_images,
			$reference, $plazo_envio, $ean13, $default, $location, $upc, $minimal_quantity, $id_shop_list, $available_date);
		$this->addSupplierReference($id_supplier, $id_product_attribute);
		$result = ObjectModel::updateMultishopTable('Combination', array(
			'wholesale_price' => (float)$wholesale_price,
		), 'a.id_product_attribute = '.(int)$id_product_attribute);

		if (!$id_product_attribute || !$result)
			return false;

		return $id_product_attribute;
	}
	public function updateAttribute($id_product_attribute, $wholesale_price, $price, $weight, $unit, $ecotax,
		$id_images, $reference, $plazo_envio, $ean13, $default, $location = null, $upc = null, $minimal_quantity = null, $available_date = null, $update_all_fields = true, array $id_shop_list = array())
	{
		$combination = new Combination($id_product_attribute);

		if (!$update_all_fields)
			$combination->setFieldsToUpdate(array(
				'price' => !is_null($price),
				'wholesale_price' => !is_null($wholesale_price),
				'ecotax' => !is_null($ecotax),
				'weight' => !is_null($weight),
				'unit_price_impact' => !is_null($unit),
				'default_on' => !is_null($default),
				'minimal_quantity' => !is_null($minimal_quantity),
				'available_date' => !is_null($available_date),
			));

		$price = str_replace(',', '.', $price);
		$weight = str_replace(',', '.', $weight);

		$combination->price = (float)$price;
		$combination->wholesale_price = (float)$wholesale_price;
		$combination->ecotax = (float)$ecotax;
		$combination->weight = (float)$weight;
		$combination->unit_price_impact = (float)$unit;
		$combination->reference = pSQL($reference);
		$combination->plazo_envio = pSQL($plazo_envio);
		$combination->location = pSQL($location);
		$combination->ean13 = pSQL($ean13);
		$combination->upc = pSQL($upc);
		$combination->default_on = (int)$default;
		$combination->minimal_quantity = (int)$minimal_quantity;
		$combination->available_date = $available_date ? pSQL($available_date) : '0000-00-00';

		if (count($id_shop_list))
			$combination->id_shop_list = $id_shop_list;

		$combination->save();

		if (is_array($id_images) && count($id_images))
			$combination->setImages($id_images);

		$id_default_attribute = (int)Product::updateDefaultAttribute($this->id);
		if ($id_default_attribute)
			$this->cache_default_attribute = $id_default_attribute;

		Hook::exec('actionProductAttributeUpdate', array('id_product_attribute' => (int)$id_product_attribute));
		Tools::clearColorListCache($this->id);

		return true;
	}
	public function addAttribute($price, $weight, $unit_impact, $ecotax, $id_images, $reference, $plazo_envio, $ean13,
								 $default, $location = null, $upc = null, $minimal_quantity = 1, array $id_shop_list = array(), $available_date = null)
	{
		if (!$this->id)
			return;

		$price = str_replace(',', '.', $price);
		$weight = str_replace(',', '.', $weight);

		$combination = new Combination();
		$combination->id_product = (int)$this->id;
		$combination->price = (float)$price;
		$combination->ecotax = (float)$ecotax;
		$combination->quantity = 0;
		$combination->weight = (float)$weight;
		$combination->unit_price_impact = (float)$unit_impact;
		$combination->reference = pSQL($reference);
		$combination->plazo_envio = pSQL($plazo_envio);
		$combination->location = pSQL($location);
		$combination->ean13 = pSQL($ean13);
		$combination->upc = pSQL($upc);
		$combination->default_on = (int)$default;
		$combination->minimal_quantity = (int)$minimal_quantity;
		$combination->available_date = $available_date;

		if (count($id_shop_list))
			$combination->id_shop_list = array_unique($id_shop_list);

		$combination->add();

		if (!$combination->id)
			return false;

		$total_quantity = (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
			SELECT SUM(quantity) as quantity
			FROM '._DB_PREFIX_.'stock_available
			WHERE id_product = '.(int)$this->id.'
			AND id_product_attribute <> 0 '
		);

		if (!$total_quantity)
			Db::getInstance()->update('stock_available', array('quantity' => 0), '`id_product` = '.$this->id);

		$id_default_attribute = Product::updateDefaultAttribute($this->id);

		if ($id_default_attribute)
		{
			$this->cache_default_attribute = $id_default_attribute;
			if (!$combination->available_date)
				$this->setAvailableDate();
		}

		if (!empty($id_images))
			$combination->setImages($id_images);

		Tools::clearColorListCache($this->id);

		if (Configuration::get('PS_DEFAULT_WAREHOUSE_NEW_PRODUCT') != 0 && Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
                {
                        $warehouse_location_entity = new WarehouseProductLocation();
                        $warehouse_location_entity->id_product = $this->id;
                        $warehouse_location_entity->id_product_attribute = (int)$combination->id;
                        $warehouse_location_entity->id_warehouse = Configuration::get('PS_DEFAULT_WAREHOUSE_NEW_PRODUCT');
                        $warehouse_location_entity->location = pSQL('');
                        $warehouse_location_entity->save();
                }

		return (int)$combination->id;
	}
	public function getAttributesGroups($id_lang)
	{
		if (!Combination::isFeatureActive())
			return array();
		$sql = 'SELECT ag.`id_attribute_group`, ag.`is_color_group`, agl.`name` AS group_name, agl.`public_name` AS public_group_name,
					a.`id_attribute`, al.`name` AS attribute_name, a.`color` AS attribute_color, product_attribute_shop.`id_product_attribute`,
					IFNULL(stock.quantity, 0) as quantity, product_attribute_shop.`price`, product_attribute_shop.`ecotax`, product_attribute_shop.`weight`,
					product_attribute_shop.`default_on`, pa.`reference`, pa.`plazo_envio`, product_attribute_shop.`unit_price_impact`,
					product_attribute_shop.`minimal_quantity`, product_attribute_shop.`available_date`, ag.`group_type`
				FROM `'._DB_PREFIX_.'product_attribute` pa
				'.Shop::addSqlAssociation('product_attribute', 'pa').'
				'.Product::sqlStock('pa', 'pa').'
				LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
				LEFT JOIN `'._DB_PREFIX_.'attribute` a ON (a.`id_attribute` = pac.`id_attribute`)
				LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON (ag.`id_attribute_group` = a.`id_attribute_group`)
				LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute`)
				LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group`)
				'.Shop::addSqlAssociation('attribute', 'a').'
				WHERE pa.`id_product` = '.(int)$this->id.'
					AND al.`id_lang` = '.(int)$id_lang.'
					AND agl.`id_lang` = '.(int)$id_lang.'
				GROUP BY id_attribute_group, id_product_attribute
				ORDER BY ag.`position` ASC, a.`position` ASC, agl.`name` ASC';
		return Db::getInstance()->executeS($sql);
	}

Modified ProductsController.php:

 

function assignAttributesGroups:

$combinations[$row['id_product_attribute']]['plazo_envio'] = $row['plazo_envio'];

Finally, I have included "plazo_envio" in AdminProductsController.php:

 

Funtion processProductAttribute:

Tools::getValue('attribute_plazo_envio'),
Tools::getValue('attribute_plazo_envio'),

Function initFormInformations:

		array_push($product_props, 'reference', 'plazo_envio', 'ean13', 'upc',
		'available_for_order', 'show_price', 'online_only',
		'id_manufacturer'
		);

Function renderListAttributes:

$comb_array[$combination['id_product_attribute']]['plazo_envio'] = $combination['plazo_envio'];

The result is that I can successfully add the info to the data base (the text box shows when I edit a combination, and I can fill it the text box, press save and the the info is saved in column "plazo_envio" in table ps_product_attribute BUT on page load I the text box is empty in the backoffice, so I cannot see the info in "plazo_envio" column).

 

I hope someone can help me to accomplish this task, it seems I am very close to manage it. 

 

Thanks in advance for your help :)

Link to comment
Share on other sites

  • 2 weeks later...

Hi, did you find a solution ?
I'm stuck at the same point of you.
 
EDIT

----------

 

I finally did it !
Everything happen in js/admin/product.js.

 

All you need to modidify is in :

product_tabs['Combinations'] = new function() {...}

In function editProductAttribute (line 264) you will have to add your custom field in the list of fields.

Also, you will have to modify fillCombination function, and add your field. Don't forget to add it also where you call this function :

self.fillCombination(...)

Now this should work.

Edited by blooo (see edit history)
Link to comment
Share on other sites

  • 1 month later...

Hi, did you find a solution ?

I'm stuck at the same point of you.

 

EDIT

----------

 

I finally did it !

Everything happen in js/admin/product.js.

 

All you need to modidify is in :

product_tabs['Combinations'] = new function() {...}

In function editProductAttribute (line 264) you will have to add your custom field in the list of fields.

Also, you will have to modify fillCombination function, and add your field. Don't forget to add it also where you call this function :

self.fillCombination(...)

Now this should work.

 

Yes!!! That's it!!!

 

I forgot to subscribe to this thread, so I did not see this answer until now :D

 

After updating products.js it is working fine, that was the step missing...

 

Many thanks!!! And sorry for the late answer :)

Link to comment
Share on other sites

I have followed the steps given here & edited my Product.js file as this

 

- Modified function editProductAttribute ( & fill Combination) :

function editProductAttribute (url, parent){
			$.ajax({
				url: url,
				data: {
					id_product: id_product,
					ajax: true,
					action: 'editProductAttribute'
				},
				context: document.body,
				dataType: 'json',
				context: this,
				async: false,
				success: function(data) {
					// color the selected line
					parent.siblings().removeClass('selected-line');
					parent.addClass('selected-line');

					$('#add_new_combination').show();
					$('#attribute_quantity').show();
					$('#product_att_list').html('');
					self.removeButtonCombination('update');
					scroll_if_anchor('#add_new_combination');
					var wholesale_price = Math.abs(data[0]['wholesale_price']);
					var price = data[0]['price'];
					var weight = data[0]['weight'];
					var unit_impact = data[0]['unit_price_impact'];
					var reference = data[0]['reference'];
					var packing_per_bale = data[0]['packing_per_bale']
					var ean = data[0]['ean13'];
					var quantity = data[0]['quantity'];
					var image = false;
					var product_att_list = new Array();
					for(i=0;i<data.length;i++)
					{
						product_att_list.push(data[i]['group_name']+' : '+data[i]['attribute_name']);
						product_att_list.push(data[i]['id_attribute']);
					}

					var id_product_attribute = data[0]['id_product_attribute'];
					var default_attribute = data[0]['default_on'];
					var eco_tax = data[0]['ecotax'];
					var upc = data[0]['upc'];
					var minimal_quantity = data[0]['minimal_quantity'];
					var available_date = data[0]['available_date'];

					if (wholesale_price != 0 && wholesale_price > 0)
					{
						$("#attribute_wholesale_price_full").show();
						$("#attribute_wholesale_price_blank").hide();
					}
					else
					{
						$("#attribute_wholesale_price_full").hide();
						$("#attribute_wholesale_price_blank").show();
					}
					self.fillCombination(
						wholesale_price,
						price,
						weight,
						unit_impact,
						reference,
						packing_per_bale,
						ean,
						quantity,
						image,
						product_att_list,
						id_product_attribute,
						default_attribute,
						eco_tax,
						upc,
						minimal_quantity,
						available_date
					);
					calcImpactPriceTI();
				}
			});
		}
	};

- and function call of fillCombination

this.fillCombination = function(wholesale_price, price_impact, weight_impact, unit_impact, reference, packing_per_bale,
	ean, quantity, image, old_attr, id_product_attribute, default_attribute, eco_tax, upc, minimal_quantity, available_date)
	{
		var link = '';
		self.init_elems();
		$('#stock_mvt_attribute').show();
		$('#initial_stock_attribute').hide();
		$('#attribute_quantity').html(quantity);
		$('#attribute_quantity').show();
		$('#attr_qty_stock').show();

		$('#attribute_minimal_quantity').val(minimal_quantity);

		getE('attribute_reference').value = reference;
		
		getE('attribute_packing_per_bale').value = packing_per_bale;

		getE('attribute_ean13').value = ean;
		getE('attribute_upc').value = upc;
		getE('attribute_wholesale_price').value = Math.abs(wholesale_price);
		getE('attribute_price').value = ps_round(Math.abs(price_impact), 2);
		getE('attribute_priceTEReal').value = Math.abs(price_impact);
		getE('attribute_weight').value = Math.abs(weight_impact);
		getE('attribute_unity').value = Math.abs(unit_impact);
		if ($('#attribute_ecotax').length != 0)
			getE('attribute_ecotax').value = eco_tax;

Still I am facing the same Problem. Any further suggestions?
NOTE : packing_per_bale is my custom filed.

Link to comment
Share on other sites

  • 10 months later...
  • 2 years later...

I am in similar trouble too.. i need to add 2 fields.. custom length and custom width so that customers can choose what dimensions they need.. but I dont want to go into the core files.. i need it to be done as a module.. so that, the the system will not break when client upgrade their version of prestashop.

Link to comment
Share on other sites

  • 6 months later...

Hi, i did all the modifications in the files and i still have a problem with the combinatios. I think this is because we have multistore. I've looked in the DB and the changes are made in product_attribute but not in product_attribute_shop. When i fill the field with mysql directly in product_attribute_shop the changes are shown in the backoffice correctly. What I need is that when I fill the field in the backoffice is stored correctly in product_attibrute_shop.

Link to comment
Share on other sites

  • 1 month later...
  • 1 year later...

Good work! Thanks alot.

Important - If you do not have multistore enabled DO NOT add your new field to product_attribute_shop. Only add the new field to product_attribute table. If you add the field to both tables the product_attribute_shop table takes priority. Once I deleted the new field from the table product_attribute_shop my value showed up into the back office.

Link to comment
Share on other sites

  • 2 years later...

Hello,

I tried all the above mentioned editing in prestashop, but when I want to call the "field" in themes/my-theme/js/product.js, it just shows "null" value.

Am I missing something?
I have a custom field in "ps_product_attribute" table for each combination and want to display this field next to quantity.

Thank you.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...