[PHP]Funzione di calcolo prezzo di una camera in un range di date

maxnegri

Utente Attivo
12 Ott 2004
87
0
6
Scusate ma non ho inserito il titolo. Chiedo scusa!!!
ecco il titolo da inserire:
Funzione di calcolo prezzo di una camera in un range di date

Ciao a tutti, sto cercando di modificare una funzione di calcolo presa da uno script php realizzato con CodeIgniter che mi dia il risultato del prezzo totale di una camera in relazione ad una data di arrivo ed una di partenza.
Ho due tabelle:
La prima "room" che ha dei prezzi base settimanali ( price_mon,price_tue,price_wed,price_thu,price_fri,price_sat,price_sun )
La seconda "room_custom_price" che ha prezzi personalizzati base alla data ( certain_date, price )
La funzione dovrebbe calcolare primail prezzo base e poi controllare se ci sono prezzi personalizzati per poi fornire il totale.

Questa è la funzione ma non riesco a capire come mai non mi fornisce il totale:

Codice:
function calcProcess($roomId, $startDate, $endDate)    {
$startDate = new DateTime($startDate->date('Y-m-d'));   
$result['totalNight'] = 0;   
$result['totalPrice'] = 0;
$statement = " SELECT           
price_sun AS d0,           
price_mon AS d1,           
price_tue AS d2,           
price_wed AS d3,           
price_thu AS d4,           
price_fri AS d5,           
price_sat AS d6       
FROM           
room       
WHERE           
id = $roomId ";   
$statement->execute(array(                   
':id' => $roomId   
));   
$defaultPrice = $statement->fetchAssociativeArray();   
$statement->close();   
// fine
// calcolo custom price   
$statement = "       
SELECT           
certain_date,           
price       
FROM           
room_custom_price       
WHERE           
room_id = $roomId AND           
(certain_date BETWEEN :startDate AND :endDate)";   
$statement->execute(array(       
':roomId' => $roomId,       
':startDate' => $startDate->date('Y-m-d'),       
':endDate' => $endDate->date('Y-m-d')   
));   
$rows = $statement->fetchAllAssociative();   
$statement->close();   
$customPriceArray = array();   
foreach ($rows as $row) {       
$customPriceArray[$row['certain_date']] = $row['price'];   
}   
// fine
while ($startDate->format('Y-m-d') != $endDate->date('Y-m-d')) {       
$result['totalNight']++;
 if (array_key_exists($startDate->format('Y-m-d'), $customPriceArray)) {           
$result['totalPrice'] += $customPriceArray[$startDate->date('Y-m-d')];       
}      
 else {           
$result['totalPrice'] += $defaultPrice['d'.$startDate->date('w')];       
}
$startDate->modify('+1 day');   
}
return $result;           
}
var_dump($result);

Spero qualcuno possa aiutarmi. Grazie!
 
Se utilizzi CI prova questa, non l'ho testata ma dovrebbe andare:
Ho utilizzato la func dell'altra volta "get_diff_Date".... Non commento è abbastanza semplice da seguire.
PHP:
function find_sconto(){
  //da implementare
   $model_return=['sconto'=>0,'type'=>'percentage','skip_zero'=>TRUE];
   return $model_return;
}
function cal_price_($room,$start_date,$end_date){
   $ci=&get_instance();
   $date_diff=get_diff_Date($start_date,$end_date);
   $model_result=
      [
         'operation'=>
            [
               'plus'=>[
                  'custom'=>0,
                  'normal'=>0
               ],
//da implementare le regole di calcolo
               'minus'=>find_sconto()
            ],
         'total'=>0,
         'per_night'=>0
      ];
   $data=$ci->db->where('id',$room)->get('room')->result_object();
   $data_custom=$ci->db->where('room_id',$room)
                       ->where('DATE(certain_date) >=',$start_date,FALSE)
                       ->where('DATE(certain_date) <=',$end_date,FALSE)
                       ->get('room_custom_price')->result_object();
   $map=['price_sun','price_mon','price_tue','price_wed','price_thu','price_fri','price_sat'];
   if(!empty($data_custom)){
      //prezzi personalizzati
      foreach ($data_custom as $k=>$items){
         $model_result['operation']['plus']['custom']+=$items->price;
      }
   }
    foreach ($data as $jey_q=>$value_q){
        foreach ($date_diff as $k=>$v){
         $model_result['operation']['plus']['normal']+=$value_q->$map[$v['day']];
      }
   }
   foreach ($model_result['operation']['plus'] as $k=>$v){
      $model_result['total']+=$v;
   }
   $model_result['per_night']=$model_result['total']/count($date_diff);
   return $model_result;
}
 
Ultima modifica:
Ciao e grazie mille per l'interesse. Sto provando la funzione ma il risultato è sempre NULL.
Probabilmente hai aggiunto nuovi campi al db relativi agli sconti e per questo non calcola il totale?
Codice:
'sconto'=>0,'type'=>'percentage','skip_zero'=>TRUE
I nuovi campi li hai inseriti nella tabella room_custom_price ?
 
Il db non l'ho creato, la funzione "find_sconto" server per avere un modello di calcolo completo...
Probabilmente hai aggiunto nuovi campi al db relativi agli sconti e per questo non calcola il totale?
No, ho lasciato a te l'onere di creare la logica di sconto e valorizzare il model!

Dovrebbe funzionare, se magari mi dai l'output riesco a vedere cosa non va!
 
però sistemerei le due query ( clausola where ) per renderle compatibili con "execute", nello script originale
Codice:
 FROM room
 WHERE id = :id
";

$statement->execute(array(':id' => $roomId));



 FROM room_custom_price
 WHERE room_id = :roomId AND (certain_date BETWEEN :startDate AND :endDate)
";
    $statement->execute(array(
        ':roomId'    => $roomId,
        ':startDate' => $startDate->date('Y-m-d'),
        ':endDate'   => $endDate->date('Y-m-d')));
 
a ok. Scusa come ti do l'output? io sto usando
Codice:
var_dump($model_result)
ed ottengo NULL.
Non mi da altri errori php. I campi sembrano giusti e le date sono in formato Y-m-d.
 
Allora, un pò di screen così vedi cosa ho fatto.....
Da modificare nella funzione 2 punti in quanto resa generica dai miei helpers....
PHP:
//nei where eliminare il FALSE
$data_custom=$ci->db->where('room_id',$room)
                    ->where('DATE(certain_date) >=',$start_date)
                    ->where('DATE(certain_date) <=',$end_date)
                    ->get('room_custom_price')->result_object();

/******************************/
foreach ($date_diff as $k=>$v){
   foreach ($data as $jey_q=>$value_q){
     //modificare qui il $value_q->$map[$v['day']]; come mostrato
      $day=$map[$v['day']];
      $model_result['operation']['plus']['normal']+=$value_q->$day;
   }
}


/********************************************************************/


//esecuzione del codice
public function test_price(){
   $data=cal_price_(1,'2019-01-19','2019-01-22');
   print_r($data);
}

OUTPUT:
Codice:
Array
(
[operation] => Array
(
[plus] => Array
(
[custom] => 15
[normal] => 20
)

[minus] => Array
(
[sconto] => 0
[type] => percentage
[ship_0] => 1
)

)

[total] => 35
[per_night] => 11.666666666667
)
Fammi sapere....
 

Allegati

  • 1_funzione.png
    1_funzione.png
    9,1 KB · Visite: 406
  • 1_result.png
    1_result.png
    11,3 KB · Visite: 415
  • 1_tabella_agg.png
    1_tabella_agg.png
    24,4 KB · Visite: 421
  • 1_tabella_room.png
    1_tabella_room.png
    18,6 KB · Visite: 408
