From 0206961987edbfc3243ef69183eb76f356f4093f Mon Sep 17 00:00:00 2001
From: efalcy <efalcy@afi-sa.fr>
Date: Fri, 27 Nov 2015 12:16:48 +0100
Subject: [PATCH] dev #25892 : consultation sur place: add column and get info
 on exemplaire to display consultation sur place

---
 library/Class/WebService/SIGB/Exemplaire.php  | 10 ++-
 .../SIGB/VSmart/SearchResponseReader.php      |  6 ++
 .../View/Helper/Notice/ConsultationLink.php   | 88 +++++++++++++++++++
 .../View/Helper/Notice/Exemplaires.php        | 13 +++
 .../controllers/NoticeAjaxControllerTest.php  |  6 ++
 .../Class/WebService/SIGB/VSmartFixtures.php  | 82 ++++++++++++++++-
 .../Class/WebService/SIGB/VSmartTest.php      | 38 ++++++++
 7 files changed, 241 insertions(+), 2 deletions(-)
 create mode 100644 library/ZendAfi/View/Helper/Notice/ConsultationLink.php

diff --git a/library/Class/WebService/SIGB/Exemplaire.php b/library/Class/WebService/SIGB/Exemplaire.php
index 091f67d824a..afea954ef6a 100644
--- a/library/Class/WebService/SIGB/Exemplaire.php
+++ b/library/Class/WebService/SIGB/Exemplaire.php
@@ -54,7 +54,7 @@ class Class_WebService_SIGB_Exemplaire {
   protected $_cote;
   protected $_emplacement;
   protected $_issue_date;
-
+  protected $consultation = false;
 
   public static function newInstance() {
     return new self(0);
@@ -425,6 +425,14 @@ class Class_WebService_SIGB_Exemplaire {
     return false;
   }
 
+  public function isAvailableForConsultation() {
+    return $this->consultation;
+  }
+
+  public function setConsultationAvailable($bool = true) {
+    $this->consultation=$bool;
+  }
+
 
   /**
    * @return bool
diff --git a/library/Class/WebService/SIGB/VSmart/SearchResponseReader.php b/library/Class/WebService/SIGB/VSmart/SearchResponseReader.php
index ebcdac12720..8ef9e31de7b 100644
--- a/library/Class/WebService/SIGB/VSmart/SearchResponseReader.php
+++ b/library/Class/WebService/SIGB/VSmart/SearchResponseReader.php
@@ -21,6 +21,7 @@
 
 class Class_WebService_SIGB_VSmart_SearchResponseReader extends Class_WebService_SIGB_AbstractMarcXMLNoticeReader {
   protected $_current_exemplaire;
+  const  CONSULTATION_CODE="PATIMP";
   protected $_STATUT_SYSTEME = ['0' => 'Disponible',
                                 '4' => 'En prêt',
                                 '8' => 'En attente de retrait',
@@ -89,6 +90,11 @@ class Class_WebService_SIGB_VSmart_SearchResponseReader extends Class_WebService
     $this->_current_exemplaire->setVisibleOpac($data != '0');
   }
 
+  public function endSubfield_852_t($data) {
+    if ($data == self::CONSULTATION_CODE)
+      $this->_current_exemplaire->setConsultationAvailable();
+  }
+
 
   public function endSubfield_852_x($data) {
     $date = $data;
diff --git a/library/ZendAfi/View/Helper/Notice/ConsultationLink.php b/library/ZendAfi/View/Helper/Notice/ConsultationLink.php
new file mode 100644
index 00000000000..ee1034a244e
--- /dev/null
+++ b/library/ZendAfi/View/Helper/Notice/ConsultationLink.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Copyright (c) 2012, 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 ZendAfi_View_Helper_Notice_ConsultationLink extends ZendAfi_View_Helper_BaseHelper {
+  const HOLD_IMG = 'resa.png';
+
+  protected $_bib;
+  protected $_holdLabel;
+
+  public function Notice_ConsultationLink($bib, $ex, $html) {
+    $this->_bib = $bib;
+    $this->_holdLabel = $this->_('Consultation sur place');
+    return $this->renderItemOn($ex, $html);
+  }
+
+
+  /**
+   * @param $ex array
+   * @param $html string
+   * @return string modified html
+   */
+  public function renderItemOn($ex, $html) {
+    if (1 == $this->_bib->getInterdireResa())
+      return $this->_renderCellWith('&nbsp;');
+    xdebug_break();
+    if (!$ex['reservable'])
+      return $this->_renderCellWith('&nbsp;');
+
+    return $this->_renderCellWith($this->_renderAjaxOn($ex));
+  }
+
+
+  /** @return string */
+  protected function _renderCellWith($content) {
+    return $this->_tag('td', $content, ['class' => 'resa',
+                                        'style' => 'text-align:center;']);
+  }
+
+
+  /** @return string */
+  protected function _renderAjaxOn($ex) {
+    $link = $this->view->url(['controller' => 'recherche',
+                              'action' => 'consultation-pickup-ajax',
+                              'id_int_bib' => $ex['id_int_bib'],
+                              'id_bib' => $ex['id_bib'],
+                              'id_origine' => $ex['id'],
+                              'code_annexe' => $ex['code_annexe']]);
+
+    return $this
+      ->_tag('a', $this->_getHoldImage(),
+             ['href' => $link,
+              'data-popup' => 'true']);
+  }
+
+
+  /** @return string */
+  protected function _getHoldImageUrl() {
+    return Class_Profil::getCurrentProfil()->getUrlImage(self::HOLD_IMG);
+  }
+
+
+  /** @return string */
+  protected function _getHoldImage() {
+    return $this->view
+      ->tagImg($this->_getHoldImageUrl(),
+               ['title' => $this->_holdLabel,
+                'style' => 'border-style:none;']);
+  }
+}
+
+?>
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Notice/Exemplaires.php b/library/ZendAfi/View/Helper/Notice/Exemplaires.php
index dfa52ee83bc..720f7a1f31b 100644
--- a/library/ZendAfi/View/Helper/Notice/Exemplaires.php
+++ b/library/ZendAfi/View/Helper/Notice/Exemplaires.php
@@ -223,6 +223,7 @@ class ZendAfi_View_Helper_Notice_Exemplaires_Abstract extends ZendAfi_View_Helpe
                 'Localisation' => $preferences['localisation'] == 1,
                 'Plan' => $preferences['plan'] == 1,
                 'Resa' => $preferences['resa'] == 1 && $display_mode == 'normal',
+                'Consultation' => true,
                 'Oeuvre' => $display_mode == 'oeuvre'];
 
     $names = array_filter($mapping);
