diff --git a/VERSIONS_WIP/173687 b/VERSIONS_WIP/173687 new file mode 100644 index 0000000000000000000000000000000000000000..f31ca69fc48344a192e27af987f0d6794d4c4b4a --- /dev/null +++ b/VERSIONS_WIP/173687 @@ -0,0 +1 @@ + - fonctionnalité #173687 : SIGB Koha : Affichage de la disponibilité des exemplaires pour les notices de dépouillement d'article ou mélanges \ No newline at end of file diff --git a/library/Class/Exemplaire.php b/library/Class/Exemplaire.php index 52cf6b254eee1ecab9a9ec08a86e1ddbbf42b47d..7d2d05691ce295f81851463d7d8854a834ce71da 100644 --- a/library/Class/Exemplaire.php +++ b/library/Class/Exemplaire.php @@ -762,4 +762,26 @@ class Class_Exemplaire extends Storm_Model_Abstract { return ($bib_id == $this->getIdBib() && $this->isNouveaute()); } + + + public function isFromKoha(): bool + { + return 1 === Class_IntBib::query() + ->eq('id_bib', $this->getIdIntBib()) + ->eq('sigb', Class_IntBib::SIGB_KOHA) + ->countAll(); + } + + + public function hasConcatenedBarcode(): bool + { + return false !== strpos($this->getCodeBarres(), '-'); + } + + + public function barcodeFirstPart(): string + { + $barcode = explode('-', $this->getCodeBarres()); + return array_shift($barcode); + } } diff --git a/library/Class/Notice.php b/library/Class/Notice.php index 99248e4c7f97a68be0d531b9ecf8a4e050e532c3..26a7f778f14f97b69c97511fbba912749dd159a4 100644 --- a/library/Class/Notice.php +++ b/library/Class/Notice.php @@ -1689,6 +1689,5 @@ class Class_Notice extends Storm_Model_Abstract { if ($item->isNouveauteForLibrary($bib_id)) return true; return false; - } } diff --git a/library/Class/WebService/SIGB/Koha/Service.php b/library/Class/WebService/SIGB/Koha/Service.php index e3060f0e30b55dc113b8a2a5bf875452d399ff15..b23ff493bb37a4224c8070872c67b7c570facc20 100644 --- a/library/Class/WebService/SIGB/Koha/Service.php +++ b/library/Class/WebService/SIGB/Koha/Service.php @@ -282,6 +282,16 @@ class Class_WebService_SIGB_Koha_Service extends Class_WebService_SIGB_AbstractR } + public function getILSWsItemFromCacheOrRequest(Class_Exemplaire $item) : Class_WebService_SIGB_Exemplaire { + + if ($alternative_item = Class_Exemplaire::findFirstBy(['code_barres' => $item->barcodeFirstPart(), + 'id_int_bib' => $item->getIdIntBib()])) + $item = $alternative_item; + + return $this->getNoticeCache()->getItemFromCacheOrILSWs($item); + } + + protected function _getIlsIdThroughAuthenticateService(Class_Users $user) : string { if ( ! $password = $user->getPassword()) return ''; diff --git a/library/templates/Intonation/Library/Record/Items.php b/library/templates/Intonation/Library/Record/Items.php index 3a8dbf48c15322bfebebed02e8f2bf8261dbbc5f..11f212e8cd138e3b2effd30754da64f76d701f78 100644 --- a/library/templates/Intonation/Library/Record/Items.php +++ b/library/templates/Intonation/Library/Record/Items.php @@ -72,13 +72,15 @@ class Intonation_Library_Record_Items { - protected function _findItems() : array { + protected function _findItems(): array + { if (empty($this->_records)) return []; $session = Zend_Registry::get('session'); - $items = new Storm_Model_Collection(); + $items = new Storm_Model_Collection; + foreach($this->_records as $record) $items->addAll($record->getExemplaires()); diff --git a/tests/fixtures/MAE_GetRecords273230.xml b/tests/fixtures/MAE_GetRecords273230.xml new file mode 100644 index 0000000000000000000000000000000000000000..c2d2bbdfa90a93b70a8635c1e6446bba7e928bb0 --- /dev/null +++ b/tests/fixtures/MAE_GetRecords273230.xml @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<GetRecords> + <record> + <timestamp>2019-07-30 13:48:26</timestamp> + <biblionumber>123415</biblionumber> + <pages>9 pièces</pages> + <volume>mélanges</volume> + <issues> + </issues> + <reserves> + </reserves> + <cn_sort></cn_sort> + <publishercode>Association française de science politique</publishercode> + <size>33 cm</size> + <biblioitemnumber>123415</biblioitemnumber> + <marcxml><?xml version="1.0" encoding="UTF-8"?> +<record + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd" + xmlns="http://www.loc.gov/MARC21/slim"> + + <leader>00684nam a2200205 4500</leader> + <controlfield tag="001">123415</controlfield> + <datafield tag="090" ind1=" " ind2=" "> + <subfield code="a">123415</subfield> + </datafield> + <datafield tag="099" ind1=" " ind2=" "> + <subfield code="t">OUVRAGE</subfield> + <subfield code="c">2019-06-28</subfield> + <subfield code="d">2019-06-28</subfield> + </datafield> + <datafield tag="100" ind1=" " ind2=" "> + <subfield code="a">20190628d1961 u||y0frey50 ba</subfield> + </datafield> + <datafield tag="101" ind1=" " ind2=" "> + <subfield code="a">fre</subfield> + </datafield> + <datafield tag="102" ind1=" " ind2=" "> + <subfield code="a">FR</subfield> + </datafield> + <datafield tag="200" ind1=" " ind2=" "> + <subfield code="a">Association française de science politique</subfield> + <subfield code="e">mélanges</subfield> + </datafield> + <datafield tag="210" ind1=" " ind2=" "> + <subfield code="a">Paris</subfield> + <subfield code="c">Association française de science politique</subfield> + <subfield code="d">1961</subfield> + </datafield> + <datafield tag="215" ind1=" " ind2=" "> + <subfield code="a">9 pièces</subfield> + <subfield code="d">33 cm</subfield> + </datafield> + <datafield tag="311" ind1=" " ind2=" "> + <subfield code="a">Ouvrage dépouillé</subfield> + </datafield> + <datafield tag="503" ind1=" " ind2=" "> + <subfield code="a">Mélanges</subfield> + <subfield code="b">Association française de science politique</subfield> + <subfield code="j">1961</subfield> + </datafield> + <datafield tag="606" ind1=" " ind2=" "> + <subfield code="9">187527</subfield> + <subfield code="a">SCIENCES POLITIQUES</subfield> + </datafield> + <datafield tag="606" ind1=" " ind2=" "> + <subfield code="9">186874</subfield> + <subfield code="a">PARTIS POLITIQUES</subfield> + </datafield> + <datafield tag="710" ind1=" " ind2=" "> + <subfield code="9">111125</subfield> + <subfield code="a">ASSOCIATION FRANCAISE DE SCIENCE POLITIQUE</subfield> + </datafield> + <datafield tag="801" ind1=" " ind2=" "> + <subfield code="a">FR</subfield> + <subfield code="b">MAEDI</subfield> + <subfield code="g">AFNOR</subfield> + </datafield> + <datafield tag="995" ind1=" " ind2=" "> + <subfield code="1">0</subfield> + <subfield code="2">0</subfield> + <subfield code="3">0</subfield> + <subfield code="5">2019-06-28</subfield> + <subfield code="9">340920</subfield> + <subfield code="b">CADLC</subfield> + <subfield code="c">CADLC</subfield> + <subfield code="e">DEP104</subfield> + <subfield code="f">435194</subfield> + <subfield code="i">2019-06-28</subfield> + <subfield code="j">435194</subfield> + <subfield code="k">MB 1166</subfield> + <subfield code="o">0</subfield> + <subfield code="r">LIVRE</subfield> + <subfield code="s">MB_1166_000000000000000</subfield> + <subfield code="u">feuillets mobiles</subfield> + <subfield code="w">0</subfield> + <subfield code="y">2019-06-28</subfield> + <subfield code="G">Baumont</subfield> + <subfield code="I">3</subfield> + </datafield> +</record> +</marcxml> + <publicationyear>1961</publicationyear> + <itemtype>OUVRAGE</itemtype> + <items> + <item> + <itemcallnumber>MB 1166</itemcallnumber> + <itemnotes>feuillets mobiles</itemnotes> + <stocknumber>435194</stocknumber> + <biblioitemnumber>123415</biblioitemnumber> + <itemnumber>340920</itemnumber> + <location_description>Dépôt A-104</location_description> + <holdingbranch>CADLC</holdingbranch> + <location>DEP104</location> + <homebranchname>La Courneuve</homebranchname> + <permanent_location>DEP104</permanent_location> + <itemlost>0</itemlost> + <replacementpricedate>2019-06-28</replacementpricedate> + <dateaccessioned>2019-06-28</dateaccessioned> + <biblionumber>123415</biblionumber> + <barcode>987988</barcode> + <damaged>0</damaged> + <timestamp>2021-02-12 20:05:51</timestamp> + <withdrawn>0</withdrawn> + <holdingbranchname>La Courneuve</holdingbranchname> + <issues>0</issues> + <notforloan>0</notforloan> + <itype_description>Livre</itype_description> + <homebranch>CADLC</homebranch> + <cn_sort>MB_1166_000000000000000</cn_sort> + <itype>LIVRE</itype> + <datelastseen>2019-06-28</datelastseen> + </item> + </items> + </record> +</GetRecords> diff --git a/tests/scenarios/Templates/TemplatesFakeItemsAvailabilityTest.php b/tests/scenarios/Templates/TemplatesFakeItemsAvailabilityTest.php new file mode 100644 index 0000000000000000000000000000000000000000..778c7c23421b9d8f421d6a8482eea9472fa90681 --- /dev/null +++ b/tests/scenarios/Templates/TemplatesFakeItemsAvailabilityTest.php @@ -0,0 +1,131 @@ +<?php +/** + * Copyright (c) 2012-2023, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class TemplatesFakeItemsAvailabilityTestCase extends AbstractControllerTestCase +{ + + public function setUp() { + parent::setUp(); + + Class_HttpClientFactory::forTest(); + + $this->_buildTemplateProfil(['id' => 1]); + + $comm_params = ['url_serveur' => 'http://catalog.meae.fr', + 'Interdire_reservation_doc_dispo' => 0, + 'disable_items_availability_threshold' => 300, + 'items_threshold' => 300, + 'Codification_disponibilites' => '', + 'restful' => '', + 'api_community' => '', + 'pre-registration' => '', + 'create_category_usergroup' => 0, + 'use_card_number' => '', + 'loans_per_page' => 20, + 'withdrawn_mapping' => '', + 'grouped_holds_itypes' => '', + 'bundled_holds_minimal_duration' => 0, + 'bundled_holds_maximal_duration' => 0]; + + $profil = Class_IntProfilDonnees::forKoha(); + $profil->save(); + + $intbib = + $this->fixture(Class_IntBib::class, + ['id' => 11, + 'id_bib' => 11, + 'label' => 'Meae', + 'sigb' => Class_IntBib::SIGB_KOHA, + 'comm_sigb' => Class_IntBib::COM_KOHA, + 'comm_params' => $comm_params]); + + $this->fixture(Class_Notice::class, + ['id' => 23, + 'titre' => 'Association française de science politique', + 'type_doc' => Class_TypeDoc::PERIODIQUE_ARTICLE]); + + $this->fixture(Class_Exemplaire::class, + ['id' => 231, + 'code_barres' => '987988-2314', + 'id_notice' => 23, + 'int_bib' => $intbib, + 'id_bib' => 11, + 'id_origine' => '340921', + 'id_data_profile' => $profil->getId(),]); + + $this->fixture(Class_Notice::class, + ['id' => 24, + 'id_sigb' => '', + 'type_doc' => Class_TypeDoc::PERIODIQUE]); + + $this->fixture(Class_Exemplaire::class, + ['id' => 241, + 'code_barres' => '987988', + 'id_notice' => 24, + 'id_int_bib' => 11, + 'int_bib' => $intbib, + 'ib_bib' => 1, + 'id_data_profile' => $profil->getId(), + 'id_origine' => '340920']); + + $this->fixture(Class_Notice::class, ['id' => 25, + 'titre' => 'Bonjour !', + + 'type_doc' => Class_TypeDoc::PERIODIQUE_ARTICLE]); + + $this->fixture(Class_Exemplaire::class, + ['id' => 251, + 'code_barres' => '', + 'id_notice' => 25, + 'id_int_bib' => 11, + 'int_bib' => $intbib, + 'ib_bib' => 1, + 'id_data_profile' => $profil->getId(), + 'zone_995' => serialize([['code'=>'9', 'valeur' =>'340920']]), + 'id_origine' => '340920']); + + + Class_HttpClientFactory::getInstance() + ->getLastHttpClient() + ->addRequestWithResponse('http://catalog.meae.fr:80?service=GetRecords&id=340920', + file_get_contents(__DIR__.'/../../fixtures/MAE_GetRecords273230.xml')); + + } + + + /** @test */ + public function item231ShouldBeAvailable() { + $this->dispatch('/opac/noticeajax/availability/id/23'); + $this->assertXPathContentContains('//span[contains(@class, "badge_record_availability")]', + 'Disponible'); + } + + + /** @test */ + public function item251ShouldBeAvailable() + { + $this->dispatch('/opac/noticeajax/availability/id/25'); + $this->assertXPathContentContains('//span[contains(@class, "badge_record_availability")]', + 'Disponible', $this->_response->getBody()); + + } +}