Symfony : contrainte d'unicité qui fonctionne mal

a marqué ce sujet comme résolu.

Bonjour (et bonne année !)

J’en suis à tester mon application de Salon du Livre. J’essaie de faire un script qui me remplirait ma BDD avec de fausses factures afin de travailler sur les pages de présentation des résultats. C’est évidemment un script bien lourd mais je compte ne l’utiliser qu’une seule fois (800+ requêtes)…

Mon souci se passe avec l’entité Stock qui comptabilise les livres vendus. Vu que je pars d’une table vide, lorsque je crée mes Factures je crée un Stock pour chaque livre. Puis, si le Stock existe déjà, on le met à jour. Et c’est là où je dois me planter ou mal comprendre le fonctionnement de Doctrine. Doctrine lève une erreur de non respect de la contrainte d’unicité et je vois mal pourquoi mon script m’envoie dans cette direction alors que je pensais justement avoir écrit quelque chose qui évite justement cela.

Pourrais-je avoir vos avis s’il vous plait ? Merci

//Stock
$stock = $stockRep->findOneBy(['Book' => $book]);

if (!$stock) {
    $stock = new Stock();   
    $stock->setBook($book);
    $stock->setAuthor($author);
    $stock->setOrigin('library');                                   
} 
                                 
$sold = $stock->getSold();
$stock->setSold($sold + $checkoutLine->getQuantity());
$em->persist($stock);    

C’est un morceau du script un peu plus grand que voici, pour info :

#[Route('/caisse/generer-des-factures', name: 'checkout.fake')]
    public function generate(BookRepository $bookRep, StockRepository $stockRep, AuthorRepository $authorRep, EntityManagerInterface $em): void
    {       
        $books = $bookRep->findAll();
        $faker = Factory::create('fr_FR');

        $cp = ['35000', '44000', '33000', '75000', '59000', '13000'];
        $paymentMethods = ['Chèque', 'Carte bancaire', 'Espèces', 'Mairie', 'Autre'];
        $quantities = ['1', '1', '1', '1', '2'];

        for ($i = 0; $i < 150; $i++) {
            $checkout = new Checkout();

            $checkout->setCustomerName($faker->lastName());
            $checkout->setCustomerPostalCode($cp[array_rand($cp)]);
            $checkout->setPaymentMethod($paymentMethods[array_rand($paymentMethods)]);

            $totalAmount = 0;
            $j = rand(1, 4);
            for ($k = 1; $k <= $j; $k++) {
                $checkoutLine = new CheckoutLine();   
                
                $book = $books[array_rand($books)]; 
                
                $authors = $book->getAuthor();
                $author = $authors->first(); //un livre peut avoir plusieurs auteurs. Pour ce test je n'en ai besoin que d'un
                
                $checkoutLine->setBook($book);
                $checkoutLine->setQuantity($quantities[array_rand($quantities)]);
                $checkoutLine->setLineAmount($book->getPrice() * $checkoutLine->getQuantity());
                $totalAmount = $totalAmount + $checkoutLine->getLineAmount();
                $checkoutLine->setCheckout($checkout);
                $em->persist($checkoutLine);

                //Stock
                $stock = $stockRep->findOneBy(['Book' => $book]);

                if (!$stock) {
                    $stock = new Stock();   
                    $stock->setBook($book);
                    $stock->setAuthor($author);
                    $stock->setOrigin('library');                                   
                } 
                                 
                $sold = $stock->getSold();
                $stock->setSold($sold + $checkoutLine->getQuantity());
                $em->persist($stock);                               
            }

            $checkout->setTotalAmount($totalAmount);
            $checkout->setCreatedAt(\DateTimeImmutable::createFromMutable($faker->dateTimeBetween('2025-12-06 09:00:00', '2025-12-06 19:00:00')));
            
            $em->persist($checkout);
        }        

        $em->flush();
    }

Pour info, si je n’ai pas utilisé Fixtures, c’est que ce système purge intégralement ma BDD, hors je ne veux pas toucher à la table des livres, qui contient de vraies données liées aux vrais auteurs, qui n’ont pas à être effacées.

Et encore pour info, ce script fonctionne si je vire la partie sur les Stocks, mais bon, ne pas comptabiliser les chiffres de vente, c’est un peu foireux. Ceci dit, je peux sans doute les créer a posteriori, mais ça me semble un peu complexe pour quelque chose qui ne le devrait pas.

Salut ! Bonne année à toi aussi

Tu effectues un seul flush() en fin de script, ce qui fait que toutes les opérations sur la base de données sont effectuées une seule fois à ce moment. Du coup, comme rien n’existe en base avant, rien n’y est retrouvé quand tu y cherches quelque chose…

Je te propose d’enregistrer les stocks dans un tableau indexé par ID de livre, et de faire avec cette liste.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte