From 8cb6a5afad6e5f29fae29f27a41952c437398c4a Mon Sep 17 00:00:00 2001
From: pbarroca <pbarroca@git-test.afi-sa.fr>
Date: Wed, 1 Aug 2012 16:32:52 +0000
Subject: [PATCH] =?UTF-8?q?Multimedia:=20prise=20en=20compte=20des=20quota?=
 =?UTF-8?q?s=20de=20r=C3=A9sa=20dans=20l'=C3=A9cran=20de=20choix=20du=20jo?=
 =?UTF-8?q?ur?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../opac/controllers/AbonneController.php     | 24 +++++-
 .../scripts/abonne/multimedia-hold-day.phtml  |  3 +
 library/Class/Multimedia/DeviceHold.php       | 27 +++++++
 library/Class/Users.php                       | 75 ++++++++++++++++++-
 library/ZendAfi/View/Helper/Timeline.php      |  1 -
 .../AbonneControllerMultimediaTest.php        | 37 +++++++++
 6 files changed, 163 insertions(+), 4 deletions(-)

diff --git a/application/modules/opac/controllers/AbonneController.php b/application/modules/opac/controllers/AbonneController.php
index 7b86f602401..1d049b67f9d 100644
--- a/application/modules/opac/controllers/AbonneController.php
+++ b/application/modules/opac/controllers/AbonneController.php
@@ -546,8 +546,28 @@ class AbonneController extends Zend_Controller_Action {
 			return;
 		}
 
