Bonjour,

J'essaye de faire un système de panier/commande sur un petit site avec Cake, le principe est simple, j'ai une table Cart ou j'enregistre le panier de l'utilisateur et ensuite j'aimerais covnertir ce panier en commande, donc j'ai une table order qui contient l'utilisateur et le total de la commande, et une table product_orders qui elle contient l'ID de la commande et le product_id.

Ce que je fais

Décrivez ici votre code ou ce que vous cherchez à faire

// Donc je suis dans le controller Cart
 public function convertCart(){
        $this->loadModel('Orders');
        $user_id = $this->Auth->user('id');
        $user_name = $this->Auth->user('name');     
        // Je recherche tous les produits associés aux panier de l'utilisateur en cours
        $products = $this->Carts
            ->find('all')
            ->contain(['Products'])
            ->where(['Carts.user_id' => $user_id]);
        // Je calcule le total du panier, qui sera le total de la commande
        $cart = $this->Carts
            ->find('all')
            ->contain(['Products'])
            ->where(['Carts.user_id' => $user_id]);
        $res =  $cart->select(['total_sum' =>$cart->func()->sum('total')])->first(); 

        // Je créer une entité commande
        $order = $this->Orders->newEntity();
        // La il est censé récupérer, l'ID et le total de la commande
        if ($this->request->is('post')) {
            $order->user_id = $user_id;
            $order->total = $res->total_sum;
            $order = $this->Orders->patchEntity($order, $this->request->data);
            if ($this->Orders->save($order)) {
            // Et c'est ici que je ne sais pas comment faire pour lui dire d'associer tous les produits du panier dans la table products_orders en prenant compte de l'ID de la commande qui vient d'être créer ... Je pense faire un foreach du style 
            foreach ($order->products as $product) {
               $product->order_id = $order->id;
               $product->product_id = $product_id
            }
            // Le problème c'est que le product_id il ne le connais pas ... vu qu'il y en as plusieurs je ne sais pas trop comment m'y prendre ..
                $this->Flash->success(__('The order has been saved.'));

                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error(__('The order could not be saved. Please, try again.'));
                return $this->redirect(['action' => 'index']);
            }
        }

        $this->set(compact('cart_products', 'cart_total', 'subtotal', 'tva', 'total'));
    }

Ce que je veux

J'aimerais pouvoir associer les produits du panier à la commande, c'est à dire convertir le panier en commande.

Ce que j'obtiens

Il n'enregistre pas la commande, je vosu remercie de votre attention.

4 réponses


Bonjour.
Pourquoi faire deux requêtes SQL qui sont identiques ?
Pour moi les requêtes SQL contenues dans les variables $products et $cart sont exactement les mêmes.
Tu pourrais donc déja commencer par remplacer :

// Je recherche tous les produits associés aux panier de l'utilisateur en cours
$products = $this->Carts
    ->find('all')
    ->contain(['Products'])
    ->where(['Carts.user_id' => $user_id]);
// Je calcule le total du panier, qui sera le total de la commande
$cart = $this->Carts
    ->find('all')
    ->contain(['Products'])
    ->where(['Carts.user_id' => $user_id]);
$res =  $cart->select(['total_sum' =>$cart->func()->sum('total')])->first();

Par :

// Je recherche tous les produits associés aux panier de l'utilisateur en cours
$cart = $this->Carts
    ->find('all')
    ->contain(['Products'])
    ->where(['Carts.user_id' => $user_id]);
// Je calcule le total du panier, qui sera le total de la commande
$res =  $cart->select(['total_sum' =>$cart->func()->sum('total')])->first();

Car faire deux requêtes SQL absolument identiques, à part augmenter la charge du serveur, je ne vois pas ce que ça fait de plus.

Le problème c'est que le product_id il ne le connais pas ... vu qu'il y en as plusieurs je ne sais pas trop comment m'y prendre ..

C'est plutôt normal, elle vient d'où cette variable ?
Tu ne l'a définie nulle part.

Muxabble
Auteur

Ouaip, je sais que les deux requêtes sont identiques, la première fois j'avais une erreur avec la fonction sum, d'où deux requêtes séparée, et vu que je ne suis pas au refactoring je laisse pour le moment, là je suis dans une première version, où je code en "scaffold", et je refactoriserais le tout dans une prochaine étape.

En faite, j'ai une table cart, avec une vue showCart qui affiche le panier d'un utilisateur comme un e-commerce classique, donc la variable product_id se trouve dans la vue show_cart, le but étant lors du submit du bouton "Checkout" reprendre toute les données du panier et créer une commande. Le soucis étant ne pas savoir comment faire, parce qu'en temps normal si j'utilisate la fonction add du controller order, je fais juste un patchEntity avec un $this->request->data et hop comme par magie cake attribue les articles dans la table products_order et créer une entity dans order.

Pourquoi veux-tu sauvegarder les produits du cart dans la table orders ?
Dans cette table il te suffirait par exemple d'y sauvegarder le total de l'achat par exemple ainsi que les informations concernant les lieux de livraisons/facturations et tu pourrais lier l'enregistrement avec le cart.
Ce qui ferait par exemple quelque chose comme :

  • carts
    • id
    • ...
    • user_id
  • cart_products
    • id
    • cart_id
    • product_id
    • quantity
  • orders
    • id
    • ...
    • amount
    • cart_id
Muxabble
Auteur

Je n'avais pas pensé à cetet solution effectivement, pour le moment j'ai une architecture de base de donnée comme celle-ci :

  • carts
    • user_id
    • product_id
    • ...
  • orders

    • user_id
    • total
    • products_orders
    • product_id
    • order_id

    Au final ça reviens à faire la même chose non ? Sachant que je n'ai pas besoin d'enregistrer les données de facturation/livraison