Jump to content

Date de livraison estimée réelle


Recommended Posts

Bonjour.

 

Pour ceux que cela intéresse, j'ai amélioré le module "Date de livraison" après avoir été agacé qu'il m'affiche : "Date approximative de livraison avec ce transporteur : entre le Mercredi 25 Décembre 2013 et le Vendredi 27 Décembre 2013 *".

Il ne tient en effet pas compte des jours fériés.

De même, il ne tient pas compte de l'heure de la commande. Si un client passe sa commande avant midi, elle pourra partir le jour même mais s'il l'a passe à 17h, elle ne partira que le lendemain.

 

On a 2 possibilités. Soit on change directement le fichier php du module qui se trouve ici :

/modules/dateofdelivery/dateofdelivery.php

soit on surcharge ce fichier en utilisant la méthode suivante :

http://www.webaki.com/blog/override-module-8.html

Pour info, j'avais testé : https://gist.github.com/JulienBreux/2287709

mais neça fonctionnait pas pour moi.

C'est ce que j'ai fait.

J'ai donc mis le fichier ici :

/themes/NomDeMonTheme/modules/dateofdelivery/dateofdelivery.php

 

Et voici ce qu'il contient :

class DateOfDelivery extends DateOfDeliveryModule
{
	public function hookBeforeCarrier($params)
	{
		if (!isset($params['delivery_option_list']) || !count($params['delivery_option_list']))
			return false;
		
		$package_list = $params['cart']->getPackageList();

		$datesDelivery = array();
		foreach ($params['delivery_option_list'] as $id_address => $by_address)
		{
			$datesDelivery[$id_address] = array();
			foreach ($by_address as $key => $delivery_option)
			{
				$date_from = null;
				$date_to = null;
				$datesDelivery[$id_address][$key] = array();
				
				foreach ($delivery_option['carrier_list'] as $id_carrier => $carrier)
				{
					foreach ($carrier['package_list'] as $id_package)
					{
						$package = $package_list[$id_address][$id_package];
						$oos = false; // For out of stock management
						foreach ($package['product_list'] as $product)
							//print_r($product);
							//echo "<br> ".$product['reference']." stock=".$product['stock_quantity']." panier=".$product['cart_quantity'];
							if (StockAvailable::getQuantityAvailableByProduct($product['id_product'], ($product['id_product_attribute'] ? (int)$product['id_product_attribute'] : null), (int)$this->context->shop->id) <= 0)
							{
								$oos = true;
								break;
							}
							if (($product['stock_quantity'] - $product['cart_quantity']) < 0)
								$oos = true;
						$available_date = Product::getAvailableDate($product['id_product'], ($product['id_product_attribute'] ? (int)$product['id_product_attribute'] : null), (int)$this->context->shop->id);
						$date_range = $this->_getDatesOfDelivery($id_carrier, $oos, $available_date);
						if (is_null($date_from) || $date_from < $date_range[0])
						{
							$date_from = $date_range[0][1];
							$datesDelivery[$id_address][$key][0] = $date_range[0];
						}
						if (is_null($date_to) || $date_to < $date_range[1])
						{
							$date_to = $date_range[1][1];
							$datesDelivery[$id_address][$key][1] = $date_range[1];
						}
					}
				}
			}
		}
		$this->smarty->assign(array(
			'nbPackages' => $params['cart']->getNbOfPackages(),
			'datesDelivery' => $datesDelivery,
			'delivery_option' => $params['delivery_option']
		));
		
		return $this->display(__FILE__, 'beforeCarrier.tpl');
	}


	/**
	 * @param int    $id_carrier
	 * @param bool   $product_oos
	 * @param string $date
	 *
	 * @return array|bool returns the min & max delivery date
	 */
	public function _getDatesOfDelivery($id_carrier, $product_oos = false)
	{
		//délai d'expedition + délai de transport
		 $delai_livraison = 0;
		 $heure_max_envoi_colis = 12.00;				// au-delà de cette heure, les colis sont expédiés le jour suivant
		 $fermeture = 0;
		 $date_fermeture_debut = "2013-12-30 12:00";	// date de début de fermeture
		 $date_fermeture_fin = "2014-01-02 23:59";		// date de fin de fermeture
		 $duree_fermeture = floor((strtotime($date_fermeture_fin) - strtotime($date_fermeture_debut))/86400);	// en nombre de jours
		 $nb_de_jour_pour_envoyer_colis_a_date_reouverture = 1;	// si on a 1000 colis à faire, c'est sûr qu'on ne pourra pas tout faire le jour même, donc prévoir le nb de jours qu'il faudra
		 
		//récupération de l'année en cours
		 $annee = date("Y");
		 
		//ajout d'un jour pour les années bisextiles
		if (cal_days_in_month(CAL_GREGORIAN,2,$annee)===29)
			 $bisextile = 1;
		else
			$bisextile = 0;
		 
		//calcul du lundi férié de paques
		$lundi_de_paque = date("z", strtotime(date("Y-m-d", strtotime(date("Y-m-d", easter_date($annee))."+1 days"))));
		 
		//création du tableau des jours férié de l'année
		$tab_jours_feries = array(0, $lundi_de_paque, 120+$bisextile, 127+$bisextile, $lundi_de_paque+38, $lundi_de_paque+49, 194+$bisextile, 226+$bisextile, 304+$bisextile, 314+$bisextile, 357+$bisextile);
		//				1er janvier   pâque	          1er mai		  8 mai		      jeudi ascension	  lundi de Pentecôte  14 juillet	  15 août		  1er novembre	  11 novembre	  noël			  		
		
		if (!(int)($id_carrier))
			return false;
		$carrier_rule = $this->_getCarrierRuleWithIdCarrier((int)($id_carrier));
		
		if ($product_oos)
			$delai_livraison += Configuration::get('DOD_EXTRA_TIME_PRODUCT_OOS');
		$delai_livraison += Configuration::get('DOD_EXTRA_TIME_PREPARATION');
		
		$delai_livraison_min = $delai_livraison + $carrier_rule['minimal_time'];	// $carrier_rule['minimal_time'] tient compte du délai si produit en rupture
		$delai_livraison_max = $delai_livraison + $carrier_rule['maximal_time'];	// $carrier_rule['maximal_time'] tient compte du délai si produit en rupture
		//echo "<br>delai_livraison_min=$delai_livraison_min delai_livraison_max=$delai_livraison_max";
		/* au cas où $carrier_rule ne serait pas défini */
		if ($delai_livraison_min < 2)
			$delai_livraison_min = 2;
		if ($delai_livraison_max < 4)
			$delai_livraison_max = 4;
		//echo "<br>delai_livraison_min=$delai_livraison_min delai_livraison_max=$delai_livraison_max";
		if ($delai_livraison_min == $delai_livraison_max)
			$delai_livraison_max = $delai_livraison_max + 2;
		//echo "<br>delai_livraison_min=$delai_livraison_min delai_livraison_max=$delai_livraison_max";
		// s'il est plus de midi et qu'on est un lundi à jeudi (ou si on est un dimanche), la commande ne sera expédiée que le lendemain. Il faut donc ajouter un jour
		$heure_jour = date("G.i");	// 0 à 24 . 0 à 59
		$jour_semaine = date("N");	// lundi = 1 ... dimanche = 7

		//$heure_jour = 11.00;
		//$jour_semaine = 7;
		//echo "<br>delai_livraison_min=$delai_livraison_min delai_livraison_max=$delai_livraison_max heure_jour=$heure_jour heure_max_envoi_colis=$heure_max_envoi_colis jour_semaine=$jour_semaine duree_fermeture=$duree_fermeture";

		
		if ( ($heure_jour > $heure_max_envoi_colis && $jour_semaine <= 4) || ($jour_semaine == 6) || ($jour_semaine == 7) ) {	// mais si samedi ou dimanche, la commande est expédiée le lundi qui suit, donc il faut ajouter 1 jours
			$delai_livraison_min = $delai_livraison_min + 1;
			$delai_livraison_max = $delai_livraison_max + 1;
		}
		elseif ( $jour_semaine == 6 ) {	// mais si samedi, la commande est expédiée le lundi qui suit, donc il faut ajouter 2 jours
			$delai_livraison_min = $delai_livraison_min + 2;
			$delai_livraison_max = $delai_livraison_max + 2;
		}
		elseif ( ($heure_jour > $heure_max_envoi_colis && $jour_semaine == 5) ) {	// mais si c'est un vendredi après 12h, la commande est expédiée le lundi qui suit, donc il faut ajouter 3 jours
			$delai_livraison_min = $delai_livraison_min + 2;
			$delai_livraison_max = $delai_livraison_max + 2;
		}
		/* si on est un lundi à vendredi, avant midi mais que c'est un jour férié */
		if ( ($heure_jour <= $heure_max_envoi_colis) && ($jour_semaine <= 5) && (in_array(date("z"),$tab_jours_feries)) ) {
			$delai_livraison_min = $delai_livraison_min + 1;
			$delai_livraison_max = $delai_livraison_max + 1;
		}
		//echo "<br>delai_livraison_min=$delai_livraison_min delai_livraison_max=$delai_livraison_max";
		//itération sur le délai de livraison commence à 1 et non à 0, car j'ai déjà traité ci-dessus les différents cas en fonction du jour de départ
		for($delai=1; $delai<=$delai_livraison_min; $delai++) {
			//si le numéro du jour de livraison estimée correspond à dimanche=7 ou si le numéro du jour est présent dans le tableau des jours fériés
			if ((date("N",strtotime("+".$delai." days"))==7) || (in_array(date("z",strtotime("+".$delai." days")),$tab_jours_feries))) {
				//on rajoute 1 jour dans le délai de livraison
				$delai_livraison_min = $delai_livraison_min + 1;
			}	
		}
		
		//itération sur le délai de livraison commence à 1 et non à 0, car j'ai déjà traité ci-dessus les différents cas en fonction du jour de départ
		for($delai=1; $delai<=$delai_livraison_max; $delai++) {
			//si le numéro du jour de livraison estimée correspond à dimanche=7 ou si le numéro du jour est présent dans le tableau des jours fériés
			if ((date("N",strtotime("+".$delai." days"))==7) || (in_array(date("z",strtotime("+".$delai." days")),$tab_jours_feries))) {
				//on rajoute 1 jour dans le délai de livraison
				$delai_livraison_max = $delai_livraison_max + 1;
			}	
		}

		if ( $fermeture == 1) {
			$nb_jour_pour_envoi_reouverture = $duree_fermeture + $nb_de_jour_pour_envoyer_colis_a_date_reouverture;
			$delai_livraison = 0;
			if ($product_oos)
				$delai_livraison += Configuration::get('DOD_EXTRA_TIME_PRODUCT_OOS');
			$delai_livraison += Configuration::get('DOD_EXTRA_TIME_PREPARATION');
			
			$delai_livraison_min = $delai_livraison + $carrier_rule['minimal_time'];
			$delai_livraison_max = $delai_livraison + $carrier_rule['maximal_time'];
			
			/* au cas où $carrier_rule ne serait pas défini */
			if ($delai_livraison_min <2)
				$delai_livraison_min = 2;
			if ($delai_livraison_max <4)
				$delai_livraison_max = 4;
					
			$delai_livraison_min += $nb_de_jour_pour_envoyer_colis_a_date_reouverture;
			$delai_livraison_max += $nb_de_jour_pour_envoyer_colis_a_date_reouverture;
			if ($delai_livraison_min == $delai_livraison_max)
				$delai_livraison_max++;

			if ( date("Y-m-d G:i")>=$date_fermeture_debut && date("Y-m-d G:i")<=$date_fermeture_fin ) {
				$delai_livraison_min = $delai_livraison_min + $duree_fermeture;
				$delai_livraison_max = $delai_livraison_max + $duree_fermeture;
			}
			//itération sur le délai de livraison commence à 1 et non à 0, car j'ai déjà traité ci-dessus les différents cas en fonction du jour de départ
			for($delai=$nb_jour_pour_envoi_reouverture; $delai<=$delai_livraison_min; $delai++) {
				//si le numéro du jour de livraison estimée correspond à dimanche=7 ou si le numéro du jour est présent dans le tableau des jours fériés
				if ((date("N",strtotime("+".$delai." days"))==7) || (in_array(date("z",strtotime("+".$delai." days")),$tab_jours_feries))) {
					//on rajoute 1 jour dans le délai de livraison
					$delai_livraison_min = $delai_livraison_min + 1;
				}	
			}

			//itération sur le délai de livraison commence à 1 et non à 0, car j'ai déjà traité ci-dessus les différents cas en fonction du jour de départ
			for($delai=$nb_jour_pour_envoi_reouverture; $delai<=$delai_livraison_max; $delai++) {
				//si le numéro du jour de livraison estimée correspond à dimanche=7 ou si le numéro du jour est présent dans le tableau des jours fériés
				if ((date("N",strtotime("+".$delai." days"))==7) || (in_array(date("z",strtotime("+".$delai." days")),$tab_jours_feries))) {
					//on rajoute 1 jour dans le délai de livraison
					$delai_livraison_max = $delai_livraison_max + 1;
				}	
			}
		}
		

		//echo "<br>delai_livraison_min=$delai_livraison_min delai_livraison_max=$delai_livraison_max<br><br>";
		$date_minimal_time = strtotime("+".$delai_livraison_min." days");
		$date_maximal_time = strtotime("+".$delai_livraison_max." days");


		/*
		Do not remove this commentary, it's usefull to allow translations of months and days in the translator tool
		
		$this->l('Sunday');
		$this->l('Monday');
		$this->l('Tuesday');
		$this->l('Wednesday');
		$this->l('Thursday');
		$this->l('Friday');
		$this->l('Saturday');

		$this->l('January');
		$this->l('February');
		$this->l('March');
		$this->l('April');
		$this->l('May');
		$this->l('June');
		$this->l('July');
		$this->l('August');
		$this->l('September');
		$this->l('October');
		$this->l('November');
		$this->l('December');
		*/
		
		$date_minimal_string = '';
		$date_maximal_string = '';
		$date_format = preg_split('/([a-z])/Ui', Configuration::get('DOD_DATE_FORMAT'), NULL, PREG_SPLIT_DELIM_CAPTURE);
		foreach ($date_format as $elmt)
		{
			if ($elmt == 'l' OR $elmt == 'F')
			{
				$date_minimal_string .= $this->l(date($elmt, $date_minimal_time));
				$date_maximal_string .= $this->l(date($elmt, $date_maximal_time));
			}
			elseif (preg_match('/[a-z]/Ui', $elmt))
			{
				$date_minimal_string .= date($elmt, $date_minimal_time);
				$date_maximal_string .= date($elmt, $date_maximal_time);
			}
			else
			{
				$date_minimal_string .= $elmt;
				$date_maximal_string .= $elmt;
			}
		}
		return array(
			array(
				$date_minimal_string,
				$date_minimal_time
			),
			array(
			$date_maximal_string,
				$date_maximal_time
			)
		);
	}
}

les echo commentés ( // echo ...) peuvent être supprimés : c'est pour faire des tests.

  

au début de la fonction _getDatesOfDelivery, il y a 2 variables :

$delai_livraison = 0;
$heure_max_envoi_colis = 12;

que vous pouvez modifier en fonction du fonctionnement de la logistique.

Normalement, on laisse $delai_livraison à 0 car ce paramètre en enregistré dans le BO et pris en compte par la fonction.

Le 2e $heure_max_envoi_colis correspond à l'heure maxi à laquelle les commandes sont envoyées le jour même.

J'ai rajouté, par rapport à la fonction initiale la possibilité de définir une période de fermeture.

Edited by djform (see edit history)
Link to comment
Share on other sites

Oui, j'ai mis un bout de temps pour trouver ça. Et c'est vrai que c'est indispensable, si on ne veut pas s'amuser à devoir tout remettre à jour à chaque mise à jour de modules.

J'espère que ça va être natif dans les prochaines versions de Presta.

Link to comment
Share on other sites

Non, pas sur la page produit mais sur la page du tunnel de commande "Frais de port", sur laquelle tu choisis ton transporteur (voir capture jointe).

Voici le hook :

Before carriers list - 1 Module [This hook is displayed before the carrier list in Front Office] (Nom techniquedisplayBeforeCarrier)

 

J'ai également renseigné une date de livraison sur la page du Panier mais c'est un autre script, qui est indépendant de celui de ce topic.

post-403727-0-09464700-1388825288_thumb.jpg

Edited by djform (see edit history)
Link to comment
Share on other sites

  • 1 year later...

Salut,

 

Tu crois que c'est possible de pouvoir règler en heure/minute, je veux dire là actuellement le minimum que l'on peut renseigner c'est 0 jours pour que cela affiche la date de demain, mais souhaitant permettre la livraison en boutique sous 1h etc.... j'aimerais pouvoir renseigner livraison entre 30 min. et 2h ou 1h à 2h.

Link to comment
Share on other sites

Avec ça, la date de livraison apparait sur la page produit ? Il se met sur quel hook ?

On peut voir un site sur lequel le module est en fonction ?

Ca n'apparait pas sur la fiche produit mais sur la page du choix du mode de livraison. J'ai également un autre script qui fait apparaitre l'info sur la page du panier.

Il est possible de voir tout cela en fonctionnement sur www.djform.fr

Link to comment
Share on other sites

  • 4 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...