Jump to content
Arsen96

impact sur le prix champs personnalisé

Recommended Posts

Bonjour,

 

J'ai ajouté un champs libre dans la fihce produit et déormais je voudrais créer un module qui permettrait en fonction des données saisies par l'utilisateur que ça impacte le prix global de mon panier.Voici comment j'imagine les choses.

-Presta récupère les valeurs saisies par l'utilisateur en ajax(sans impact sur le prix)

-ajouter les champs au panier

-créer un produit à la volée(un clone) en multipliant le prix de base en fonction des données saisies par l'utilisateur

-Affecter le prix à mon nouveau produit

-Ajouter au panier.

 

Pouvez-vous valider si j'ai bien compris le principe et si vous avez d'autres solutions encore plus simplifiéé.

 

Merci

Share this post


Link to post
Share on other sites

Plus simple ?

- Soit simplement créer une combinaison à la volée plutôt qu'un produit complet

- Soit avoir déjà créé les combinaisons (sans les afficher) avec impact de prix et sélectionner la bonne lors de la validation des champs de perso (si remplis ou autre critère)

- Soit, ma solution préférée,  faire un override de la fonction Product::getPriceStatic() (permet de modifier le prix comme on le souhaite)

Share this post


Link to post
Share on other sites

Merci pour votre réponse. Je débute avec Prestashop

J'ai opté pour la fonction  statique Product::getPriceStatic() . Voici  ma classe d'override .  Je souhaiterais que mon produit ayant l'id 138 ait le prix 25 (modification ). Cependant je ne sais que ce que la methode doit retourner pour que ma demande soit opérationnelle.

 

PrixProduit.PNG.3dcb52977f7f3784e7214f542008bdea.PNG

Share this post


Link to post
Share on other sites

De plus non seulement je voudrais modifier le prix de base de mon produit mais aussi faire un statement en fonction des données saisies par l'utilisateur.

Par exemple .  Pensez-vous qu'il est possible de faire comme ceci ?

$height = Tools::getValue('height');
 

if($height > 10 && $height < 15) {

return Product::getPriceStatic(138, false, null, 6, null, false, false, 1, false, null, null, null, 25, false, false, null, false);

}else if($height >= 15){

return Product::getPriceStatic(138, false, null, 6, null, false, false, 1, false, null, null, null, 35, false, false, null, false);

}

Share this post


Link to post
Share on other sites

Euh... il n'y a rien dans votre override et il ne faut surtout pas forcer l'$id_product ici

Vous mettez une condition, en rapport avec votre module.

If (in_array($id_product, array(138,150,xxxx) ) {

le code natif de la fonction

et au lieu du return final (qui renvoie le prix) vous effectuez vos calculs et renvoyez votre prix

}

else {

return Parent::getPriceStatic($id_product, $usetax, $id_product_attribute, $decimals, $divisor,
        $only_reduc, $usereduc, $quantity, $force_associated_tax, $id_customer, $id_cart,
        $id_address, &$specific_price_output, $with_ecotax, $use_group_reduction, Context $context,
        $use_customer_price)

}

Share this post


Link to post
Share on other sites

le Tools::getValue() ne fonctionne que par rapport au contexte et si un paramètre est transmis en $_GEt ou $_POST.

Il faut savoir que cette fonction qui récupère le prix est appelée à plein d'endroits et pas seulement lors de la mise au panier. Or vous voulez avoir le même résultat partout où ce produit personnalisé sera utilisé avec ses champs remplis (BO ou FO)

- Il faut que votre module enregistre ces id_produits spéciaux pour remplir le tableau utilisé comme déclencheur (if(in_array()) {...

- si le produit matche et suivant l'id_cart du client, il faut récupérer les valeurs des customs enregistrées par ce client pour ce produit (Tout est en base de données)

Là vous aurez tous les éléments pour forger votre prix perso.

Share this post


Link to post
Share on other sites

Modifier &$specific_price_output ne sert à rien, cette variable est recalculée dans la fonction suivante^^

Share this post


Link to post
Share on other sites
<input name="height"><br>
<input name="width">

Merci encore une fois. J'ai compris le principe mais cela me paraît un peu compliqué et je voudrais faire quelque chose à ma portée..

J'ai une deuxième solution avec la classe  SpecificPrice. Pouvez-vous me le valider svp.

Je pense u'avec cette méthode je n'aurais pas besoin de créer un module mais simplement overridé la SpectificPrice

Je décris étape par étape afin que ça soit compréhensible pour moi et pour vous.

                                           Au niveau d'affichage.

1)Ajout de deux champs dans product.tpl

<input name="height">

<input name="width">

2) Enregistrer les valeurs de mes champs dans la BDD afin de pouvoir récupérer les valeurs avec Tools::getValue

Au niveau de traitement.

3) Imaginons je souhaite modifié le prix dynamiquement ayany l'id 135 donc j'override SpecificPrice

$id_product = 135;    
$nouveauPrix= 20;

 

if($height > 10 && $width > 10) $nouveauPrix= 10;

    $specific_price = new SpecificPrice();
    $specific_price->price = $nouveauPrix;
    $specific_price->id_cart = (int) $this->context->cart->id;
    $specific_price->id_shop = 0;
    $specific_price->id_shop_group = 0;
    $specific_price->id_currency = 0;
    $specific_price->id_country = 0;
    $specific_price->id_group = 0;
    $specific_price->id_customer = (int)    $this->context->customer->id;
    $specific_price->id_product = (int)$id_product;
    $specific_price->id_product_attribute = 0;
    $specific_price->from_quantity = 1;
    $specific_price->reduction = 0;
    $specific_price->reduction_type = 'amount';
    $specific_price->from = '0000-00-00 00:00:00';
    $specific_price->to = '0000-00-00 00:00:00';
    $specific_price->add();


Pensez-vous qu'il est possible de faire ceci ?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Share this post


Link to post
Share on other sites

Non...

je me répète 

Il y a 1 heure, Eolia a dit :

le Tools::getValue() ne fonctionne que par rapport au contexte et si un paramètre est transmis en $_GEt ou $_POST.

Donc rien à voir avec la base de données.

Je vous avais répondu car vous aviez expliqué vouloir créer un module. Votre override directe de specificPrice va vous remplir la table en bdd et risque de vous donner de drôles de valeurs suivant les groupes, pays, monnaies & taxes...

Share this post


Link to post
Share on other sites

Dans ce cas là comment on obtiens la valeur saisi par l'utilisateur dans le name de input type 

Share this post


Link to post
Share on other sites

ces valeurs sont enregistrées dans la table ps_customized_data.

Comment fait Prestashop à votre avis ?

Share this post


Link to post
Share on other sites

Vous m'avez dit que Tools::getValue()  n'a rien à avoir avec la base de donnée, mais dans ce cas là comment on récupère l'attribut name de mon champs personnalisé pour faire le traitement derrière.

Je remarque que la table de ps_customized_data possède  un champs prix, donc je suppose qu'il est possible de modifier le prix global de mon produit en fonction de saisi de l'utilisateur.

Cependant je ne sais pas où est-ce que je dois faire le traitement. Faut-il utiliser un hook ou non.

Share this post


Link to post
Share on other sites

Tout est dans l'objet $product, faites un var_dump ou print_r vous comprendrez

L'attribut name du champ est dans ps_customization_field_lang

Le champ prix de cette table n'existe pas nativement (sans doute ajouté par un module), c'est une fonction qui n'a jamais été terminée dans l'historique de Prestashop mais rien ne vous empêche de le remplir et de l'utiliser.

Edited by Eolia (see edit history)

Share this post


Link to post
Share on other sites

