diff --git a/VERSIONS_WIP/96423 b/VERSIONS_WIP/96423 new file mode 100644 index 0000000000000000000000000000000000000000..b9705faa68e34b3d66ccf0c38483be2b811191eb --- /dev/null +++ b/VERSIONS_WIP/96423 @@ -0,0 +1 @@ + - ticket #96423 : SIGB Orphée : ajout d'une option pour activer les réservations à l'exemplaire \ No newline at end of file diff --git a/cosmogramme/php/fonctions/objets_saisie.php b/cosmogramme/php/fonctions/objets_saisie.php index c9b8dd6ae9145f2b822af6c95b9f0db29cefaa45..d54df4a3dc3c1a8ff8bd6c36c6e38f6049c44c2c 100644 --- a/cosmogramme/php/fonctions/objets_saisie.php +++ b/cosmogramme/php/fonctions/objets_saisie.php @@ -20,58 +20,58 @@ */ function getComboSimple($name, $valeur, $liste, $tous=false, $events='') { - if ('' != $events) - $events = ' ' . $events; - $combo = '<select id="' . $name . '" name="' . $name . '" ' . $events . '>'; - if ($tous) - $combo .= '<option value="">tous</option>'; - foreach ($liste as $clef => $libelle) { - $selected = ($valeur == $clef) ? ' selected' : ''; - $combo .= '<option value="' . $clef . '"' . $selected . '>' . $libelle . '</option>'; - } - return $combo . '</select>'; + if ('' != $events) + $events = ' ' . $events; + $combo = '<select id="' . $name . '" name="' . $name . '" ' . $events . '>'; + if ($tous) + $combo .= '<option value="">tous</option>'; + foreach ($liste as $clef => $libelle) { + $selected = ($valeur == $clef) ? ' selected' : ''; + $combo .= '<option value="' . $clef . '"' . $selected . '>' . $libelle . '</option>'; + } + return $combo . '</select>'; } function getOuiNon($name, $value) { - return getComboSimple($name, $value, ['' => 'Non', '1' => 'Oui']); + return getComboSimple($name, $value, ['' => 'Non', '1' => 'Oui']); } function getComboCodif($name, $clef, $valeur, $events='', $tous=false) { - $data = fetchOne('select liste from variables where clef=\''. $clef . '\''); - $v = array_filter(explode(chr(13) . chr(10), $data)); - $values = []; - for ($i=0; $i < count($v); $i++) { - $elem = explode(':', $v[$i]); - $values[$elem[0]] = $elem[1]; - } - return getComboSimple($name, $valeur, $values, $tous, $events); + $data = fetchOne('select liste from variables where clef=\''. $clef . '\''); + $v = array_filter(explode(chr(13) . chr(10), $data)); + $values = []; + for ($i=0; $i < count($v); $i++) { + $elem = explode(':', $v[$i]); + $values[$elem[0]] = $elem[1]; + } + return getComboSimple($name, $valeur, $values, $tous, $events); } function getComboTable($name, $table, $clef, $valeur, $condition='', $tous=false) { - global $sql; - $req = 'select ' . $clef . ',libelle from ' .$table; - $data = $sql->fetchAll($req . ' ' . $condition); - $values = []; - for($i=0; $i < count($data); $i++) { - $elem = $data[$i]; - $values[$elem[$clef]] = $elem['libelle']; - } - return getComboSimple($name, $valeur, $values, $tous); + global $sql; + $req = 'select ' . $clef . ',libelle from ' .$table; + $data = $sql->fetchAll($req . ' ' . $condition); + $values = []; + for($i=0; $i < count($data); $i++) { + $elem = $data[$i]; + $values[$elem[$clef]] = $elem['libelle']; + } + return getComboSimple($name, $valeur, $values, $tous); } function getChamp($id, $valeur, $taille) { - return '<input type="text" name="'.$id.'" value="'.$valeur .'"' - . (($taille) ? ' size="' . $taille . '"': '') . '>'; + return '<input type="text" name="'.$id.'" value="'.$valeur .'"' + . (($taille) ? ' size="' . $taille . '"': '') . '>'; } function getTextarea($id, $valeur, $largeur, $hauteur) { - return '<textarea name="'.$id.'" cols="'.$largeur .'" rows="'.$hauteur.'">' - . $valeur . '</textarea>'; + return '<textarea name="'.$id.'" cols="'.$largeur .'" rows="'.$hauteur.'">' + . $valeur . '</textarea>'; } @@ -79,108 +79,116 @@ function getTextarea($id, $valeur, $largeur, $hauteur) { * Blocs des parametres de communication avec le sigb */ function getBlocsParams($id_bib, $type, $valeurs) { - $valeurs = unserialize($valeurs); - $types = getCodifsVariable("comm_sigb"); + $valeurs = unserialize($valeurs); + $types = getCodifsVariable("comm_sigb"); - foreach($types as $item) { - $clef = $item['code']; - $bloc .= sprintf('<div id="comm_%s_%s" style="display:%s">', - $id_bib, $clef, ($clef == $type) ? 'block' : 'none'); + foreach($types as $item) { + $clef = $item['code']; + $bloc .= sprintf('<div id="comm_%s_%s" style="display:%s">', + $id_bib, $clef, ($clef == $type) ? 'block' : 'none'); - $params = []; - $champs_params = []; - $titres[0] = 'Paramètres'; + $params = []; + $champs_params = []; + $titres[0] = 'Paramètres'; if(in_array($clef, [COM_NANOOK])) $champs_params[0] = ['url_serveur', ['provide_suggest' => function($id, $valeur) { - return getOuiNon($id, $valeur); - }], + return getOuiNon($id, $valeur); + }], ['pre-registration' => function($id, $valeur) { - return getOuiNon($id, $valeur); - }]]; + return getOuiNon($id, $valeur); + }]]; if(in_array($clef, [COM_CDSCRIPT])) $champs_params[0] = ['server_url', 'remote_library_id']; - if (in_array($clef, [COM_PMB, COM_VSMART, COM_MICROBIB, COM_BIBLIXNET, COM_WATERBEAR])) - $champs_params[0] = ['url_serveur']; + if (in_array($clef, [COM_PMB, COM_VSMART, COM_MICROBIB, COM_BIBLIXNET, COM_WATERBEAR])) + $champs_params[0] = ['url_serveur']; - if (in_array($clef, [COM_CARTHAME])) - $champs_params[0] = ['url_serveur', 'key','sigb_field_name']; + if (in_array($clef, [COM_CARTHAME])) + $champs_params[0] = ['url_serveur', 'key','sigb_field_name']; - if (in_array($clef, [COM_ORPHEE])) - $champs_params[0] = ['url_serveur', 'key', 'allow_hold_available_items']; - - if ($clef == COM_KOHA) - $champs_params[0] = ['url_serveur', - ['restful' => function($id, $valeur) { - return getOuiNon($id, $valeur); - }], + if (in_array($clef, [COM_ORPHEE])) + $champs_params[0] = ['url_serveur', + 'key', + 'allow_hold_available_items', + ['hold_mode' => function($id, $valeur) { + return getComboSimple($id, + $valeur, + ['' => 'Au titre', + '1' => 'A l\'exemplaire']); + }]]; + + if ($clef == COM_KOHA) + $champs_params[0] = ['url_serveur', + ['restful' => function($id, $valeur) { + return getOuiNon($id, $valeur); + }], ['pre-registration' => function($id, $valeur) { - return getOuiNon($id, $valeur); - }], - 'Interdire_reservation_doc_dispo', + return getOuiNon($id, $valeur); + }], + 'Interdire_reservation_doc_dispo', 'use_card_number', - ['Codification_disponibilites' => function($id, $valeur){ - return getTextArea($id, $valeur, 30, 20); - }]]; - - if ($clef == COM_OPSYS) - $champs_params[0] = ['url_serveur', 'catalogue_web', 'reserver_retrait_bib_abonne']; - - if ($clef == COM_DYNIX) - $champs_params[0] = ['url_serveur', 'client_id']; - - if ($clef == COM_Z3950) - $champs_params[0] = ['url_serveur', 'login', 'password', 'nom_base']; - - if ($clef == COM_PERGAME) { - $titres = ['Règles de réservations', 'Règles de prolongations']; - $champs_params[0] = ['Autoriser_docs_disponibles', 'Max_par_carte' , 'Max_par_document']; - $champs_params[1] = ['Autoriser_prolongations', 'Interdire_si_reservation', - 'Nombre_max_par_document', 'Duree_en_jours', 'Anteriorite_max_en_jours']; - } - - $defaultInputRenderer = function($id, $valeur) { - return getChamp($id, $valeur, 30); - }; - - $cnt = count($champs_params); - for ($i=0; $i < $cnt; $i++) { - if (!$champs_params[$i]) - continue; - - $num_aide = 0; - $bloc .= '<div style="margin-top:5px"><b>' . $titres[$i] . '</b></div>'; - $bloc .= '<table>'; - - foreach ($champs_params[$i] as $param) { - $param_name = is_array($param) ? array_keys($param)[0] : $param; - $renderer = is_array($param) ? array_values($param)[0] : $defaultInputRenderer; - $valeur = $clef == $type ? $valeurs[$param_name] : ''; - - $bloc.= '<tr>' - .'<td class="form">' . $param_name.$aide[$num_aide] . '</td>' - .'<td class="form">' . $renderer('comp_' . $clef . '_' . $param_name, $valeur) .'</td>' - .'</tr>'; - - $num_aide++; - } - $bloc .= '</table>'; - - if ($clef == COM_NANOOK) { - $bloc .= "Format(0.8.7): ip:port/chemin_tomcat/ilsdi/nom_base <br/>" - . "Ex: 62.193.55.152:8080/afi_NanookWs/ilsdi/NANOOK"; - } - } - - if (in_array($clef, [COM_NANOOK, COM_KOHA, COM_PMB])) - $bloc .= " <br/><a target='_blank' class='test' href='#'>Tester la communication</a>"; - $bloc .= '</div>'; - } - return $bloc; + ['Codification_disponibilites' => function($id, $valeur){ + return getTextArea($id, $valeur, 30, 20); + }]]; + + if ($clef == COM_OPSYS) + $champs_params[0] = ['url_serveur', 'catalogue_web', 'reserver_retrait_bib_abonne']; + + if ($clef == COM_DYNIX) + $champs_params[0] = ['url_serveur', 'client_id']; + + if ($clef == COM_Z3950) + $champs_params[0] = ['url_serveur', 'login', 'password', 'nom_base']; + + if ($clef == COM_PERGAME) { + $titres = ['Règles de réservations', 'Règles de prolongations']; + $champs_params[0] = ['Autoriser_docs_disponibles', 'Max_par_carte' , 'Max_par_document']; + $champs_params[1] = ['Autoriser_prolongations', 'Interdire_si_reservation', + 'Nombre_max_par_document', 'Duree_en_jours', 'Anteriorite_max_en_jours']; + } + + $defaultInputRenderer = function($id, $valeur) { + return getChamp($id, $valeur, 30); + }; + + $cnt = count($champs_params); + for ($i=0; $i < $cnt; $i++) { + if (!$champs_params[$i]) + continue; + + $num_aide = 0; + $bloc .= '<div style="margin-top:5px"><b>' . $titres[$i] . '</b></div>'; + $bloc .= '<table>'; + + foreach ($champs_params[$i] as $param) { + $param_name = is_array($param) ? array_keys($param)[0] : $param; + $renderer = is_array($param) ? array_values($param)[0] : $defaultInputRenderer; + $valeur = $clef == $type ? $valeurs[$param_name] : ''; + + $bloc.= '<tr>' + .'<td class="form">' . $param_name.$aide[$num_aide] . '</td>' + .'<td class="form">' . $renderer('comp_' . $clef . '_' . $param_name, $valeur) .'</td>' + .'</tr>'; + + $num_aide++; + } + $bloc .= '</table>'; + + if ($clef == COM_NANOOK) { + $bloc .= "Format(0.8.7): ip:port/chemin_tomcat/ilsdi/nom_base <br/>" + . "Ex: 62.193.55.152:8080/afi_NanookWs/ilsdi/NANOOK"; + } + } + + if (in_array($clef, [COM_NANOOK, COM_KOHA, COM_PMB])) + $bloc .= " <br/><a target='_blank' class='test' href='#'>Tester la communication</a>"; + $bloc .= '</div>'; + } + return $bloc; } ?> \ No newline at end of file diff --git a/library/Class/WebService/SIGB/Orphee.php b/library/Class/WebService/SIGB/Orphee.php index c302bc725822a09d2c5e1618863fc84ea1a2a10b..d9ceca0f22007831cb1ebe2361d8e0e39547b6fe 100644 --- a/library/Class/WebService/SIGB/Orphee.php +++ b/library/Class/WebService/SIGB/Orphee.php @@ -16,7 +16,7 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class Class_WebService_SIGB_Orphee { @@ -25,9 +25,12 @@ class Class_WebService_SIGB_Orphee { public static function getService($params){ if (!isset(self::$service)) { $instance = new self(); - self::$service = Class_WebService_SIGB_Orphee_Service::getService($params['url_serveur'], - isset($params['key']) ? $params['key'] : null, - $params['allow_hold_available_items'] ? $params['allow_hold_available_items'] : null); + self::$service = Class_WebService_SIGB_Orphee_Service::getService($params['url_serveur'], + isset($params['key']) ? $params['key'] : null, + $params['allow_hold_available_items'] ? $params['allow_hold_available_items'] : null); + + if (isset($params['hold_mode']) && (Class_WebService_SIGB_Orphee_Service::HOLD_MODE_ITEM === (int)$params['hold_mode'])) + self::$service->beHoldModeItem(); } return self::$service; diff --git a/library/Class/WebService/SIGB/Orphee/Service.php b/library/Class/WebService/SIGB/Orphee/Service.php index 1441ba487ad41272a8f19c24b752cf2e620cf1a6..af814ded2498d1016bc068f461f67e30df1aff70 100644 --- a/library/Class/WebService/SIGB/Orphee/Service.php +++ b/library/Class/WebService/SIGB/Orphee/Service.php @@ -20,12 +20,18 @@ */ class Class_WebService_SIGB_Orphee_Service extends Class_WebService_SIGB_AbstractService { - protected $_search_client; - protected $_session_strategy; - protected $_wsdl; - protected $_key; - protected $_allow_hold_available_items; - protected $_soap_options; + const + HOLD_MODE_TITLE = 0, + HOLD_MODE_ITEM = 1; + + protected + $_search_client, + $_session_strategy, + $_wsdl, + $_key, + $_allow_hold_available_items, + $_soap_options, + $_hold_mode; public static function getService($wsdl, $key=null, $allow_hold_available_items=null) { @@ -44,6 +50,18 @@ class Class_WebService_SIGB_Orphee_Service extends Class_WebService_SIGB_Abstrac $this->_key = $key; $this->_allow_hold_available_items = $allow_hold_available_items; $this->_soap_options = $soap_options; + $this->_hold_mode = static::HOLD_MODE_TITLE; + } + + + public function beHoldModeItem() { + $this->_hold_mode = static::HOLD_MODE_ITEM; + return $this; + } + + + public function isHoldModeItem() { + return $this->_hold_mode === static::HOLD_MODE_ITEM; } @@ -245,24 +263,42 @@ class Class_WebService_SIGB_Orphee_Service extends Class_WebService_SIGB_Abstrac public function reserverExemplaire($user, $exemplaire, $code_annexe) { $notice_id = $this->removeOrpheeNoticePrefix($exemplaire->getIdOrigine()); + + return $this + ->withUserDo( + $user, + + $notice_id, + + function ($id, $emprunteur) use ($code_annexe, $exemplaire) { + return $this->_holdRecordOrItem($id, $emprunteur, $code_annexe, $exemplaire); + }, + + function ($result) { + $datas = simplexml_load_string($result->getXml()); + return ($datas->msg->code == 1) ? false : (string)$datas->msg->libelle; + }); + } + + + protected function _holdRecordOrItem($id, $emprunteur, $code_annexe, $exemplaire) { $tome = $exemplaire->isPeriodique() ? $exemplaire->getSubfield('u') : 0; - return $this->withUserDo( - $user, $notice_id, - function ($id, $emprunteur) use ($code_annexe, $tome) { - if ($this->hasSetAdhDispoAnx() && (null !== $code_annexe)) - $this->getSearchClient() - ->setAdhDispoAnx(setAdhDispoAnx::with($code_annexe)); + $client = $this->getSearchClient(); - return $this->getSearchClient() - ->RsvNtcAdh(RsvNtcAdh::withNoticeUserNo($id, $emprunteur->getId(), $tome)); - }, - function ($result) { - $datas = simplexml_load_string($result->getXml()); - return ($datas->msg->code == 1) ? false : (string)$datas->msg->libelle; - }); + if ($this->hasSetAdhDispoAnx() && (null !== $code_annexe)) + $client->setAdhDispoAnx(setAdhDispoAnx::with($code_annexe)); + + return $this->isHoldModeItem() + ? $client->RsvDmtAdh(RsvDmtAdh::withNoticeItemUser($id, + $exemplaire->getSigbExemplaire()->getId(), + $emprunteur->getId())) + + : $client->RsvNtcAdh(RsvNtcAdh::withNoticeUserNo($id, + $emprunteur->getId(), + $tome)); } @@ -567,6 +603,21 @@ class RsvNtcAdh { } +class RsvDmtAdh { + public $sntc; // string + public $dmt; // int + public $adh; // int + + public static function withNoticeItemUser($sntc, $dmt, $adh) { + $instance = new self(); + $instance->sntc = $sntc; + $instance->dmt = $dmt; + $instance->adh = $adh; + return $instance; + } +} + + class RsvNtcAdhResponse { public $RsvNtcAdhResult; // string @@ -583,6 +634,20 @@ class RsvNtcAdhResponse { } +class RsvDmtAdhResponse { + public $RsvDmtAdhResult; // string + + public static function withResult($xml) { + $instance = new self(); + $instance->RsvDmtAdhResult = $xml; + return $instance; + } + + + public function getXml() { + return Class_WebService_SIGB_Orphee_XMLFilter::filter($this->RsvDmtAdhResult); + } +} class SetPwdAdh { diff --git a/tests/library/Class/WebService/SIGB/OrpheeServiceTest.php b/tests/library/Class/WebService/SIGB/OrpheeServiceTest.php index 253eafa78867fa72f3d6bcbb4a8818d307b82971..07f0342fcecd12f685efaab099378946355314c4 100644 --- a/tests/library/Class/WebService/SIGB/OrpheeServiceTest.php +++ b/tests/library/Class/WebService/SIGB/OrpheeServiceTest.php @@ -24,6 +24,7 @@ include_once('Class/WebService/SIGB/Orphee/SessionStrategy.php'); include_once('OrpheeFixtures.php'); + class Class_WebService_SIGB_Orphee_ServiceForTesting extends Class_WebService_SIGB_Orphee_Service { public function __construct($search_client) { $this->_provided_search_client = $search_client; @@ -43,9 +44,7 @@ class Class_WebService_SIGB_Orphee_ServiceForTesting extends Class_WebService_SI class OrpheeServiceGetServiceTest extends ModelTestCase { - protected - $_storm_default_to_volatile = true, - $_orphee; + protected $_search_client; public function setUp() { parent::setUp(); @@ -55,23 +54,51 @@ class OrpheeServiceGetServiceTest extends ModelTestCase { ->whenCalled('GetId')->answers(GetIdResponse::withIdResult('1234')) ->whenCalled('__setCookie')->answers(true) ->whenCalled('EndSession')->answers(true); - - $this->_orphee = Class_WebService_SIGB_Orphee_Service::getService('tests/fixtures/orphee.wsdl'); - $this->_orphee->setSearchClient($this->_search_client); - $this->_orphee->isConnected(); } /** @test */ public function shouldCallEndSessionOnServiceDestruction() { - unset($this->_orphee); + $orphee = Class_WebService_SIGB_Orphee_Service::getService('tests/fixtures/orphee.wsdl'); + $orphee->setSearchClient($this->_search_client); + $orphee->isConnected(); + + unset($orphee); gc_collect_cycles(); $this->assertTrue($this->_search_client->methodHasBeenCalled('EndSession')); } + + + /** @test */ + public function serviceHoldModeShouldDefaultToHoldTitle() { + $orphee = Class_WebService_SIGB_Orphee::getService(['url_serveur' => 'tests/fixtures/orphee.wsdl', + 'allow_hold_available_items' => 0]); + $orphee->setSearchClient($this->_search_client); + + $this->assertFalse($orphee->isHoldModeItem()); + } + + + /** @test */ + public function serviceWithParamHoldModeOneShouldActivateHoldModeItem() { + $orphee = Class_WebService_SIGB_Orphee::getService(['url_serveur' => 'tests/fixtures/orphee.wsdl', + 'allow_hold_available_items' => 0, + 'hold_mode' => '1']); + $orphee->setSearchClient($this->_search_client); + + $this->assertTrue($orphee->isHoldModeItem()); + } + + + public function tearDown() { + Class_WebService_SIGB_Orphee::reset(); + parent::tearDown(); + } } + abstract class OrpheeServiceTestCase extends ModelTestCase { protected $_search_client, @@ -1349,6 +1376,7 @@ class OrpheeServiceGetInfoUserCarteHenryDupontVersion092015Test extends OrpheeSe + class OrpheeServiceReservationTest extends OrpheeServiceTestCase { public function setUp() { parent::setUp(); @@ -1361,7 +1389,7 @@ class OrpheeServiceReservationTest extends OrpheeServiceTestCase { /** @test */ - public function testReservationSuccessful() { + public function withHoldModeTitleShouldCallRsvNtcAdh() { $this->_search_client ->whenCalled('RsvNtcAdh') ->with(RsvNtcAdh::withNoticeUserNo('1301700727', 100753, 0)) @@ -1381,6 +1409,35 @@ class OrpheeServiceReservationTest extends OrpheeServiceTestCase { } + /** @test */ + public function withHoldModeItemShouldCallRsvDmtAdh() { + $this->_search_client + ->whenCalled('GetLstDmt') + ->with(GetLstDmt::withNtcAndFas('0030008850', 0)) + ->answers(GetLstDmtResponse::withResult(OrpheeFixtures::xmlGetLstDmtLivreEspagnol())) + + ->whenCalled('RsvDmtAdh') + ->with(RsvDmtAdh::withNoticeItemUser(30008850, 30007086, 100753)) + ->answers(RsvDmtAdhResponse::withResult('<datas><msg><code><![CDATA[1]]></code><libelle><![CDATA[Réservation mise en attente]]></libelle></msg></datas>')); + + + $result = $this->_orphee + ->beHoldModeItem() + ->reserverExemplaire($this->_henry_dupont, + $this->fixture('Class_Exemplaire', + ['id' => 234, + 'id_origine' => '30008850', + 'code_barres' => 'Ancien-07086', + 'int_bib' => $this->_henry_dupont->getIntBib(), + 'notice' => $this->fixture('Class_Notice', + ['id' => 988, + 'tome_alpha' => 2, + 'type_doc' => Class_TypeDoc::LIVRE])]), + ''); + $this->assertEquals(['statut' => true, 'erreur' => ''], $result); + } + + /** @test */ public function testReservationPeriodiqueSuccessful() {