Nulla mi sa che sto facendo un casino. Potresti postarmi il codice completo con le correzioni?
Poi se richiamo solo la funzione
PHP:
//esecuzione del codice
public function test_price(){
   $data=cal_price_(1,'2019-01-19','2019-01-22');
   print_r($data);
}[/CODE] mi da errore di scrittura. Se invece elimino public [CODE]
function test_price(){
   $data=cal_price_(1,'2019-01-19','2019-01-22');
   print_r($data);
}
non mi segnala l'errore di scrittura.
 
Ultima modifica di un moderatore:
Spero tu stia utilizzando CI...!
PHP:
function get_diff_Date($dt1,$dt2){
   $data_in=new DateTime($dt1);
   $data_out=new DateTime($dt2);
   $diff=$data_out->diff($data_in);
   $create_date=[];
   for ($i=1;$i<=$diff->days;$i++) {
      $data_in->add(new DateInterval('P1D'));
      $create_date[]=
         [
            'date'=>$data_in->format('d/m/Y'),
            'day'=>$data_in->format('w'),
            'label_day'=>$data_in->format('l')
         ];
   }
   return $create_date;
}

function find_sconto(){
   /*
      'sconto'=>0,
   //percentuale o fisso (fixed)
      'type'=>'percentage',
      'skip_if_0'=>TRUE
   /*/
   $model_return=['sconto'=>0,'type'=>'percentage','ship_0'=>TRUE];
   return $model_return;
}

function cal_price_($room,$start_date,$end_date){
   $ci=&get_instance();
   $date_diff=get_diff_Date($start_date,$end_date);
   $model_result=
      [
         'operation'=>
            [
               'plus'=>[
                  'custom'=>0,
                  'normal'=>0
               ],
               'minus'=>find_sconto()
            ],
         'total'=>0,
         'per_night'=>0
      ];

   $data=$ci->db->where('id',$room)->get('room')->result_object();
   $data_custom=$ci->db->where('room_id',$room)
                       ->where('DATE(certain_date) >=',$start_date)
                       ->where('DATE(certain_date) <=',$end_date)
                       ->get('room_custom_price')->result_object();
   $map=['price_sun','price_mon','price_tue','price_wed','price_thu','price_fri','price_sat'];

   if(!empty($data_custom)){
      //non ci sono prezzi personalizzati
      foreach ($data_custom as $k=>$items){
         $model_result['operation']['plus']['custom']+=$items->price;
      }
   }
   foreach ($date_diff as $k=>$v){
      foreach ($data as $jey_q=>$value_q){
         $day=$map[$v['day']];
         $model_result['operation']['plus']['normal']+=$value_q->$day;
      }
   }
   foreach ($model_result['operation']['plus'] as $k=>$v){
      $model_result['total']+=$v;
   }
   $model_result['per_night']=$model_result['total']/count($date_diff);

   return $model_result;
}
 
function get_diff_Date($dt1,$dt2){
$data_in=new DateTime($dt1);
$data_out=new DateTime($dt2);
$diff=$data_out->diff($data_in);
$create_date=[];
for (
$i=1;$i<=$diff->days;$i++) {
$data_in->add(new DateInterval('P1D'));
$create_date[]=
[
'date'=>$data_in->format('d/m/Y'),
'day'=>$data_in->format('w'),
'label_day'=>$data_in->format('l')
];
}
return
$create_date;
}
Forse l'errore sta in questa funzione le date $data_in e $data_out che sono diverse da tutto il resto delle funzioni?
 
No è l'istanza CodeIgniter..... altrimenti non avrei scritto
PHP:
$ci=&get_instance();

Se utilizzi la un tuo script custom devi cambiare le query... cosa da poco!


qui fai due prove di calcolo: https://perms.madi-solution.it/test_calcolo

Forse l'errore sta in questa funzione le date $data_in e $data_out che sono diverse da tutto il resto delle funzioni?
Quella funzione viene utilizzata per i giorni della settimana e basta quindi no!
 
@maxnegri
Quando posti codice PHP non usare il tag
code.gif
ma sa il tag
php.png

Questa volta te lo ho corretto io
Grazie
 
Il problema è proprio quello. Io non utilizzo CodeIgniter ma uno script che sto creando io.
Potresti cortesemente specificarmi dove sostituire le query?
 
Ecco il codice completo che ho nella pagina. Ho modificato anche startDate in data_in e endDate in data_out
PHP:
$room=$id;
$datain="2019-08-26"; // data di arrivo
$dataout="2019-08-30"; // data di partenza
$data_in=new DateTime($datain);
$data_out=new DateTime($dataout);
function get_diff_Date($dt1,$dt2){
   $data_in=new DateTime($dt1);
   $data_out=new DateTime($dt2);
   $diff=$data_out->diff($data_in);
   $create_date=[];
   for ($i=1;$i<=$diff->days;$i++) {
      $data_in->add(new DateInterval('P1D'));
      $create_date[]=
         [
            'date'=>$data_in->format('d/m/Y'),
            'day'=>$data_in->format('w'),
            'label_day'=>$data_in->format('l')
         ];
   }
   return $create_date;
}

function find_sconto(){
   /*
      'sconto'=>0,
   //percentuale o fisso (fixed)
      'type'=>'percentage',
      'skip_if_0'=>TRUE
   /*/
   $model_return=['sconto'=>0,'type'=>'percentage','ship_0'=>TRUE];
   return $model_return;
}

function cal_price_($room,$data_in,$data_out){
   $ci=&get_instance();
   $date_diff=get_diff_Date($data_in,$data_out);
   $model_result=
      [
         'operation'=>
            [
               'plus'=>[
                  'custom'=>0,
                  'normal'=>0
               ],
               'minus'=>find_sconto()
            ],
         'total'=>0,
         'per_night'=>0
      ];

   $data=$ci->db->where('id',$room)->get('room')->result_object();
   $data_custom=$ci->db->where('room_id',$room)
                       ->where('DATE(certain_date) >=',$data_in)
                       ->where('DATE(certain_date) <=',$data_out)
                       ->get('room_custom_price')->result_object();
   $map=['price_sun','price_mon','price_tue','price_wed','price_thu','price_fri','price_sat'];

   if(!empty($data_custom)){
      //non ci sono prezzi personalizzati
      foreach ($data_custom as $k=>$items){
         $model_result['operation']['plus']['custom']+=$items->price;
      }
   }
   foreach ($date_diff as $k=>$v){
      foreach ($data as $jey_q=>$value_q){
         $day=$map[$v['day']];
         $model_result['operation']['plus']['normal']+=$value_q->$day;
      }
   }
   foreach ($model_result['operation']['plus'] as $k=>$v){
      $model_result['total']+=$v;
   }
   $model_result['per_night']=$model_result['total']/count($date_diff);

   return $model_result;
}


var_dump($model_result);
function test_price(){
   $data=cal_price_(1,'2019-01-19','2019-01-22');
   print_r($data);
}
 
Al posto di queste metti le tue query
PHP:
 $data=$ci->db->where('id',$room)->get('room')->result_object();
   $data_custom=$ci->db->where('room_id',$room)
                       ->where('DATE(certain_date) >=',$data_in)
                       ->where('DATE(certain_date) <=',$data_out)
                       ->get('room_custom_price')->result_object();

PHP:
$statement = " SELECT  * 
FROM           
room       
WHERE           
id = $roomId ";   
$statement->execute(array(                   
':id' => $roomId   
));   
$data= $statement->fetchAll(PDO::FETCH_CLASS, 'room');


$statement = "       
SELECT           
certain_date,           
price       
FROM           
room_custom_price       
WHERE           
room_id = $roomId AND           
(certain_date BETWEEN :startDate AND :endDate)";   
$statement->execute(array(       
':roomId' => $roomId,       
':startDate' => $startDate->date('Y-m-d'),       
':endDate' => $endDate->date('Y-m-d')   
));   
$data_custom=$statement->fetchAll(PDO::FETCH_CLASS, 'custom');
Try this!
 
var_dump($model_result);
function
test_price(){
$data=cal_price_(1,'2019-01-19','2019-01-22');
print_r($data);
}
Qui sbagli l'esecuzione.....
PHP:
test_price();
Non avendo CI come fai ad utilizzare
PHP:
$ci->db->get()
, quindi dovresti modificare la parte CI con la tua conn!
 
Ti ringrazio per la pazienza che mi hai concesso ma ancora non sono riuscito ad ottenere risultati.
Non ho una connessione PDO e quindi ho fatto come segue ma senza ottenere risultati. Ottengo ancora NULL
PHP:
$roomId=$id;
$start_date="2019-08-26"; // data di arrivo
$end_date="2019-08-30"; // data di partenza


function find_sconto(){
   /*
      'sconto'=>0,
   //percentuale o fisso (fixed)
      'type'=>'percentage',
      'skip_if_0'=>TRUE
   /*/
   $model_return=['sconto'=>0,'type'=>'percentage','ship_0'=>TRUE];
   return $model_return;
}

function cal_price_($room,$start_date,$end_date){
   $ci=&get_instance();
   $date_diff=get_diff_Date($start_date,$end_date);
   $model_result=
      [
         'operation'=>
            [
               'plus'=>[
                  'custom'=>0,
                  'normal'=>0
               ],
               'minus'=>find_sconto()
            ],
         'total'=>0,
         'per_night'=>0
      ];

$statement1 = " SELECT * FROM room WHERE id = $roomId "; 
$statement1->execute(array(                 
':id' => $roomId 
)); 
$data=mysqli_query($conn,$statement1);
mysqli_fetch_all($data,'room');
//$data= $statement->fetchAll(PDO::FETCH_CLASS, 'room');


$statement2 = "SELECT certain_date,price FROM room_custom_price WHERE room_id = $roomId AND (certain_date BETWEEN :startDate AND :endDate)"; 
$statement2->execute(array(     
':roomId' => $roomId,     
':startDate' => $startDate->date('Y-m-d'),     
':endDate' => $endDate->date('Y-m-d') 
)); 
$data_custom=mysqli_query($conn,$statement2);
mysqli_fetch_all($data_custom,'custom');
//$data_custom=$statement->fetchAll(PDO::FETCH_CLASS, 'custom');


   $map=['price_sun','price_mon','price_tue','price_wed','price_thu','price_fri','price_sat'];

   if(!empty($data_custom)){
      //non ci sono prezzi personalizzati
      foreach ($data_custom as $k=>$items){
         $model_result['operation']['plus']['custom']+=$items->price;
      }
   }
   foreach ($date_diff as $k=>$v){
      foreach ($data as $jey_q=>$value_q){
         $day=$map[$v['day']];
         $model_result['operation']['plus']['normal']+=$value_q->$day;
      }
   }
   foreach ($model_result['operation']['plus'] as $k=>$v){
      $model_result['total']+=$v;
   }
   $model_result['per_night']=$model_result['total']/count($date_diff);

   return $model_result;
}

var_dump($model_result);
 
PHP:
$mysqli=new mysqli('host','user','pass','dbname');

//$mysqli->query('SELECT * FROM room WHERE id = :id');
$query=$mysqli->query('SELECT * FROM room WHERE id = '.$room);
$data=json_decode(json_encode($query->fetch_all(MYSQLI_ASSOC)));
print_r($data);


$query=$mysqli->query('SELECT * FROM room_custom_price WHERE (DATE(certain_date) BETWEEN "'.$start_date.'" AND "'.$end_date.'")');
$data_custom=json_decode(json_encode($query->fetch_all(MYSQLI_ASSOC)));
print_r($data_custom);
Le variabili si chiamano come quelle della funzione sopra, quindi basta rimpiazzare il contenuto...
Spero ti vada bene---!
 

Discussioni simili