diff --git a/VERSIONS_HOTLINE/36466 b/VERSIONS_HOTLINE/36466 new file mode 100644 index 0000000000000000000000000000000000000000..d60cc8a9d9a099a69c67076defa9ffcea15e1239 --- /dev/null +++ b/VERSIONS_HOTLINE/36466 @@ -0,0 +1 @@ + - tickets #36466 et #34901 : Correction de la localisation d'un exemplaire sur le plan insitu diff --git a/application/modules/opac/controllers/NoticeajaxController.php b/application/modules/opac/controllers/NoticeajaxController.php index 0b2b0fa198af2efe0bad1937784203b00c50cec6..6332780a18bc4937209491e94e63b07e45379d07 100644 --- a/application/modules/opac/controllers/NoticeajaxController.php +++ b/application/modules/opac/controllers/NoticeajaxController.php @@ -149,18 +149,8 @@ class NoticeAjaxController extends Zend_Controller_Action { public function localisationAction() { - $id_bib=$this->_request->getParam("id_bib"); - $cote=$this->_request->getParam("cote"); - $code_barres=$this->_request->getParam("code_barres"); - - // Recup des donnees - $data = []; - if ($bib = Class_Bib::find($id_bib)) - $data = Class_Localisation::getLocFromExemplaire($bib,$cote,$code_barres); - - // Retour - $ret = json_encode($data); - $this->_sendResponse($ret); + $item = Class_Exemplaire::find($this->_request->getParam('id_item', 0)); + $this->_helper->json(Class_Localisation::getItemLocalisation($item)); } diff --git a/library/Class/Localisation.php b/library/Class/Localisation.php index 2abc1efd2fa163f9d2d20834c192b51b62a4ef4a..3bfc0130b59ebfa1ed5ea8f4abae14748d775c2e 100644 --- a/library/Class/Localisation.php +++ b/library/Class/Localisation.php @@ -22,39 +22,59 @@ class LocalisationLoader extends Storm_Model_Loader { use Trait_Translator; - public function findAvailableLocalisation($localisations, $exemplaire) { + public function findAvailableLocalisation($localisations, $item) { $available_localisations = []; + foreach($localisations as $loc) { - if($localisation_with_quality = $loc->isForExemplaire($exemplaire)) { - $available_localisations[array_keys($localisation_with_quality)[0]] = array_shift($localisation_with_quality); - } + if(!$localisation_with_quality = $loc->isForExemplaire($item)) + continue; + + $available_localisations = $this->getSuperiorQuality($available_localisations, $localisation_with_quality); } if(!array_filter($available_localisations)) - return ''; + return null; krsort($available_localisations); return array_shift($available_localisations); } - public function getLocFromExemplaire($bib, $cote, $code_barres) { - if(!$localisations = $bib->getLocalisations()) - return $this->localisationErrorAsArray(); + protected function getSuperiorQuality($localisations, $localisation) { + $position = array_keys($localisation)[0]; + $localisation = array_values($localisation)[0]; + + if(!isset($localisations[$position])) { + $localisations[$position] = $localisation; + return $localisations; + } + + $same_quality = $localisations[$position]; + + $superior_quality = $same_quality->getCotesLength() > $localisation->getCotesLength() + ? $same_quality + : $localisation; + + $localisations[$position] = $superior_quality; + + return $localisations; + } + + + public function getItemLocalisation($item) { + $error = $this->localisationErrorAsArray(); - $exemplaire = (!$code_barres) - ? Class_Exemplaire::findFirstBy(['cote' => $cote, - 'id_bib' => $bib->getId()]) - : Class_Exemplaire::findFirstBy(['code_barres' => $code_barres, - 'id_bib' => $bib->getId()]); + if(!$item) + return $error; - if(!$exemplaire) - return $this->localisationErrorAsArray(); + if(!$library = $item->getBib()) + return $error; - $localisation = Class_Localisation::getLoader()->findAvailableLocalisation($localisations, $exemplaire); + if(!$localisations = $library->getLocalisations()) + return $error; - if(!$localisation) - return $this->localisationErrorAsArray(); + if(!$localisation = Class_Localisation::getLoader()->findAvailableLocalisation($localisations, $item)) + return $error; return $localisation->asArrayForJson(); } @@ -193,10 +213,7 @@ class Class_Localisation extends Storm_Model_Abstract { public function isForExemplaire($exemplaire) { - if(! $location_with_quality = $this->findLocationWithParamsFor($exemplaire)) - return $this->findLocalisationByCote($exemplaire); - - return $location_with_quality; + return $this->findLocationWithParamsFor($exemplaire); } @@ -214,23 +231,40 @@ class Class_Localisation extends Storm_Model_Abstract { 'emplacement' => $this->getEmplacement()]); $quality = count(array_intersect_assoc($matching_datas, $exemplaire_datas)); - $quality += $this->coteMatchingQuality($exemplaire); + + if( 0 > ($cote_quality = $this->coteMatchingQuality($exemplaire))) + return null; + + $quality += $cote_quality; return [$quality => $this]; } - protected function coteMatchingQuality($exemplaire) { - $start_cote_exemplaire = substr($exemplaire->getCote() ,0, strlen($this->getCoteDebut())); - $end_cote_exemplaire = substr($exemplaire->getCote() ,0, strlen($this->getCoteFin())); - + protected function coteMatchingQuality($item) { if(!$this->hasCoteDebut() && !$this->hasCoteFin()) - return 0; + return 0; + + if($this->hasCoteFin() && ($item->getCote() > $this->getCoteFin())) + return -1; + + if($this->hasCoteDebut() && ($item->getCote() < $this->getCoteDebut())) + return -1; + + $cote_quality = 0; + + if($this->hasCoteDebut() && ($item->getCote() >= $this->getCoteDebut())) + $cote_quality++; + + if($this->hasCoteFin() && ($item->getCote() <= $this->getCoteFin())) + $cote_quality++; + + return $cote_quality; + } - if ((!$this->hasCoteDebut() || ($this->hasCoteDebut() and $start_cote_exemplaire >= $this->getCoteDebut())) && - (!$this->hasCoteFin() || ($this->hasCoteFin() and $end_cote_exemplaire <= $this->getCoteFin()))) - return strlen($start_cote_exemplaire); - return 0; + public function getCotesLength() { + return strlen($this->getCoteDebut()) + + strlen($this->getCoteFin()); } } ?> \ No newline at end of file diff --git a/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php b/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php index 613e3145af59e799f87f8f9ee1bfe0278d3c1959..ce9d2f1e59b24ebcc261cb22841cc6bb9b74b018 100644 --- a/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php +++ b/library/ZendAfi/View/Helper/Notice/ExemplairesTable.php @@ -82,7 +82,7 @@ class ZendAfi_View_Helper_Notice_ExemplairesTable extends ZendAfi_View_Helper_Ba public function getBib($exemplaire){ - return ($bib = Class_Bib::find($exemplaire->getIdBib())) + return ($bib = $exemplaire->getBib()) ? $bib : new Class_Bib(); } @@ -222,8 +222,18 @@ class ZendAfi_View_Helper_Notice_Exemplaires_Localisation extends ZendAfi_View_H public function renderContent($exemplaire) { $html='<td class="localisation" style="text-align:center">'; + $id = $exemplaire->getIdBib(); + + if ($annexe=Class_CodifAnnexe::findFirstBy(['code' => $exemplaire->getAnnexe()])) + $id = $annexe->getIdBib(); + + $url = CLass_Url::absolute(['module' => 'opac', + 'controller' => 'noticeajax', + 'action' => 'localisation', + 'id_item' => $exemplaire->getId()], null, true); + + $onclick = 'localisationExemplaire(this, \'' . $url . '\')'; - $onclick="localisationExemplaire(this," . $exemplaire->getIdBib().",'".$exemplaire->getCote()."','".$exemplaire->getCodeBarres() . "')"; if ($this->getBib($exemplaire)->numberOfLocalisations()>0) $html.= sprintf('<img src="%s" border="0" title="%s" style="cursor:pointer" onclick="%s" alt="%s" />', URL_ADMIN_IMG.'picto/localisation.png', diff --git a/public/opac/js/recherche.js b/public/opac/js/recherche.js index 3ac0d4bc74f928834c5c7fb2b2cb092fa877d08c..1228173fda45de3eb6db07bc904e3050b551adfd 100644 --- a/public/opac/js/recherche.js +++ b/public/opac/js/recherche.js @@ -132,12 +132,12 @@ function fermer_infos_notice(sId) ///////////////////////////////////////////////////////////////////////////////// var saveImg=""; -function localisationExemplaire(localization_img, id_bib, sCote, sCodeBarres) { +function localisationExemplaire(localization_img, url) { localization_img_backup = $(localization_img).attr('src'); $(localization_img).attr('src',imagesUrl+'patience.gif'); var restore_localization_img = function(){ $(localization_img).attr('src', localization_img_backup); }; - $.getJSON(baseUrl+'/opac/noticeajax/localisation/id_bib/' + id_bib + '?cote='+ sCote + '&code_barres=' + sCodeBarres, + $.getJSON(url, function(data) { if(data.erreur > '') { restore_localization_img(); diff --git a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php index 8525a2f9589c633ecc7b02cd14614ff6f0f2b173..8ae8ae63f7420edfc7f29f8573855fa50d158888 100644 --- a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php +++ b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php @@ -1874,13 +1874,12 @@ class NoticeAjaxControllerBiographieNonTrouveeTest extends NoticeAjaxControllerB abstract class NoticeAjaxControllerLocalisationTestCase extends AbstractControllerTestCase { - protected $_json, $_storm_default_to_volatile = true; - + protected $_json, + $_storm_default_to_volatile = true; public function setUp() { parent::setUp(); - Class_Exemplaire::beVolatile(); $file_system = Storm_Test_ObjectWrapper::mock() ->whenCalled('unlink') ->answers(true) @@ -1892,10 +1891,9 @@ abstract class NoticeAjaxControllerLocalisationTestCase extends AbstractControll ->answers(true) ->whenCalled('getcwd') ->answers('path'); - Class_Localisation::beVolatile(); - Class_Plan::beVolatile(); Class_Localisation::setFileSystem($file_system); Class_Plan::setFileSystem($file_system); + $this->fixture('Class_Notice', ['id' => 1, 'titre' => 'An Error occurd', @@ -1915,8 +1913,6 @@ abstract class NoticeAjaxControllerLocalisationTestCase extends AbstractControll $this->fixture('Class_Plan', ['id' => 1, 'image' => 'plan_bib_level_1.png']); - - } } @@ -1986,7 +1982,7 @@ class NoticeAjaxControllerWithLocalisationTest extends NoticeAjaxControllerLocal 'emplacement' => '']); - $this->dispatch('noticeajax/localisation/id_bib/1/cote/123', true); + $this->dispatch('noticeajax/localisation/id_item/1', true); $this->_json = json_decode($this->_response->getBody()); } @@ -2015,7 +2011,7 @@ class NoticeAjaxControllerWithMultipleSelectorLocalisationTest extends NoticeAja ['id' => 5, 'id_bib' => 1, 'code_barres' => '', - 'cote' => 123789, + 'cote' => '995 d', 'genre' => 'Doc', 'emplacement' => '7', 'id_notice' => 1, @@ -2029,9 +2025,13 @@ class NoticeAjaxControllerWithMultipleSelectorLocalisationTest extends NoticeAja 'genre' => 'Doc', 'emplacement' => '7']); + $this->fixture('Class_Localisation', + ['id' => 15, + 'id_bib' => '1', + 'libelle' => 'Last floor', + 'cote_fin' => '995 z']); - - $this->dispatch('noticeajax/localisation/id_bib/1/cote/123789', true); + $this->dispatch('noticeajax/localisation/id_item/5', true); $this->_json = json_decode($this->_response->getBody()); } @@ -2066,7 +2066,7 @@ class NoticeAjaxControllerLocalisationWithCoteTest extends NoticeAjaxController ->setCoteFin('999 Z') ->save(); - $this->dispatch('noticeajax/localisation/id_bib/1/code_barres/123456', true); + $this->dispatch('noticeajax/localisation/id_item/5', true); $this->_json = json_decode($this->_response->getBody()); } @@ -2101,7 +2101,7 @@ class NoticeAjaxControllerLocalisationWithStartedCoteTest extends NoticeAjaxCon ->setCoteFin('999 Z') ->save(); - $this->dispatch('noticeajax/localisation/id_bib/1/code_barres/123456', true); + $this->dispatch('noticeajax/localisation/id_item/5', true); $this->_json = json_decode($this->_response->getBody()); } @@ -2127,13 +2127,20 @@ class NoticeAjaxControllerLocalisationWithEndCoteTest extends NoticeAjaxControl 'id_notice' => 1, 'section' => '']); - Class_Localisation::find(1) - ->setLibelle('Last floor') - ->setGenre('') - ->setCoteFin('999 Z') - ->save(); + $this->fixture('Class_Localisation', + ['id' => 15, + 'id_bib' => '1', + 'libelle' => 'Last floor', + 'genre' => 'Doc', + 'cote_fin' => '995 z']); + + $this->fixture('Class_Localisation', + ['id' => 16, + 'id_bib' => '1', + 'libelle' => 'Third floor', + 'cote_fin' => '999 z']); - $this->dispatch('noticeajax/localisation/id_bib/1/code_barres/123456', true); + $this->dispatch('noticeajax/localisation/id_item/5', true); $this->_json = json_decode($this->_response->getBody()); } diff --git a/tests/library/Class/LocalisationTest.php b/tests/library/Class/LocalisationTest.php index 81f5b386872e82041c0ad73d4f1b432dfe21200a..73c9007c820b08969a95edf6d9e08f5af135bcff 100644 --- a/tests/library/Class/LocalisationTest.php +++ b/tests/library/Class/LocalisationTest.php @@ -35,7 +35,6 @@ class LocalisationTest extends Storm_Test_ModelTestCase { 'section' => 'A', 'type_doc' => 1]); - $this->fixture('Class_Localisation', ['id' => 2, 'id_bib' => 1, @@ -47,7 +46,6 @@ class LocalisationTest extends Storm_Test_ModelTestCase { 'cote_debut' => 'BD A', 'cote_fin' => 'BD Z']); - $this->fixture('Class_Localisation', ['id' => 3, 'id_bib' => 1, @@ -59,7 +57,6 @@ class LocalisationTest extends Storm_Test_ModelTestCase { 'cote_debut' => 'BD A', 'cote_fin' => 'BD Z']); - $this->fixture('Class_Localisation', ['id' => 4, 'id_bib' => 1, @@ -68,6 +65,14 @@ class LocalisationTest extends Storm_Test_ModelTestCase { 'cote_debut' => 'CDA', 'cote_fin' => 'CDZ']); + $this->fixture('Class_Localisation', + ['id' => 15, + 'id_bib' => 1, + 'annexe' => 1, + 'libelle' => 'Compact discs floor', + 'cote_debut' => 'CD', + 'cote_fin' => 'CDZ']); + $this->fixture('Class_Localisation', ['id' => 5, 'id_bib' => 1, @@ -80,7 +85,7 @@ class LocalisationTest extends Storm_Test_ModelTestCase { /** @test */ public function bdByCoteAndGenreLocalisationShouldBeBD() { - $this->fixture('Class_Exemplaire', + $item = $this->fixture('Class_Exemplaire', ['id' => 4, 'id_bib' => 1, 'code_barres' => 'abc', @@ -91,36 +96,32 @@ class LocalisationTest extends Storm_Test_ModelTestCase { 'type_doc' => 1])]); $this->assertEquals('BD', - Class_Localisation::getLocFromExemplaire($this->_bib, - 'BD E', - 'abc')['libelle']); + Class_Localisation::getItemLocalisation($item)['libelle']); } /** @test */ public function coteMatchingShoulHavePriority() { - $this->fixture('Class_Exemplaire', - ['id' => 4, - 'id_bib' => 1, - 'code_barres' => 'abc', - 'cote' => 'CDE', - 'genre' => 'B', - 'section' => 'J', - 'annexe' => 1, - 'notice' => $this->fixture('Class_Notice', - ['id' => 2, - 'type_doc' => 1])]); + $item = $this->fixture('Class_Exemplaire', + ['id' => 4, + 'id_bib' => 1, + 'code_barres' => 'abc', + 'cote' => 'CDE', + 'genre' => 'B', + 'section' => 'J', + 'annexe' => 1, + 'notice' => $this->fixture('Class_Notice', + ['id' => 2, + 'type_doc' => 1])]); $this->assertEquals('Compact discs', - Class_Localisation::getLocFromExemplaire($this->_bib, - 'CDE', - 'abc')['libelle']); + Class_Localisation::getItemLocalisation($item)['libelle']); } /** @test */ public function coteWithMostCharactersMatchingShoulHavePriority() { - $this->fixture('Class_Exemplaire', + $item = $this->fixture('Class_Exemplaire', ['id' => 4, 'id_bib' => 1, 'code_barres' => 'abc', @@ -133,34 +134,30 @@ class LocalisationTest extends Storm_Test_ModelTestCase { 'type_doc' => 1])]); $this->assertEquals('CD Jazz', - Class_Localisation::getLocFromExemplaire($this->_bib, - 'CDJazz E', - 'abc')['libelle']); + Class_Localisation::getItemLocalisation($item)['libelle']); } /** @test */ public function bdByGenreLocalisationShouldBeMangas() { - $this->fixture('Class_Exemplaire', - ['id' => 4, - 'id_bib' => 1, - 'code_barres' => 'abc', - 'cote' => 'BD E', - 'genre' => 'M', - 'notice' => $this->fixture('Class_Notice', - ['id' => 2, - 'type_doc' => 1])]); + $item = $this->fixture('Class_Exemplaire', + ['id' => 4, + 'id_bib' => 1, + 'code_barres' => 'abc', + 'cote' => 'BD E', + 'genre' => 'M', + 'notice' => $this->fixture('Class_Notice', + ['id' => 2, + 'type_doc' => 1])]); $this->assertEquals('Mangas', - Class_Localisation::getLocFromExemplaire($this->_bib, - 'B', - 'abc')['libelle']); + Class_Localisation::getItemLocalisation($item)['libelle']); } /** @test */ public function romanBySectionLocalisationShouldBeRoman() { - $this->fixture('Class_Exemplaire', + $item = $this->fixture('Class_Exemplaire', ['id' => 4, 'id_bib' => 1, 'code_barres' => 'abc', @@ -171,9 +168,7 @@ class LocalisationTest extends Storm_Test_ModelTestCase { 'type_doc' => 1])]); $this->assertEquals('romans', - Class_Localisation::getLocFromExemplaire($this->_bib, - 'ROM', - 'abc')['libelle']); + Class_Localisation::getItemLocalisation($item)['libelle']); } }