IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

besoin d'aide pour un gros calcul de malade


Sujet :

Langage PHP

  1. #1
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2007
    Messages : 696
    Points : 222
    Points
    222
    Par défaut besoin d'aide pour un gros calcul de malade
    bonjour à tous.
    bon voila, j'ai besoin d'un coup de main pour avancer un programme que je fais.
    disons que je loue des maisons, et j'ai un système de saisons!
    j'ai 4 saisons avec les id 1, 2, 3...
    pour chacune de ces saisons, j'ai des tarifs de location par semaine, weekend et nuitée différents !

    exemple :
    voici un tableau ou je rends ma maison dispo avec les saison de mon choix :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $dates_loc = array(array('date_debut' => '2010-05-02', 'date_fin' => '2010-05-16', 'saison' => 1, 'tarifs' => array('tarif_semaine' => 500, 'tarif_weekend' => 150, 'tarif_nuitee' => 40)),
    				   array('date_debut' => '2010-05-17', 'date_fin' => '2010-05-31', 'saison' => 2, 'tarifs' => array('tarif_semaine' => 400, 'tarif_weekend' => 100, 'tarif_nuitee' => 30)),
    				   array('date_debut' => '2010-06-01', 'date_fin' => '2010-06-12', 'saison' => 3, 'tarifs' => array('tarif_semaine' => 300, 'tarif_weekend' => 75, 'tarif_nuitee' => 25)));
    $nb_dates_loc = count($dates_loc);
    ici je loue ma maison entre les dates suivantes (aaaa-mm-jj) :
    - entre le 2010-05-02 et le 2010-05-16
    - entre le 2010-05-17 et le 2010-05-31
    - entre le 2010-05-01 et le 2010-06-12

    bon maintenant, disons que j'ai trouvé un locataire, il veut prendre ma maison entre le 2010-05-04 et le 2010-05-28 !!

    le tarif semaine : du lundi au vendredi
    weekend : samedi et dimanche
    nuitée : lorsque ce n'est ni une semaine ni un week end.

    par exemple :
    disons que je loue ma maison entre un mercredi et le dimanche de la semaine d'après. la première semaine est incomplète, il s'agit dond d'une nuitée, on paira au jour. ensuite on paie le week end comme convenue, et la semaine d'après aussi.
    CEPENDANT, si durant la semaine d'après par exemple on change de "saison", on doit calculer les jours individuellement.

    pour avoir la liste de chaque jour entre 2 dates, j'ai la fonction suisante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    function getDatesBetween($dStart, $dEnd)
    {
    	$iStart = strtotime ($dStart);
    	$iEnd = strtotime ($dEnd);
    	if (false === $iStart || false === $iEnd)
    	{
    		return false;
    	}
    	$aStart = explode ('-', $dStart);
    	$aEnd = explode ('-', $dEnd);
    	if (count ($aStart) !== 3 || count ($aEnd) !== 3)
    	{
    		return false;
    	}
    	if (false === checkdate ($aStart[1], $aStart[2], $aStart[0]) || false === checkdate ($aEnd[1], $aEnd[2], $aEnd[0]) || $iEnd <= $iStart)
    	{
    		return false;
    	}
    	for ($i = $iStart; $i < $iEnd + 86400; $i = strtotime ('+1 day', $i) )
    	{
    		$sDateToArr = strftime ('%Y-%m-%d', $i);
    		$aDates[] = $sDateToArr;
    	}
    	if (isset ($aDates) && !empty ($aDates))
    	{
    		return $aDates;
    	}
    	else
    	{
    		return false;
    	}
    }
    voici le tableau du locataire, avec les dates qu'il souhaite disposer du bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $dates_reserv = array(array('date_debut' => '2010-05-04', 'date_fin' => '2010-05-28'));
    $nb_dates_reserv = count($dates_reserv);
    et voici la méga fonction de la mort qui tue que j'ai commencé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    /****************************************************************************************************/
    /*	CALCUL DU PRIX POUR CHAQUE RESERVATION															*/
    /****************************************************************************************************/
    $tab_jour_et_tarifs = array();
    $prix_ht = 0;
    for($j=0;$j<$nb_dates_reserv;$j++)
    {
    	// création d'un tableau ayant tous les jours de réservation avec les tarifs
    	$k = 0;
    	$liste_dates_reserv = getDatesBetween($dates_reserv[$j]['date_debut'], $dates_reserv[$j]['date_fin']);
    	foreach($liste_dates_reserv as $date_reserv)
    	{
    		for($i=0;$i<$nb_dates_loc;$i++)
    		{
    			list($annee, $mois, $jour) = explode('-', $dates_loc[$i]['date_debut']);
    			$date_debut = mktime(0,0,0,$mois,$jour,$annee);
     
    			list($annee, $mois, $jour) = explode('-', $dates_loc[$i]['date_fin']);
    			$date_fin = mktime(0,0,0,$mois,$jour,$annee);
     
    			list($annee, $mois, $jour) = explode('-', $date_reserv);
    			$jour_reservation = mktime(0,0,0,$mois,$jour,$annee);
     
    			// si la date de RESERVATION est entre les 2 dates de LOCATION, on s'occupe des calculs
    			if(($jour_reservation >= $date_debut) && ($jour_reservation <= $date_fin))
    			{
    				$tab_jour_et_tarifs[$k]['jour'] = date('Y-m-d', $jour_reservation);
    				$tab_jour_et_tarifs[$k]['saison'] = $dates_loc[$i]['saison'];
    				$tab_jour_et_tarifs[$k]['tarifs'] = $dates_loc[$i]['tarifs'];
    				$k++;
    			}
    		}
    	}
    	$nb_jour = count($tab_jour_et_tarifs);
     
    	//print_r($tab_jour_et_tarifs);
     
    	for($i=0;$i<$nb_jour;$i++)
    	{
    		/****************************************************/
    		/*	RECHERCHE DES SEMAINES A 5 JOURS				*/
    		/****************************************************/
    		list($annee, $mois, $jour) = explode('-', $tab_jour_et_tarifs[$i]['jour']);
    		// est-ce un lundi ?
    		$num_jour = date('w', mktime(0,0,0,$mois,$jour,$annee));
    		$semaine = true;
    		if($num_jour == 1)
    		{
    			// pour les 4 jours prochains
    			for($l=1;$l<=4;$l++)
    			{
    				// si c'est une semaine et qu'elle est toute entiere dans la meme saison ...
    				$demain = date('Y-m-d', mktime(0,0,0,$mois,$jour+$l,$annee));
    				if(($tab_jour_et_tarifs[$i+$l]['jour'] == $demain) && ())
    			}
    		}
    	}
    }
    bon je coince en bas de la fonction >_<
    jusque là j'ai réussi a réunir tous les jours réservés, avec la saison qui leur correspond et les différents tarifs.
    mais je n'arrive plus à avancer, et j'ai la tête enflée :s
    Pourriez-vous m'aider ?

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Quand on fait un code comme ca, il faut tout de suite le structurer par des fonctions : le code est plus clair est plus facile à debuguer.

    De quoi avons-nous besoin ?
    - une fonction qui determine quel formule appliquer : definir_formule
    - une fonction qui determine la periode : defini_periode
    - une fonction qui parcourt les jours : browse
    Mon idée est de parcourir les jours en recherchant quelle formule je peux appliquer et ensuite par chacun des jours de la formule regarder quel tarif j'applique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    <?php
     
    class Location {
     
    function __construct() {
    	date_default_timezone_set('Europe/Paris');
    	$this->tblFormule = array('semaine'=>
    								array('duree'=>5, 'label'=>'tarif semaine'),
    							'weekend'=>
    								array('duree'=>2, 'label'=>'tarif week-end'),
    							'nuit'=>
    								array('duree'=>1, 'label'=>'tarif nuitée')
    	);
     
    	$this->tblPeriode = array(
    							0=>array('debut'=>'2010-04-10','fin'=>'2010-04-24'),
    							1=>array('debut'=>'2010-09-10','fin'=>'2010-12-25'),
    							1=>array('debut'=>'2010-04-25','fin'=>'2010-4-27')
    						);
     
    	$this->tblTarifs = array(
    						0=>array('semaine'=>300, 'weekend'=>100, 'nuit'=>65),
    						1=>array('semaine'=>350, 'weekend'=>150, 'nuit'=>85)
    					);
    }
     
    function browse($date_begin, $date_end) {
    	$objDate_begin = new DateTime($date_begin);
    	$objDate_end = new DateTime($date_end);
     
    	$this->objJour = clone($objDate_begin);
     
    	while($this->objJour->format('U') <= $objDate_end->format('U')) {
    		$formule = $this->definir_formule($this->objJour, $objDate_end);
    		for ($i = 0; $i <= $this->tblFormule[$formule]['duree'] - 1; $i++) {
    			$periode = $this->definir_periode($this->objJour);
    			echo $this->objJour->format('d/m/Y'). ' : ';
    			if ($periode !== FALSE) {
    				$prix = $this->tblTarifs[$periode][$formule];
    				echo $this->tblFormule[$formule]['label'] . ' ' . $prix;
    				echo '<br/>';
    			}
    			else {
    				echo 'pas de location';
    			}
    			$this->objJour->modify('+1 day');
    			echo '<br/>';
    		}
    	}
    }
     
    function definir_periode($objDate) {
    	foreach ($this->tblPeriode as $key=>$dates) {
    		if ($objDate->format('U') >= strtotime($dates['debut']) AND $objDate->format('U') <= strtotime($dates['fin'])) {
    			return $key;
    		}
    	}
    	return FALSE;
    }
     
    function definir_formule($objDate_begin, $objDate_end) {
    	$premier_jour = $objDate_begin->format('N');
    	$nombre_jours = $objDate_end->diff($objDate_begin);
     
    	if ($premier_jour == 1 AND $nombre_jours->d >= 5) {
    		$formule = 'semaine';
    	}
    	elseif ($premier_jour == 6 AND $nombre_jours->d >= 2) {
    		$formule = 'weekend';
    	}
    	else {
    		$formule = 'nuit';
    	}
    	return $formule;
    }
     
    }
     
    $location = new Location();
    $location->browse('2010-04-19', '2010-04-28');
     
    ?>
    PHP5.3 est necessaire pour l'objet Datetime que j'utilise mais on peut faire la meme chose sans, c'est juste plus pénible.

    Je voulais surtout te montrer comment découper un code en fonctions et aussi eviter de faire trop de conversion de dates.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 83
    Points : 100
    Points
    100
    Par défaut DateTime et 5.2.x
    Je crois bien l'avoir utiliser sur une prod en derniere version 5.2.x ...

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    pas date_diff.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2007
    Messages : 696
    Points : 222
    Points
    222
    Par défaut
    merci, j'ai avancé dans mon big programme, dès que je l'aurais fini je le montrerais et ... vous allez avoir envie de vomir xD
    là j'ai vraiment pas eu le choix, et j'ai un mal de tête carabiné ^^

Discussions similaires

  1. [XL-2007] Besoin d'aide pour réaliser des calcul dans mon usf
    Par capi81 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 25/08/2014, 19h42
  2. Réponses: 3
    Dernier message: 14/04/2010, 23h25
  3. Besoin d'aide pour un gros projet
    Par aouchachacha dans le forum Général Conception Web
    Réponses: 2
    Dernier message: 05/06/2008, 16h08
  4. Gros besoin d'aide pour une requete
    Par Coulomb dans le forum Langage SQL
    Réponses: 2
    Dernier message: 19/10/2007, 13h53
  5. Besoin d'aide pour un calcul sur un site
    Par barre dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 23/02/2007, 08h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo