Function save order

  • Posts: 454
  • Thank you received: 31
  • Hikamarket Multivendor Hikashop Business
2 months 1 week ago #363204

Bonjour,

je tourne un peu en rond avec l'ajout de commande, voici mon code, pour le moment simple sans port, taxes, ni discounts.

Tout est ok, sauf l'attribution des produits à la commande puisque au moment de créer les produits, on ne connais pas order_id pour les attribuer, et le save de order se fait en même temps que le save des products.

Pouvez vous m'éclairer sur cette partie de la procédure svp ?

Merci d'avance :)

            $sub_total = 0;
            $products = [];
            foreach ($post['order_product'] as $product_id => $qty) {
                $product = $productModel->getProduct($product_id);
                // catch and add price
                $db->setQuery('SELECT price_value FROM #__hikashop_price 
                                WHERE price_users LIKE "%,' . $post['order_user_id'] . ',%"
                                AND price_product_id = ' . $product_id);
                $order_product_price = $db->loadResult();
                $sub_total = $sub_total + ($order_product_price * $qty);

                $order_product = new stdClass();
                $order_product->order_id = 0; // on ne connais pas encore order_id
                $order_product->product_id = $product_id;
                $order_product->order_product_name = $product->product_name;
                $order_product->order_product_code = $product->product_code;
                $order_product->order_product_quantity = $qty;
                $order_product->order_product_price = $order_product_price;
                $order_product->order_product_sold_by = $post['user_link'];
                $products[] = $order_product;
            }

            // save order
            $order = new stdClass();
            $order->order_status = 'confirmed';
            $order->order_user_id = $post['order_user_id'];
            $order->order_billing_address_id = $post['order_billing_address_id'];
            $order->order_shipping_address_id = $post['order_shipping_address_id'];
            $order->order_full_price = $sub_total;
            $order->order_currency_id = 1;
            $order->product = $products;
            echo '<pre>';
            var_dump($order);
            echo '</pre>';
            // exit;
            $orderClass->save($order);

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
2 months 1 week ago #363205

Bonjour,

En effet, le tableau $order->product est utilisé pour mettre à jour la liste des produits d'une commande déjà créée.
Si vous voulez créer une commande tout en fournissant les produits en même temps, vous devez les avoir dans $order->cart->products à la place. HikaShop ajoutera automatiquement l'order_id après que l'entrée de commande a été créée dans la base de données, puis il ajoutera les produits à la base de données.
Un bon exemple de ce qu'il faut faire pour créer une commande avec la fonction save se trouve dans la fonction "createFromCart" dans administrator/components/com_hikashop/classes/order.php.

En fait, vous pourriez simplement créer un panier et y ajouter les produits que vous souhaitez, puis appeler createFromCart avec le cart_id, ce qui générerait la commande pour vous.
Créer un panier est plus simple car vous n'avez pas à vous soucier des prix, taxes, etc. HikaShop calcule tout pour vous en fonction de la situation, donc vous pouvez utiliser la méthode addProduct de la classe.cart.

De plus, assurez-vous de sécuriser les données provenant du post. Vous n'avez pas fourni le code remplissant la variable $post, donc je ne peux pas dire avec certitude s'il y a un problème ou non avec ce que vous avez. Mais en général, nous préférons sécuriser les variables lors de l'écriture des requêtes MySQL. De cette façon, même si le code avant la requête est réorganisé, la requête reste protégée contre les injections SQL.
Par exemple, personnellement, j'écrirais :

                $db->setQuery('SELECT price_value FROM #__hikashop_price 
                                WHERE price_users LIKE "%,' . (int)$post['order_user_id'] . ',%"
                                AND price_product_id = ' . (int)$product_id);
De cette façon, lorsqu'un attaquant injecte du code MySQL dans la valeur POST de order_user_id pour essayer de récupérer des données de votre base de données, cela sera converti en entier et ne perturbera pas la requête MySQL.
Lorsque vous utilisez les fonctions de HikaShop, HikaShop sécurise les attributs de vos objets pour vous, donc vous n'avez pas à le faire. Mais il peut être judicieux de le faire quand même, au cas où nous manquerions quelque chose.

Désolé pour l'Anglais... je viens de réaliser que votre message était en Français ^^;

[Edit:] Traduction refaite dans un second temps.

Last edit: 2 months 1 week ago by Philip.

Please Log in or Create an account to join the conversation.

  • Posts: 454
  • Thank you received: 31
  • Hikamarket Multivendor Hikashop Business
2 months 1 week ago #363230

Bonjour Nicolas,

merci beaucoup, effectivement je vais prendre ce chemin qui m'a l'air déjà bien préparé.

Je n'ai pas sécurisé les variables c'est vrai, l'utilisateur a juste à régler les quantités il ne touche à rien d'autre.

Merci pour cette réponse très complète !

Please Log in or Create an account to join the conversation.

  • Posts: 454
  • Thank you received: 31
  • Hikamarket Multivendor Hikashop Business
2 months 1 week ago #363241

Re bonjour,

il se passe des choses étranges lors du passage de createFromCart, le prix des produit change.

Dans le panier tout était ok, hikashop a bien pris automatiquement le prix correspondant à cet utilisateur, mais une fois dans la commande ce sont les prix de base de chaque produit au lieu du prix pour cet utilisateur.

Savez vous pourquoi / comment éviter ce souci ?

Sinon à part ca tout à l'air de très bien fonctionné :)

edit : je précise que l'utilisateur connecté n'est pas le user_id de la commande, mon code modifie manuellement le user_id du panier après création, mais même avant ca, les prix de produits étaient bon dans le panier et pas bon dans la commande après createFromCart, mais peut être qu'il y a un lien

Last edit: 2 months 1 week ago by Minie.

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
2 months 1 week ago #363242

Bonjour,

HikaShop charge le panier pour le transformer en commande en utilisant l'utilisateur courant.
Je suppose que la façon dont vous créez la commande, l'utilisateur courant n'est pas l'utilisateur pour lequel vous voulez créer la commande.
Ce que vous pouvez faire dans ce cas, c'est au lieu d'avoir:

$orderClass->createFromCart($cart_id);
vous pouvez faire:
$cartClass = hikashop_get('class.cart');
$cart = $cartClass->getFullCart($cart_id, array('force_user_prices' => true));
$orderClass->createFromCart($cart);
cartFromCart peut prendre soit un cart_id, soit l'objet complet du panier. Lorsque vous fournissez le cart_id, il va appeler getFullCart pour récupérer l'objet complet du panier.
En faisant vous-même le getFullCart, vous pouvez passer l'option force_user_prices pour dire à getFullCart d'utiliser les prix de l'utilisateur lié au panier au lieu des prix de l'utilisateur courant.

Please Log in or Create an account to join the conversation.

  • Posts: 454
  • Thank you received: 31
  • Hikamarket Multivendor Hikashop Business
2 months 1 week ago #363290

Bonjour,

au top, merci beaucoup, ca fonctionne très bien.

Une chose n'est apparemment pas gérée dans le processus, ce sont les méthodes de livraisons, je suppose que c'est paracerque le client est sensé choisir ?

Dans mon cas je n'en ai que 3 qui ne peuvent pas se concurrencer, n'y a t'il pas moyen que les modes de livraisons soient attribuer automatiquement pour chaque produits dans ce cas ? comme lors su passage en caisse classique ou il n'y a qu'un seul choix de livraison pour chaque groupe de produit.

Exemple :
Livraison 1 : entrepôt 1 et client post code commence par 64 ou 40
Livraison 2 : entrepôt 1 et client post code NE commence PAS par 64 ou 40
Livraison 3 : entrepôt autre que 1

Donc résumé :
Question 1 : Comment faire en sorte que cart_shipping_ids soit géré par hikashop dans createFromCart ?
Question 2 : Dans les restrictions de mode de livraison par entrepôt, suis- obligée de lister tous les autres ou puis-je faire une règle "tous sauf le 1" ? car les autres vont être créés régulièrement et dynamiquement dans mon code, au pire je ferais un plugin pour les ajouter aux restrictions.

Merci :)

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
2 months 1 week ago #363291

Bonjour,

1.
La fonction createFromCart gère déjà les méthodes de livraison. Du moment que cart_shipping_ids est fourni, createFromCart va assigner les méthodes de livraison à la commande.
La fonction getFullCart var remplir $cart->usable_methods->shipping avec un array des méthodes de livraison disponibles pour le panier.
C'est à vous d'appeler la fonction updateShipping de class.cart pour fournir les méthodes de livraison que vous voulez utiliser parmi la liste des méthodes disponibles, même s'il n'y a qu'une seule méthode de livraison de disponible.

2.
Il n'y a pas de filtre "autre que" pour les restrictions des méthodes de livraison.

Please Log in or Create an account to join the conversation.

  • Posts: 454
  • Thank you received: 31
  • Hikamarket Multivendor Hikashop Business
2 months 5 days ago #363346

Bonjour,

c'est magique, magnifique, c'est parfait, merci beaucoup !

Tout fonctionne très bien :)

