Partage
  • Partager sur Facebook
  • Partager sur Twitter

[SQL/UML] Système réservation vehicule

Sujet résolu
    3 mai 2019 à 9:59:29

    Bonjour, j'espère que vous allez bien.
    Je rencontre des difficultés à mettre en place un système de réservation (avec demande et acceptation).

    Mise en contexte: Je souhaite réalisé un système de réservation (d'engins), possibilité de réserver pour plusieurs jours. 

    Formulaire de réservation: Nom, Type, Date de début, Date de fin

    Table engin: id_engin, nom_engin, type_engin
    Table reservation_engin: id_reservation, id_engin, dateDebut, dateFin

    J'ai donc décidé dans la table engin, de créer une ligne par engin, pour ne pas à avoir à gérer de stock. Parce que le stock peut être différent d'un jour à un autre pour le même engin.
    Je sais que ma configuration est fausse, mais je n'arrive pas à imaginer la liaison entre les dates et les stocks afin de définir si durant ce créneau un engin est disponible ou non.
    Quelqu'un pourrez me mettre sur la piste?

    Je travaille avec du php/sql.

    J'espère que j'ai été suffisamment clair ^^

    Merci beaucoup de m'avoir lu
    • Partager sur Facebook
    • Partager sur Twitter
      3 mai 2019 à 11:10:21

      Bonjour,

      ThéoLeao a écrit:

      J'ai donc décidé dans la table engin, de créer une ligne par engin, pour ne pas à avoir à gérer de stock

      Ce n'est pas forcément une mauvaise idée, et cela simplifie en effet la gestion des réservations ...

      ThéoLeao a écrit:

      définir si durant ce créneau un engin est disponible ou non

      Selon moi, il faut mettre en place 2 contrôles, un côté applicatif et un côté base de données. Les deux contrôles vont s'appuyer plus au moins sur la même requête :

      -- Liste des engins disponibles sur une période donnée
      SELECT DISTINCT id_engin
      FROM
          engin E
              LEFT JOIN reservation_engin R
                  ON E.id_engin = R.id_engin
                  AND R.dateDebut <= 'date fin souhaitée'
                  AND R.dateFin >= 'date début souhaitée'
      WHERE
          R.id_reservation IS NULL

      Cette requête te permet de lister à l'utilisateur seulement les engins disponibles sur la période donnée. Tu peux donc laisser l'utilisateur saisir ses dates, puis lui proposer les engins disponibles en fonction.

      Par contre il faut également mettre un contrôle en base de données pour empêcher d'enregistrer des réservations quasi-simultanées : deux utilisateurs réservent en même temps le même engin ... Cela se fera par le biais d'un TRIGGER BEFORE INSERT qui vérifiera que le véhicule est toujours disponible au moment de l'enregistrement en base :

      -- Disponibilité engin avant enregistrement
      SELECT COUNT(*)
      FROM reservation_engin R
      WHERE
          id_engin = NEW.id_engin
          AND dateDebut <= NEW.dateFin
          AND dateFin >= NEW.dateDebut

      Si cette requête retourne plus de 0 il faut bloquer l'INSERT avec un SIGNAL que tu traiteras côté applicatif pour informer l'utilisateur qu'il s'est fait grillé au poteau pour quelqu'un d'autre, et lui proposer de nouveau les engins disponibles pou les même dates ...

      Côté ergonomie, c'est sympa de proposer un planning des réservations existantes permettant à l'utilisateur d'ajuster ses dates lors de sa réservation.

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        3 mai 2019 à 12:10:40

        Wow, super, merci de ta réponse rapide, clair et précise, De ton post m'est venu une seconde idée. Mais j'ai quelques questions à te poser sur celle-ci si ça ne te dérange pas. Mais j'y reviendrais plus tard.

        Idée 1: Où le système effectue la réservation sans autorisation de l'admin (donc l'idée que tu proposes, super cool)

        J'ai écris sur papier l’algorithme afin de m'assurer de bien l'avoir compris, de plus il me parait cohérent et réalisable; Que j'ai retranscris ici:

        - Emprunteur entre sa demande (Nom, type, dateDebut, dateFin)

        - Emprunteur redirection étape 2 où sont listé les engins disponibles pour son intervalle grâce à cette requête via un tableau avec pour chaque ligne, un form pour récupérer l'id de l'engin, la dateDebut, la dateFin :

        -- Liste des engins disponibles sur une période donnée
        SELECT DISTINCT id_engin
        FROM
            engin E
                LEFT JOIN reservation_engin R
                    ON E.id_engin = R.id_engin
                    AND R.dateDebut <= 'date fin souhaitée'
                    AND R.dateFin >= 'date début souhaitée'
        WHERE
            R.id_reservation IS NULL

        **Pourquoi WHERE: R.id_reservation IS NULL?**

        **Pour la création de ce tableau, il se fera dans une boucle for (avec incrémentation), comment je peux relié cette boucle avec la requête SQL? **

        - Emprunteur sélectionne un engin en cliquant sur le bouton de la ligne correspondant à l'engin voulu

        - Redirection sur la page post de l'engin où on effectue la vérification de la disponibilité ainsi que l'enregistrement de la reservation grâce à:

            Si le résultat de:

        -- Disponibilité engin avant enregistrement
        SELECT COUNT(*)
        FROM reservation_engin R
        WHERE
            id_engin = NEW.id_engin
            AND dateDebut <= NEW.dateFin
            AND dateFin >= NEW.dateDebut

        est supérieur à zéro. Alors afficher à l'utilisateur qu'entre-temps quelqu'un d'autre a déjà réservé l'engin qui était disponible et qu'il ne l'est plus.

        Si c'est égale à zero:

        - Insérer dans reservation_engin la reservation

        Idée 2: Où l'utilisateur fait la demande et l'administrateur lui choisit quel engin il attribut et se réserve le droit d'acceptation (qui correspondrait plus à mon projet).

        Pareil j'ai écris sur papier le début de l’algorithme, mais je me trouves bloqué à une étape car je me demande, qu'est-ce qui est le plus correcte:

        - Le fait de creer plusieurs table reservations:

             -reservation_enattente

             -reservation_encours

             -reservation_archive

        - Le fait d'ajouter à la table reservation une colonne etat:

             - Table reservation_engin(id_engin,dateDebut,dateFin,etat)

             - où Etat = 1 (En attente), Etat = 2 (En cours), Etat = 3 (Archive)

        Ce qui changerais complètement la requête permettant de voir la liste des engins disponible au niveau des jointures:

        Cette requête:

        -- Liste des engins disponibles sur une période donnée
        SELECT DISTINCT id_engin
        FROM
        engin E
        LEFT JOIN reservation_engin R
        ON E.id_engin = R.id_engin
        AND R.dateDebut <= 'date fin souhaitée'
        AND R.dateFin >= 'date début souhaitée'
        WHERE
        R.id_reservation IS NULL

        - Mais la suite, concernant la vérification de disponibilité avant insertion dans la base, je pense que ça changera rien.

        Si tu pourrais m'éclairer un peu sur ces différents points, ce serait vraiment super de ta part.

        Merci beaucoup !!

        • Partager sur Facebook
        • Partager sur Twitter
          3 mai 2019 à 14:19:15

          ThéoLeao a écrit:

          **Pourquoi WHERE: R.id_reservation IS NULL?**

          Justement pour lister les engins qui ne sont pas lié à une réservation dans la période donnée, c'est le principe de la jointure externe que de retourner NULL si aucun enregistrement n'existe.

          ThéoLeao a écrit:

          **Pour la création de ce tableau, il se fera dans une boucle for (avec incrémentation), comment je peux relié cette boucle avec la requête SQL? **

          Euh ... je ne comprends pas ... Ton code PHP, avec la classe PDO par exemple, lance la requête SQL et récupère le résultat dans un tableau. Avec ce tableau tu peux afficher une balise <select> ou tout autre élément HTML permettant la sélection ... Au passage cela peut se faire avec un bout de JavaScript/AJAX pour éviter de recharger ta page.

          ThéoLeao a écrit:

          Si le résultat de la requête [...] est supérieur à zéro. Alors afficher à l'utilisateur qu'entre-temps quelqu'un d'autre a déjà réservé l'engin qui était disponible et qu'il ne l'est plus.

          Si c'est égale à zero insérer dans reservation_engin la reservation

          En fait non, là tu refais un contrôle applicatif ... qui va revenir au même que le premier contrôle. Il faut mettre en place un TRIGGER en base de données. Lorsque PHP va lancer la requête INSERT INTO reservation_engin, alors la base de données va exécuter le TRIGGER et lever une erreur en cas de conflit de date. C'est cette erreur qu'il faudra traiter côté PHP pour informer l'utilisateur (avec un bloc Try/Catch).

          Après, pour moi les solutions 1 et 2 sont presque identiques, car tu ne dois pas de toute façon autoriser un utilisateur à enregistrer une réservation incompatible avec le planning, même si elle doit être validée dans un second temps par l'administrateur ... Tu fais croire à l'utilisateur que sa réservation est bonne alors que l'administrateur devra la déplacer (celle là ou une autre) pour qu'elle rentre dans le planning.

          Donc pour moi, le fonctionnement décris dans l'idée 1 (et précisé/corrigé/complété comme dit juste avant) est la base. L'idée 2 c'est toute l'idée 1 + la colonne "état" pour distinguer ce qu'a traité l'administrateur ou non.

          -
          Edité par Benzouye 3 mai 2019 à 14:21:11

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            26 mai 2019 à 14:09:31

            Bonjour,

            J'ai personnellement testé ce script, mais il me renvoie quand même les id_engin en tant que 'NULL', bien que dans la table réservation ceux-ci soient occupés durant cette période.

            Le script est le même, serait-ce un problème de format DATE ('2010-06-23') ?

            Merci de votre aide

            • Partager sur Facebook
            • Partager sur Twitter
              27 mai 2019 à 9:06:53

              Quel est le type des colonne dateDebut et dateFin ? DATE ? DATETIME ? autre chose ?

              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                27 mai 2019 à 9:20:00

                J’ai essayé le type DATE et timestamp
                • Partager sur Facebook
                • Partager sur Twitter
                  27 mai 2019 à 10:05:55

                  Peux-tu fournir un dump SQL de ta base en l'état, avec quelques données d'exemple ?

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                    27 mai 2019 à 11:13:45

                    En réalité, mon script n'est vraiment pas complexe, le voici ci-dessous

                    CREATE TABLE RESERV (idR INT NOT NULL AUTO_INCREMENT ,idengin INT NOT NULL, PRIMARY KEY (idR),datedeb DATE NOT NULL, datefin DATE NOT NULL, FOREIGN KEY (idengin) REFERENCES ENGINS (idengin))"

                    CREATE TABLE ENGIN (idengin INT NOT NULL AUTO_INCREMENT ,nom VARCHAR(100), PRIMARY KEY (idengin))

                    INSERT INTO `RESERV`(`idR`, `idengin`, `datedeb`, `datefin`) VALUES ('',1001,'2010-12-06','2010-12-07')

                    SELECT DISTINCT * FROM ENGIN e LEFT JOIN RESERV r ON e.idengin = r.idR AND r.datedeb = '2010-12-06' WHERE  r.idR IS NULL

                    Avec une réservation, la requête ne prend pas en compte cette dernière.

                    -
                    Edité par GigiCamille 27 mai 2019 à 11:33:12

                    • Partager sur Facebook
                    • Partager sur Twitter
                      27 mai 2019 à 11:32:35

                      Cette requête SELECT te ressort la ligne que tu viens d'insérer ?

                      Ce n'est pas possible ... sauf si idR vaut vraiment NULL ...

                      Avec cet INSERT, le SELECT ne doit pas ressortir la réservation insérée ...

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                        27 mai 2019 à 12:34:54

                        Oui justement, avec ce SELECT, il me renvoie absolument tous les engins de la table ENGINS, sans distinction. Alors que dans la table RESERV la date 2010-12-06 est bien réservée. 

                        En tant normal on devrait avoir tous les engins avec NULL, sauf le 1001 qui est réservé à la date souhaitée.

                        idR ne peut être NULL, puisque lors de la création de table on a bien noté idR INT NOT NULL AUTO_INCREMENT.

                        -
                        Edité par GigiCamille 27 mai 2019 à 12:35:16

                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 mai 2019 à 13:01:28

                          GigiCamille a écrit:

                          En tant normal on devrait avoir tous les engins avec NULL, sauf le 1001 qui est réservé à la date souhaitée

                          Exactement.

                          Le problème, je ne l'avais pas vu, vient de ta condition de jointure ...

                          GigiCamille a écrit:

                          ON e.idengin = r.idR

                          C'est plutôt e.idengin = r.idengin ...
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                            27 mai 2019 à 13:33:43

                            Ahh c'est exact, suis-je bête.

                            En tout, c'est assez rare pour le remarquer, merci de ta sympathie et de ton temps de réaction.

                            • Partager sur Facebook
                            • Partager sur Twitter

                            [SQL/UML] Système réservation vehicule

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown