From 93c800cc1c392f396b8cdde027e2fca39edbdbcc Mon Sep 17 00:00:00 2001
From: llaffont <llaffont@afi-sa.fr>
Date: Thu, 4 Dec 2014 17:38:21 +0100
Subject: [PATCH] dev #13769 add item availability recognition

---
 cosmogramme/php/_init.php                     |  2 +-
 cosmogramme/php/classes/classe_unimarc.php    |  8 ++-
 cosmogramme/php/config_profil_donnees.php     |  1 +
 cosmogramme/sql/patch/patch_225.sql           |  1 +
 .../php/classes/NoticeIntegrationTest.php     | 51 +++++++++++++++-
 library/Class/Codification.php                | 58 ++++++++++++++-----
 library/Class/Exemplaire.php                  | 12 ++--
 library/Class/IntProfilDonnees.php            |  8 +++
 scripts/marc_add_fields.php                   | 23 ++++++++
 tests/library/Class/CodificationTest.php      | 14 ++---
 10 files changed, 151 insertions(+), 27 deletions(-)
 create mode 100644 cosmogramme/sql/patch/patch_225.sql
 create mode 100644 scripts/marc_add_fields.php

diff --git a/cosmogramme/php/_init.php b/cosmogramme/php/_init.php
index 653e89b2a2c..d2e8cb1dc36 100644
--- a/cosmogramme/php/_init.php
+++ b/cosmogramme/php/_init.php
@@ -1,7 +1,7 @@
 <?php
 // Constantes
 error_reporting(E_ERROR | E_PARSE);
-define("PATCH_LEVEL","224");
+define("PATCH_LEVEL","225");
 
 define("APPLI","cosmogramme");
 define("COSMOPATH", "/var/www/html/vhosts/opac2/www/htdocs");