J'ai juste une dernière petite question, comment faire en sorte lors d'un changement de statut, que le mail soit toujours envoyé.

L'équivalent de cocher la case "notifier le client" dans le backend, mais lorsque j'édite le statut depuis mon code ?
J'ai tenté un plugin qui ne fonctionne pas , utilisant onAfterOrderUpdate et mettant $send_email = true;
Ca m'aurais permis de régler moi même si notification ou non selon les cas, sans action manuelle.

Merci encore pour la création de commande, c'était une partie que je n'avais encore jamais expérimentée

Please Log in or Create an account to join the conversation.

  • Posts: 82867
  • Thank you received: 13374
  • MODERATOR
2 months 5 days ago #363347

Bonjour,

Mettre $send_mail à true dans un évènement onAfterOrderUpdate d'un plugin HikaShop est pourtant une solution oui.
Veillez bien à mettre le & avant $send_mail dans les paramètres de la méthode, sinon, la valeur ne sera pas remontée à class.order.

Sinon, une autre solution encore plus simple, c'est qu'avant votre appel au save de class.order vous rajoutiez :
$order->history->history_notified = true;

Si vous cherchez "onAfterOrderUpdate" dans class.order, vous pouvez voir ce code:

			$send_email = @$order->history->history_notified;
			$app->triggerEvent('onAfterOrderUpdate', array( &$order, &$send_email) );

			$historyClass->addRecord($order);

			if(!$send_email)
				return $order->order_id;

... code qui envoie l'email ...
Donc, comme vous pouvez le voir, les 2 méthodes vont provoqué un return, avant l'envoi de l'email si $send_mail est à false, et si il est à true, alors l'email va être envoyé.

Please Log in or Create an account to join the conversation.

  • Posts: 454
  • Thank you received: 31
  • Hikamarket Multivendor Hikashop Business
2 months 2 days ago #363391

Bonjour,

merci beaucoup, effectivement j'avais oublié le petit & avant le $send_mail :unsure:

Super, tout fonctionne ! :woohoo:

Merci !

Please Log in or Create an account to join the conversation.

Time to create page: 0.084 seconds
Powered by Kunena Forum