Pouvez-vous s'il vous plaît me décrire les différents étapes qu'il faut suivre pour mettre cela en place avec une solution que vous estimez le moins compliqué. Je ne demande pas d'écrire le code mais au moins avoir une ligne directive.

 

Share this post


Link to post
Share on other sites

 

 

au niveau de la page produit, faire un appel ajax au début de la fonction add de /themes/votre_theme/js/modules/blockcart/blockcart.js

- vérifiez que le produit est customisable

- si oui récupérez vos données et effectuez un appel ajax vers un fichier php à la racine du site (saveCustomPrice.php par exemple)

	// add a product in the cart via ajax
	add : function(idProduct, idCombination, addedFromProductPage, callerElement, quantity, whishlist){

		if (addedFromProductPage && !checkCustomizations())
		{
			if (contentOnly)
			{
				var productUrl = window.document.location.href + '';
				var data = productUrl.replace('content_only=1', '');
				window.parent.document.location.href = data;
				return;
			}
			if (!!$.prototype.fancybox)
				$.fancybox.open([
					{
						type: 'inline',
						autoScale: true,
						minHeight: 30,
						content: '<p class="fancybox-error">' + fieldRequired + '</p>'
					}
				], {
					padding: 0
				});
			else
				alert(fieldRequired);
			return;
		}
// Ajoutez votre code ici pour enregistrer vos prix customs (Mise à jour des prix dans la table ps_customized_datas

Dans ce fichier php:

- Controlez que l'id_product correspond à l'un de ceux concernés par ces prix spéciaux (configurés dans votre module ou dans les pages produits en BO)

- Vérifiez les données de chaque champ

- Calculez vos prix

- Enregistrez les prix dans la table ps_customized_data

Dans votre override de Product::getPriceStatic(), juste avant le return $return final, allez récupérer les prix enregistrés dans la table des custom et ajustez le prix renvoyé (le prix = la variable $return)

Exemple:

- A la fin de la fonction, $return = 12.5   (en HT ou TTC suivant la configuration de votre boutique)

- Ce produit ID 128 est un produit avec custom et le prix doit être ajusté

- Vous récupérez la ou les prix correspondants aux customs enregistrées par le client dans la table ps_customized_data (à croiser avec la table ps_customization) ce qui vous donne quelque chose comme:

- On récupère l'identifiant des champs textes de ce produit ($type = 1, pour les champs texte)

	$index = Db::getInstance()->executeS($sql = '
									SELECT `id_customization_field`
									FROM `'._DB_PREFIX_.'customization_field`
									WHERE `id_product` = '.(int)$id_product.'
									AND `type` = '.(int)$type.'
									AND `required` = 1');

On rassemble ces index dans une chaine pour la prochaine requete SQL:

$indexes = implode(', ', array_map(function ($entry) {
  			return $entry['id_customization_field'];
			}, $index));

On récupère la somme des prix:

			$price = Db::getInstance()->getValue('
								SELECT SUM(cd.`price`)
								FROM `'._DB_PREFIX_.'customization` cu
								LEFT JOIN `'._DB_PREFIX_.'customized_data` cd ON (cu.`id_customization` = cd.`id_customization`)
								WHERE cu.id_cart = '.(int)$context->cart->id.'
								AND cu.id_product = '.(int)$id_product.'
								AND cd.index IN ('.$indexes.')
								AND cd.type = 1'
							);

mettons que $price nous retourne 18.25 dans cette dernière requête, on ajoute ou remplace à $return (tout dépend si vous considérez que ces prix sont des majorations ou carrément des prix complets)

$return += $price;

// ou

$return = $price;

et le code de Prestashop finit le travail:

return $return;

 

Share this post


Link to post
Share on other sites

Merci beaucoup pour ces explications.

Comment est-ce que je peux préciser depuis ma fiche produit que je souhaite faire appel vers un fichier php que moi même je veux la créer (ex saveCustomPrice.php ).

 

Share this post


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.   Restore formatting

  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.


×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More