diff --git a/cosmogramme/php/classes/classe_unimarc.php b/cosmogramme/php/classes/classe_unimarc.php
index a00baecc48b..6a999753620 100644
--- a/cosmogramme/php/classes/classe_unimarc.php
+++ b/cosmogramme/php/classes/classe_unimarc.php
@@ -300,6 +300,7 @@ class notice_unimarc extends iso2709_record {
 		$champ_genre = $this->getProfilNumericAttribute('champ_genre');
 		$champ_emplacement = $this->getProfilNumericAttribute('champ_emplacement');
 		$champ_annexe = $this->getProfilNumericAttribute('champ_annexe');
+		$champ_availability = $this->getProfilNumericAttribute('champ_availability');
 
 		$champs_nouveaute = $this->profil['attributs'][4];
 		if(count($champs_nouveaute)) {
@@ -325,7 +326,8 @@ class notice_unimarc extends iso2709_record {
 				function ($champ, &$ex) use ($ret, $champ_code_barres, $codes_barres,
 																		 $cotes, $nb_ex_detruits, $champs_nouveaute,
 																		 $champ_genre, $champ_emplacement,
-																		 $champ_annexe, $champ_section, $champ_cote) {
+																		 $champ_annexe, $champ_section, $champ_cote,
+																		 $champ_availability) {
 					if ($champ['code'] == $champ_code_barres) {
 						$this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
 
@@ -389,6 +391,10 @@ class notice_unimarc extends iso2709_record {
 							and $champ['code'] == $champs_nouveaute['champ']) {
 						$ex['date_nouveaute'] = $this->calculDateNouveaute($champ['valeur']);
 					}
+
+					if ($champ_availability and $champ['code'] == $champ_availability) {
+						$ex['is_available'] = ('1' === $champ['valeur']);
+					}
 				});
 
 			if ($ex['code_barres'] > '') {
diff --git a/cosmogramme/php/config_profil_donnees.php b/cosmogramme/php/config_profil_donnees.php
index 7661379536a..c4997be3cb5 100644
--- a/cosmogramme/php/config_profil_donnees.php
+++ b/cosmogramme/php/config_profil_donnees.php
@@ -207,6 +207,7 @@ function paveUnimarcNotice($profil)
 	print('<tr><td class="form" align="right">Genre</td><td class="form">'.getComboChampsExemplaires("champ_genre",$profil["attributs"][0]["champ_genre"]).'</td></tr>');
 	print('<tr><td class="form" align="right">Emplacement</td><td class="form">'.getComboChampsExemplaires("champ_emplacement",$profil["attributs"][0]["champ_emplacement"]).'</td></tr>');
 	print('<tr><td class="form" align="right">Annexe</td><td class="form">'.getComboChampsExemplaires("champ_annexe",$profil["attributs"][0]["champ_annexe"]).'</td></tr>');
+	print('<tr><td class="form" align="right">Disponibilité</td><td class="form">'.getComboChampsExemplaires("champ_availability",$profil["attributs"][0]["champ_availability"]).'</td></tr>');
 
 	// date de nouveauté
 	print('<tr><th class="form" align="left" colspan="2">Date de nouveauté</th></tr>');
diff --git a/cosmogramme/sql/patch/patch_225.sql b/cosmogramme/sql/patch/patch_225.sql
new file mode 100644
index 00000000000..f41d3b558d0
--- /dev/null
+++ b/cosmogramme/sql/patch/patch_225.sql
@@ -0,0 +1 @@
+alter table exemplaires add column is_available boolean default false;
diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
index 8d01ecc9661..173bcaddd3b 100644
--- a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
+++ b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php
@@ -106,13 +106,18 @@ abstract class NoticeIntegrationTestCase extends ModelTestCase {
 
 
 	public function loadNotice($filename) {
+		$this->loadNoticeFromString(file_get_contents(dirname(__FILE__)."/".$filename.".txt"));
+	}
+
+
+	public function loadNoticeFromString($unimarc) {
 		Codif_langue::getInstance()->setCodif(['fre' => ['id_langue' => 'fre',
 			'libelle' => 'français']]);
 
 		$this->notice_integration = new notice_integration();
 		$this->notice_integration->setParamsIntegration(1, 0, isset($this->_profil_donnees['id_profil']) ? $this->_profil_donnees['id_profil'] : 1);
 
-		$this->notice_integration->traiteNotice(file_get_contents(dirname(__FILE__)."/".$filename.".txt"));
+		$this->notice_integration->traiteNotice($unimarc);
 		$this->notice_integration->traiteFacettes();
 		$this->notice_data = $this->notice_integration->getNotice();
 	}
@@ -1569,6 +1574,50 @@ class NoticeIntegrationConcertoSaintSaensTest extends NoticeIntegrationTestCase
 
 
 
+/** @see http://forge.afi-sa.fr/issues/13769 */
+class NoticeIntegrationAvailabilityFacetTest extends NoticeIntegrationTestCase {
+	public function getProfilDonnees() {
+		return Class_IntProfilDonnees::forNanook()
+			->setIdProfil(110)
+			->setAvailabilityField('v')
+			->getRawAttributes();
+	}
+
+
+	public function setUp() {
+		parent::setUp();
+
+		/*
+		 * cf class_unimarc: [[file:../../../php/classes/classe_unimarc.php::$notice%5B"sections"%5D%5B%5D%20%3D%20$exemplaire%5B"section"%5D%3B][item data to record]] ,
+		 * [[file:../../../php/classes/classe_unimarc.php::if%20($champ_availability%20and%20$champ%5B'code'%5D%20%3D%3D%20$champ_availability)%20{][item parse unimarc]]
+		 */
+		$writer = new Class_NoticeUnimarc_Writer();
+		$writer->setNotice(file_get_contents(dirname(__FILE__)."/unimarc_symphonie.txt"));
+		$writer->add_field('995',
+											 '  ',
+											 [
+												['f', '12345'],
+												['v', '1']
+											 ]);
+		$writer->update();
+		$this->loadNoticeFromString($writer->getFullRecord());
+	}
+
+
+	/** @test */
+	public function firstItemShouldNotBeAvailable() {
+		$this->assertFalse(Class_Exemplaire::find(1)->isDisponible(true));
+	}
+
+
+	/** @test */
+	public function secondItemShouldBeAvailable() {
+		$this->assertTrue(Class_Exemplaire::find(2)->isDisponible(true));
+	}
+}
+
+
+
 /** @see http://forge.afi-sa.fr/issues/16358 */
 class NoticeIntegrationSymphonieTest extends NoticeIntegrationTestCase {
 	public function getProfilDonnees() {
diff --git a/library/Class/Codification.php b/library/Class/Codification.php
index 697f466df57..e2d4d470951 100644
--- a/library/Class/Codification.php
+++ b/library/Class/Codification.php
@@ -16,12 +16,44 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with AFI-OPAC 2.0; 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
  */
 
+
+/**
+ * Liste des codes utilisés:
+ * A: auteur
+ * B: bib
+ * C: collection
+ * D: dewey
+ * E: éditeur
+ * F: centre intérêt
+ * G: genre
+ * H: thésaurus
+ * I: identifiant
+ * J: titre
+ * K: collation
+ * L: langue
+ * M: matière
+ * N: année
+ * O: notes
+ * P: pcdm4
+ * Q:
+ * R: résumé
+ * S: section
+ * T: type de doc
+ * U:
+ * V: disponibilité
+ * W:
+ * X:
+ * Y: annexe
+ * Z: tag
+ * 8: urlg
+ * 9: nouveauté
+ */
 class Class_Codification {
 	use Trait_Singleton, Trait_Translator;
-	const 
+	const
 		CHAMPS = 'JAKEFCNMDGHPILOR8',
 		CODE_COLLECTION = 'C',
 		CODE_EDITEUR = 'E',
@@ -67,17 +99,17 @@ class Class_Codification {
 		$combo.='</select>';
 		return $combo;
 	}
-	
+
 
 	public function getCodesLibellesFacette($concatenated_facettes) {
 		$codes_libelles=[];
 		for($i=0; $i<strlen($concatenated_facettes); $i++) {
-			
+
 			if($concatenated_facettes[$i]=='H') {
 				$code=substr($concatenated_facettes,$i,5);
 				$i=$i+4;
 			}
-			else 
+			else
 				$code=substr($concatenated_facettes,$i,1);
 			$nom_facette= Class_Codification::getNomChamp($code);
 			$codes_libelles[$code]=$nom_facette;
@@ -92,11 +124,11 @@ class Class_Codification {
 			return '';
 
 		switch($type)	{
-			case "X": 
+			case "X":
 				$lib=[" ", $this->_('Livres et Vidéos'), $this->_('Musique')];
 				$l=getVar("FACETTE_PCDM4_LIBELLE"); if(trim($l)) $lib[2]=$l;
 				$l=getVar("FACETTE_DEWEY_LIBELLE"); if(trim($l)) $lib[1]=$l;
-				return $lib[intval($id)]; 
+				return $lib[intval($id)];
 		  case Class_CodifDewey::CODE_FACETTE:							return Class_CodifDewey::getLibelle($id);
 			case Class_CodifPcdm4::CODE_FACETTE:							return Class_CodifPcdm4::getLibelle($id);
 			case Class_CodifThesaurus::CODE_FACETTE:					return ($thesaurus			= Class_CodifThesaurus::findFirstBy(['id_thesaurus'=>$id]))		? $thesaurus->getLibelleFacette(): '';
@@ -178,13 +210,13 @@ class Class_Codification {
 
 		self::genereNomsChamps();
 
-		if($code=="tous")	{ 
-			foreach($this->_nom_champs as $key => $valeur) 
+		if($code=="tous")	{
+			foreach($this->_nom_champs as $key => $valeur)
 				$lib[$key]=$valeur[0];
 			return $lib;
 		}
 
-		return isset($this->_nom_champs[$type][$pluriel]) ? $this->_nom_champs[$type][$pluriel] : '';	
+		return isset($this->_nom_champs[$type][$pluriel]) ? $this->_nom_champs[$type][$pluriel] : '';
 	}
 
 
@@ -198,7 +230,7 @@ class Class_Codification {
 			return;
 
 		$translate = Zend_Registry::get('translate');
-			
+
 		$this->_nom_onglets = [
 			"detail"				=> Class_Onglet::forLibelleAndType($translate->_("Description du document"),'detail'),
 			"avis"					=> Class_Onglet::forLibelleAndType($translate->_("Critiques"),'avis'),
@@ -238,7 +270,7 @@ class Class_Codification {
 		return $onglet ? $this->_nom_onglets[$onglet]->getLibelle() : $this->_nom_onglets;
 	}
 
-	
+
 	public static function getLibelleForSerie($notice) {
 		$message = 'Voir tous les tomes';
 
@@ -249,7 +281,7 @@ class Class_Codification {
 		case Class_TypeDoc::DVD:
 			$message = 'Voir tous les épisodes';
 			break;
-		}		
+		}
 
 		return self::concatLibelleWithTitreChapeau($message, $notice->getTitreChapeau());
 	}
diff --git a/library/Class/Exemplaire.php b/library/Class/Exemplaire.php
index 58c231b0cd3..33b8dd27e96 100644
--- a/library/Class/Exemplaire.php
+++ b/library/Class/Exemplaire.php
@@ -37,9 +37,10 @@ class Class_Exemplaire extends Storm_Model_Abstract {
 									 'referenced_in' => 'id_int_bib']];
 
 	protected $_default_attribute_values = [
-		'id_origine' => null,
-		'code_barres' => null,
-		'annexe' => null];
+																					'id_origine' => null,
+																					'code_barres' => null,
+																					'annexe' => null,
+																					'is_available' => false];
 
 	protected $_sigb_exemplaire;
 
@@ -137,10 +138,13 @@ class Class_Exemplaire extends Storm_Model_Abstract {
 		return Class_CodifAnnexe::findFirstBy(['code' => $this->getAnnexe()]);
 	}
 
-	public function isDisponible() {
+	public function isDisponible($cache_only = false) {
 		if ($this->getNotice()->isRessourceNumerique())
 			return true;
 
+		if ($cache_only)
+			return $this->_get('is_available');
+
 		$sigbExemplaire = $this->getSigbExemplaire();
 		if (null == $sigbExemplaire)
 			return false;
diff --git a/library/Class/IntProfilDonnees.php b/library/Class/IntProfilDonnees.php
index 724f69ab25c..a8ce294b834 100644
--- a/library/Class/IntProfilDonnees.php
+++ b/library/Class/IntProfilDonnees.php
@@ -345,11 +345,19 @@ class Class_IntProfilDonnees extends Storm_Model_Abstract {
 		return $this->setAttributs($config);
 	}
 
+
 	public function setTypeDocField($value) {
 		$config = unserialize($this->getAttributs());
 		$config[0]['champ_type_doc'] = $value;
 		return $this->setAttributs($config);
 	}
+
+
+	public function setAvailabilityField($value) {
+		$config = unserialize($this->getAttributs());
+		$config[0]['champ_availability'] = $value;
+		return $this->setAttributs($config);
+	}
 }
 
 ?>
\ No newline at end of file
diff --git a/scripts/marc_add_fields.php b/scripts/marc_add_fields.php
new file mode 100644
index 00000000000..2b99ed45371
--- /dev/null
+++ b/scripts/marc_add_fields.php
@@ -0,0 +1,23 @@
+<?php
+
+// sample : php scripts/marc_add_fields.php cosmogramme/tests/php/classes/unimarc_symphonie.txt '995 $a Médiathèque $v 1 $f 3601051399'
+
+require('console.php');
+$writer = new Class_NoticeUnimarc_Writer();
+$writer->setNotice(file_get_contents($argv[1]));
+$params = explode(' ', $argv[2]);
+
+
+$zone=array_shift($params);
+
+$subfields=array_chunk($params,2);
+foreach($subfields as $index => $subfield) {
+	$subfields[$index][0]=str_replace('$','',$subfield[0]);
+}
+
+$writer->add_field($zone,'  ',$subfields);
+$writer->update();
+echo $writer->getFullRecord();
+
+
+?>
\ No newline at end of file
diff --git a/tests/library/Class/CodificationTest.php b/tests/library/Class/CodificationTest.php
index 19086d6e5d9..06917470fea 100644
--- a/tests/library/Class/CodificationTest.php
+++ b/tests/library/Class/CodificationTest.php
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with AFI-OPAC 2.0; 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 CodificationNomChampsTest extends Storm_Test_ModelTestCase {
@@ -33,7 +33,7 @@ class CodificationNomChampsTest extends Storm_Test_ModelTestCase {
 
 		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_CodifThesaurus')
 			->whenCalled('getIndices')
-			->answers([Class_CodifThesaurus::newInstanceWithId(3, 
+			->answers([Class_CodifThesaurus::newInstanceWithId(3,
 																								 ['id_thesaurus' => 'GENR',
 																									'libelle_facette' => 'Genre Electre',
 																									'libelle' => 'Genre '
@@ -45,8 +45,8 @@ class CodificationNomChampsTest extends Storm_Test_ModelTestCase {
 		$translate = Zend_Registry::get('translate');
 		$translate->setLocale('fr');
 
-	}								
-	
+	}
+
 
 	public function expectedChamps() {
 		$translate = Zend_Registry::get('translate');
@@ -74,6 +74,7 @@ class CodificationNomChampsTest extends Storm_Test_ModelTestCase {
 			[ ['S'],[$translate->_('Section')]],
 			[ ['J'],[$translate->_('Titre')]],
 			[ ['T'],[$translate->_('Type de document')]],
+			[ ['V'],[$translate->_('Disponibilité')]],
 			[ ['Y'],[$translate->_('Site')]],
 			[ ['Z'],[$translate->_('Tag')]],
 			[ ['8'],[$translate->_('Lien internet')]],
@@ -81,12 +82,11 @@ class CodificationNomChampsTest extends Storm_Test_ModelTestCase {
 			];
 	}
 
-	/** 
+	/**
 	 * @dataProvider expectedChamps
-	 * @test 
+	 * @test
 	 */
 	public function getNomChampShouldBe($nom_champs,$libelle) {
 		$this->assertEquals($libelle[0],$this->codification->getNomChamp($nom_champs,0));
 	 }
 }
-
-- 
GitLab