@@ -458,6 +459,18 @@ class ZendAfi_View_Helper_Notice_Exemplaires_Resa extends ZendAfi_View_Helper_No
 }
 
 
+class ZendAfi_View_Helper_Notice_Exemplaires_Consultation extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
+  public function getLibelle() {
+    return $this->_('Consultation sur place');
+  }
+
+  public function renderContent($exemplaire) {
+    return $this->view->Notice_ConsultationLink($this->getBib($exemplaire), $exemplaire, '');
+  }
+
+}
+
+
 
 class ZendAfi_View_Helper_Notice_Exemplaires_Oeuvre extends ZendAfi_View_Helper_Notice_Exemplaires_Abstract {
   public function getLibelle() {
diff --git a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
index 2edb7010273..cb701fc98b9 100644
--- a/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
+++ b/tests/application/modules/opac/controllers/NoticeAjaxControllerTest.php
@@ -771,6 +771,12 @@ class NoticeAjaxControllerExemplairesWithIdBibs extends NoticeAjaxControllerExem
     $this->assertNotXPathContentContains('//td[@class="cote"]','VOD-T-DLJ');
   }
 
+
+  /** @test */
+  public function consultationTitleShouldBeDisplayed() {
+    $this->assertXPathContentContains('//th[@class="consultation"]','Consultation sur place',$this->_response->getBody());
+  }
+
 }
 
 