-		if (null != $this->_getParam('day')) {
-			$bean->day = $this->_getParam('day');
+		$day = $this->_getParam('day');
+		$quotaErrorType = null;
+		if (null != $day) {
+			$quotaErrorType = $this->_user->getMultimediaQuotaErrorForDay($day);
+			switch ($quotaErrorType) {
+			  case Class_Multimedia_DeviceHold::QUOTA_NONE:
+					$this->view->quotaError = $this->view->_('Vous n\'avez pas les nécessaires pour effectuer une réservation');
+					break;
+			  case Class_Multimedia_DeviceHold::QUOTA_DAY:
+					$this->view->quotaError = $this->view->_('Quota déjà atteint ce jour, choisissez un autre jour.');
+					break;
+			  case Class_Multimedia_DeviceHold::QUOTA_WEEK:
+					$this->view->quotaError = $this->view->_('Quota déjà atteint cette semaine, choisissez une autre semaine.');
+					break;
+			  case Class_Multimedia_DeviceHold::QUOTA_MONTH:
+					$this->view->quotaError = $this->view->_('Quota déjà atteint ce mois, choisissez un autre mois.');
+					break;
+			}
+		}
+				
+		if (null != $day && null == $quotaErrorType) {
+			$bean->day = $day;
 			$this->_redirect('/abonne/multimedia-hold-hours');
 			return;
 		}
diff --git a/application/modules/opac/views/scripts/abonne/multimedia-hold-day.phtml b/application/modules/opac/views/scripts/abonne/multimedia-hold-day.phtml
index 66d7a14d1c5..b47336e6ba1 100644
--- a/application/modules/opac/views/scripts/abonne/multimedia-hold-day.phtml
+++ b/application/modules/opac/views/scripts/abonne/multimedia-hold-day.phtml
@@ -2,6 +2,9 @@
 <?php echo $this->timeline($this->timelineActions);?>
 
 <h2><?php echo $this->_('Pour quel jour ?');?></h2>
+<?php if ($this->quotaError) { ?>
+<div class="error"><?php echo $this->quotaError;?></div>
+<?php } ?>
 <?php
 Class_ScriptLoader::getInstance()
   ->addAdminScript('jquery_ui/jquery-ui-i18n.min')
diff --git a/library/Class/Multimedia/DeviceHold.php b/library/Class/Multimedia/DeviceHold.php
index 98ba1424c87..c680883bbb6 100644
--- a/library/Class/Multimedia/DeviceHold.php
+++ b/library/Class/Multimedia/DeviceHold.php
@@ -69,6 +69,28 @@ class Multimedia_DeviceHoldloader extends Storm_Model_Loader {
 	}
 
 
+	/**
+	 * @param $user Class_Users
+	 * @param $start int timestamp
+	 * @param $end int timestamp
+	 * @return int minutes
+	 */
+	public function getDurationForUserBetweenTimes($user, $start, $end) {
+		$duration = 0;
+		$holds = $this->findAll($this->getTable()->select()
+			                       ->where('id_user = ' . $user->getId())
+			                       ->where('start >= ' . $start)
+			                       ->where('end <= ' . $end)
+			                       ->order('start asc'));
+		
+		foreach($holds as $hold)
+			$duration += ($hold->getEnd() - $hold->getStart()) / 60;
+
+		return $duration;
+	}
+
+
+		
 	/**
 	 * @param $device Class_Multimedia_Device
 	 * @param $time int
@@ -145,6 +167,11 @@ class Multimedia_DeviceHoldloader extends Storm_Model_Loader {
 
 
 class Class_Multimedia_DeviceHold extends Storm_Model_Abstract {
+	const QUOTA_DAY = 'day';
+	const QUOTA_MONTH = 'month';
+	const QUOTA_WEEK = 'week';
+	const QUOTA_NONE = 'none';
+
 	protected $_loader_class = 'Multimedia_DeviceHoldLoader';
 	protected $_table_name = 'multimedia_devicehold';
 	protected $_belongs_to = array(
diff --git a/library/Class/Users.php b/library/Class/Users.php
index 4cdaef720cc..cd474882900 100644
--- a/library/Class/Users.php
+++ b/library/Class/Users.php
@@ -797,7 +797,8 @@ class Class_Users extends Storm_Model_Abstract {
 	}
 
 
-	/* Hook AbstractModel::save
+	/**
+	 * Hook AbstractModel::save
 	 * Sauvegarde des données compte lecteur sur le SIGB
 	 */
 	public function afterSave() {
@@ -815,4 +816,76 @@ class Class_Users extends Storm_Model_Abstract {
 			->setPassword($this->getPassword())
 			->save();
 	}
+
+
+	/**
+	 * @param $day string YYYY-MM-DD formatted
+	 * @return string const error type @see Class_Multimedia_DeviceHold
+	 */
+	public function getMultimediaQuotaErrorForDay($day) {
+		// chargements des quotas les plus avantageux pour l'utilisateur selon ses groupes
+		$max_day = $max_week = $max_month = 0;
+		$quotaNames = array('day', 'week', 'month');
+		foreach ($this->getUserGroups() as $group) {
+			foreach ($quotaNames as $name) {
+				$quotaName = 'max_' . $name;
+				$methodName = 'getMax' . ucfirst($name);
+				$value = (int)$group->$methodName();
+				if (${$quotaName} < $value)
+					${$quotaName} = $value;
+			}
+		}
+
+		// si un seul des quotas est resté à 0, on n'a aucun droit
+		if (in_array(0, array($max_day, $max_week, $max_month)))
+			return Class_Multimedia_DeviceHold::QUOTA_NONE;
+
+		if ($max_day <= $this->getMultimediaHoldDurationForDay($day))
+			return Class_Multimedia_DeviceHold::QUOTA_DAY;
+
+		if ($max_week <= $this->getMultimediaHoldDurationForWeekOfDay($day))
+			return Class_Multimedia_DeviceHold::QUOTA_WEEK;
+
+		if ($max_month <= $this->getMultimediaHoldDurationForMonthOfDay($day))
+			return Class_Multimedia_DeviceHold::QUOTA_MONTH;
+	}
+
+
+	/**
+	 * @param $day string
+	 * @return int minutes
+	 */
+	public function getMultimediaHoldDurationForDay($day) {
+		$start = strtotime($day);
+		$end = strtotime('+1 day', $start);
+
+		return (int) Class_Multimedia_DeviceHold::getLoader()
+				->getDurationForUserBetweenTimes($this, $start, $end);
+	}
+
+
+	/**
+	 * @param $day string
+	 * @return int minutes
+	 */
+	public function getMultimediaHoldDurationForWeekOfDay($day) {
+		$start = strtotime('previous monday', strtotime($day));
+		$end = strtotime('next monday', $start);
+
+		return (int) Class_Multimedia_DeviceHold::getLoader()
+				->getDurationForUserBetweenTimes($this, $start, $end);
+	}
+
+
+	/**
+	 * @param $day string
+	 * @return int minutes
+	 */
+	public function getMultimediaHoldDurationForMonthOfDay($day) {
+		$start = strtotime('first day of this month', strtotime($day));
+		$end = strtotime('first day of next month', $start);
+
+		return (int) Class_Multimedia_DeviceHold::getLoader()
+				->getDurationForUserBetweenTimes($this, $start, $end);
+	}
 }
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Timeline.php b/library/ZendAfi/View/Helper/Timeline.php
index 8b042ea1e21..5957140c8c3 100644
--- a/library/ZendAfi/View/Helper/Timeline.php
+++ b/library/ZendAfi/View/Helper/Timeline.php
@@ -31,7 +31,6 @@ class ZendAfi_View_Helper_Timeline extends Zend_View_Helper_Abstract {
 	 * @return string
 	 */
 	public function timeline($actions) {
-		xdebug_break();
 		$this->_after_current = false;
 				
 		$html = '<div class="timeline"><ul>';
diff --git a/tests/application/modules/opac/controllers/AbonneControllerMultimediaTest.php b/tests/application/modules/opac/controllers/AbonneControllerMultimediaTest.php
index cf4ed960b7b..3dcb308e5ef 100644
--- a/tests/application/modules/opac/controllers/AbonneControllerMultimediaTest.php
+++ b/tests/application/modules/opac/controllers/AbonneControllerMultimediaTest.php
@@ -285,6 +285,17 @@ abstract class AbonneControllerMultimediaHoldTestCase extends AbstractController
 		$bean->duration = 0;
 		$bean->device = 0;
 		$this->_session->holdBean = $this->_bean = $bean;
+
+		Class_Users::getLoader()->getIdentity()->setUserGroups(array(
+				Class_UserGroup::getLoader()
+				->newInstanceWithId(12)
+				->setMaxDay(120)
+				->setMaxWeek(240)
+				->setMaxMonth(360)));
+				
+		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Multimedia_DeviceHold')
+			->whenCalled('getDurationForUserBetweenTimes')
+			->answers(0);
 	}
 
 
@@ -432,6 +443,32 @@ class AbonneControllerMultimediaHoldDayChoiceTest extends AbonneControllerMultim
 }
 
 
+class AbonneControllerMultimediaHoldDayChoiceWithOverQuotaTest extends AbonneControllerMultimediaHoldTestCase {
+	public function setUp() {
+		parent::setUp();
+		$this->_prepareLocationInSession();
+
+		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Multimedia_DeviceHold')
+			->whenCalled('getDurationForUserBetweenTimes')
+			->answers(8000);
+				
+		$this->dispatch('/abonne/multimedia-hold-day/day/2012-09-09', true);
+	}
+
+
+	/** @test */
+	public function shouldNotRedirect() {
+		$this->assertNotRedirect();
+	}
+
+
+	/** @test */
+	public function quotaErrorShouldBePresent() {
+		$this->assertXPathContentContains('//div', 'Quota déjà atteint ce jour');
+	}
+}
+
+
 class AbonneControllerMultimediaHoldHoursTest extends AbonneControllerMultimediaHoldTestCase {
 	public function setUp() {
 		parent::setUp();
-- 
GitLab