Bonjour je reviens avec une autre demande,
désormais j’ai bien les chambres disponible dans la période voulu, (Booking System)
je souhaite avoir en plus les « périodicités » de prix, en effet une chambre a un prix par nuit en fonction d’une date entré et de sorti.
Par exemple du 10/01 au 10/06 c’est 90€/n mais du 11/06 au 10/10 c’est 120€.

Première question comment stocker en base données des dates sans années ?
(Une saison de prix est valable tous les ans seul le jour et le mois sont à identifier !?)

J’ai donc une table « periodicities » et une table « periodicities_rooms »

Table Periodicities :

+-------------+---------------+------+-----+---------+----------------+ 
| Field       | Type          | Null | Key | Default | Extra          | 
+-------------+---------------+------+-----+---------+----------------+ 
| id          | int(11)       | NO   | PRI | NULL    | auto_increment | 
| name        | varchar(90)   | NO   |     | NULL    |                | 
| start       | date          | NO   |     | NULL    |                | 
| end         | date          | NO   |     | NULL    |                | 
| start_day   | tinyint(4)    | NO   |     | NULL    |                | 
| start_month | tinyint(4)    | NO   |     | NULL    |                | 
| end_day     | tinyint(4)    | NO   |     | NULL    |                | 
| end_month   | tinyint(4)    | NO   |     | NULL    |                | 
| price       | decimal(12,2) | NO   |     | NULL    |                | 
| modified    | datetime      | NO   |     | NULL    |                | 
+-------------+---------------+------+-----+---------+----------------+ 

(start et end sont des dates sans années que j’utilise pour faire des tests en ce moment)

Model Periodicities :

$this->belongsToMany('Rooms', [
            'foreignKey' => 'periodicity_id',
            'targetForeignKey' => 'room_id',
            'joinTable' => 'periodicities_rooms'
        ]);

Model Rooms :

$this->belongsToMany('Periodicities', [
            'foreignKey' => 'room_id',
            'targetForeignKey' => 'periodicity_id',
            'joinTable' => 'periodicities_rooms'
        ]);

Voici ma requête pour afficher les chambres disponible ainsi que les périodicités :

$check_in = new Date($this->request->data['check_in']);
            $check_out = new Date($this->request->data['check_out']);

            $this->loadModel('Rooms');
            $roomsAvailable = $this->Rooms->find('all')
            ->contain([
                'Bookings', 
                'Amenities',
                'Periodicities' =>  function ($q) use ($check_in, $check_out) {
                   return $q
                        ->where(function ($exp) use ($check_in, $check_out) {

                            $exp->between('Periodicities.start_day', $check_in->format('j'), $check_out->format('j'));
                            $exp->between('Periodicities.start_month', $check_in->format('n'), $check_out->format('n'));
                            return $exp;
                        })
                        ->orWhere(function ($exp) use ($check_in, $check_out) {
                            $exp->between('Periodicities.end_day', $check_in->format('j'), $check_out->format('j'));
                            $exp->between('Periodicities.end_month', $check_in->format('n'), $check_out->format('n'));
                            return $exp;
                        })
                        ;
                }

            ])
            ->notMatching('Bookings', function ($q) use ($check_in, $check_out) 
            {
                return $q                    
                    ->where(function ($q) use ($check_in, $check_out) {
                        return $q->between('Bookings.check_in', $check_in, $check_out);
                    })
                    ->orWhere(function ($q) use ($check_in, $check_out) 
                    {
                        return $q->between('Bookings.check_out', $check_in, $check_out);
                    })
                    ->andWhere(['Bookings.status' => true]);
            })
            ; 

Cependant elle ne me retourne pas les périodicités ,

Donc j’ai fait des tests avec cette autre requête :

$roomsAvailable = $this->Rooms->find('all')
            ->contain([
                'Bookings', 
                'Amenities',
                'Periodicities' =>  function ($q) use ($check_in, $check_out) {
                   return $q
                        ->where(function ($exp) use ($check_in, $check_out) {
                            $exp->between('Periodicities.start', $check_in, $check_out);
                            return $exp;
                        })
                        ->orWhere(function ($exp) use ($check_in, $check_out) {
                            $exp->between('Periodicities.end', $check_in, $check_out);
                            return $exp;
                        })
                        ;
                }

            ])
            ->notMatching('Bookings', function ($q) use ($check_in, $check_out) 
            {
                return $q                    
                    ->where(function ($q) use ($check_in, $check_out) {
                        return $q->between('Bookings.check_in', $check_in, $check_out);
                    })
                    ->orWhere(function ($q) use ($check_in, $check_out) 
                    {
                        return $q->between('Bookings.check_out', $check_in, $check_out);
                    })
                    ->andWhere(['Bookings.status' => true]);
            })
            ;

elle non plus ne fonctionne pas :/

Dois-je faire un matching sur la table Periodicities ?
Il est envisageable que ma structure de base de données ne soit pas adapté je peux la modifier.

Merci d’avoir pris le temps de me lire,

Avez vous des suggestions ?

Aucune réponse