diff --git a/tests/library/Class/WebService/SIGB/VSmartFixtures.php b/tests/library/Class/WebService/SIGB/VSmartFixtures.php
index ad032c3471c..b4767cee3c5 100644
--- a/tests/library/Class/WebService/SIGB/VSmartFixtures.php
+++ b/tests/library/Class/WebService/SIGB/VSmartFixtures.php
@@ -329,9 +329,89 @@ class VSmartFixtures {
          </zs:searchRetrieveResponse>';
   }
 
+  public static function xmlConsultationItems() {
+    return
+      '<?xml version="1.0" encoding="utf-8"?><zs:searchRetrieveResponse xmlns:zs="http://www.loc.gov/zing/srw/"><zs:version>2013.08.20</zs:version><zs:numberOfRecords>1</zs:numberOfRecords><zs:resultSetId></zs:resultSetId><zs:records><zs:record format="UniMarc/B" type="Bibliographic"><zs:recordSchema>info:marcXchange</zs:recordSchema><zs:recordPacking>xml</zs:recordPacking><zs:recordData><leader>00855nam  22002293n 450 </leader>
+<controlfield tag="001">1/162383</controlfield>
+<controlfield tag="003">http://catalogue.bnf.fr/ark:/12148/cb324328130</controlfield>
+<controlfield tag="005">20130218095144.0</controlfield>
+<datafield tag="035" ind1=" " ind2=" "><subfield code="a">SAFIG00010361-01</subfield>
+</datafield>
+<datafield tag="035" ind1=" " ind2=" "><subfield code="a">FRBNF32432813000000X</subfield>
+</datafield>
+<datafield tag="035" ind1=" " ind2=" "><subfield code="a">SAFIG00040553-01</subfield>
+</datafield>
+<datafield tag="039" ind1=" " ind2=" "><subfield code="a">SU076400310001P  </subfield>
+</datafield>
+<datafield tag="100" ind1=" " ind2=" "><subfield code="a">19970701d1938    m  y0frey0103    ba</subfield>
+</datafield>
+<datafield tag="101" ind1="0" ind2=" "><subfield code="a">fre</subfield>
+</datafield>
+<datafield tag="102" ind1=" " ind2=" "><subfield code="a">FR</subfield>
+</datafield>
+<datafield tag="105" ind1=" " ind2=" "><subfield code="a">||||z   00|||</subfield>
+</datafield>
+<datafield tag="106" ind1=" " ind2=" "><subfield code="a">r</subfield>
+</datafield>
+<datafield tag="200" ind1="1" ind2=" "><subfield code="a">A Montluçon</subfield>
+<subfield code="b">Texte imprimé</subfield>
+<subfield code="f">Maurice Antonin</subfield>
+</datafield>
+<datafield tag="210" ind1=" " ind2=" "><subfield code="a">Montluçon</subfield>
+<subfield code="b">avenue Wilson</subfield>
+<subfield code="c">Eyboulet</subfield>
+<subfield code="d">1938 (28 octobre)</subfield>
+<subfield code="e">Saint-Étienne</subfield>
+<subfield code="g">impr. Verdier</subfield>
+</datafield>
+<datafield tag="215" ind1=" " ind2=" "><subfield code="a">235 p., 18 fr. [1005]</subfield>
+<subfield code="c">couv. ill.</subfield>
+<subfield code="d">In-16</subfield>
+</datafield>
+<datafield tag="700" ind1=" " ind2="1"><subfield code="a">Antonin</subfield><subfield code="b">Maurice</subfield>
+<subfield code="4">070</subfield>
+</datafield>
+<datafield tag="801" ind1=" " ind2="0"><subfield code="2">AFNOR</subfield>
+<subfield code="a">FR</subfield>
+<subfield code="b">FR-751131015</subfield>
+<subfield code="c">19970701</subfield>
+<subfield code="g">AFNOR</subfield>
+<subfield code="h">FRBNF32432813000000X</subfield>
+</datafield>
+<datafield tag="801" ind1=" " ind2="0"><subfield code="a">FR</subfield>
+<subfield code="b">Moulins Communauté B031906101</subfield>
+<subfield code="c">20120101</subfield>
+</datafield>
+<datafield tag="801" ind1=" " ind2=" "><subfield code="a">FR</subfield>
+<subfield code="b">SAFIG</subfield>
+<subfield code="c">20110101</subfield>
+</datafield>
+<datafield tag="852"><subfield code="a">RES</subfield>
+<subfield code="b">MCFP</subfield>
+<subfield code="c">MPBOU</subfield>
+<subfield code="e">20120713</subfield>
+<subfield code="h">BP-1273</subfield>
+<subfield code="p">MCP903847</subfield>
+<subfield code="q">MCP903847</subfield>
+<subfield code="t">PATIMP</subfield>
+<subfield code="y">0</subfield>
+</datafield>
+<datafield tag="852"><subfield code="a">RES</subfield>
+<subfield code="b">MCFP</subfield>
+<subfield code="c">MPBOU</subfield>
+<subfield code="e">20120713</subfield>
+<subfield code="h">BP-180</subfield>
+<subfield code="p">MCP900038</subfield>
+<subfield code="q">MCP900038</subfield>
+<subfield code="t">PATIMP</subfield>
+<subfield code="y">0</subfield>
+</datafield>
+</zs:recordData><zs:recordPosition>-1</zs:recordPosition></zs:record></zs:records></zs:searchRetrieveResponse>';
+  }
+
 
   public static function xmlAvailableItems() {
-      return
+    return
          '<VubisSmart>
               <Header>
                   <Function>GetASRItems</Function>
diff --git a/tests/library/Class/WebService/SIGB/VSmartTest.php b/tests/library/Class/WebService/SIGB/VSmartTest.php
index 1e85a6821d7..0f73c07e160 100644
--- a/tests/library/Class/WebService/SIGB/VSmartTest.php
+++ b/tests/library/Class/WebService/SIGB/VSmartTest.php
@@ -459,6 +459,44 @@ class VSmartServiceBibGetAnthologieLitteratureTest extends Storm_Test_ModelTestC
 
 
 
+
+
+class VSmartServiceBibGetConsultationTest extends Storm_Test_ModelTestCase {
+  public function setUp() {
+    $mock_web_client = $this->mock()
+      ->whenCalled('open_url')
+      ->with('http://vpn.agglo-moulins.fr/formation/VubisSmartHttpApi.csp?fu=BibSearch&Application=Bib&Database=2&RequestType=RecordNumber&Request=3066')
+      ->answers(VSmartFixtures::xmlConsultationItems());
+
+    $this->service = Class_WebService_SIGB_VSmart_Service::newInstance()
+                                      ->setServerRoot('vpn.agglo-moulins.fr/formation/')
+                                      ->setWebClient($mock_web_client);
+
+    $this->montlucon = $this->service->getNotice('2/3066');
+  }
+
+
+  /** @test */
+  public function shouldAnswerOneNotice() {
+    $this->assertInstanceOf('Class_WebService_SIGB_Notice', $this->montlucon);
+  }
+
+
+
+  /** @test */
+  public function firstExemplaireShouldNotBeReservable() {
+    $this->assertFalse($this->montlucon->exemplaireAt(0)->isReservable());
+  }
+
+
+  /** @test */
+  public function firstExemplaireCanBeAvailableForConsultation() {
+    $this->assertTrue($this->montlucon->exemplaireAt(0)->isAvailableForConsultation());
+  }
+
+}
+
+
 class VSmartServiceBibGetHarryPotterTest extends Storm_Test_ModelTestCase {
   public function setUp() {
     $mock_web_client = $this->mock()
-- 
GitLab