From 7a908d7553dd45387b5a7b0015088b93857302d1 Mon Sep 17 00:00:00 2001 From: Laurent Laffont <llaffont@afi-sa.fr> Date: Mon, 15 Jul 2019 12:17:06 +0200 Subject: [PATCH] hotline #82630 add record deduplication on 001 per integration site hotline #82630 add missing file --- cosmogramme/VERSIONS_HOTLINE/82630 | 1 + .../php/classes/KohaRecordIntegrationTest.php | 63 +++++++++++++++++-- .../tests/php/classes/ModelTestCase.php | 2 +- .../php/classes/NoticeIntegrationTest.php | 49 ++++++++------- .../tests/php/classes/unimarc_mementos.txt | 1 + library/Class/IntBib.php | 4 +- library/Class/Notice/DoubleFinder.php | 38 +++++++---- .../library/Class/Notice/DoubleFinderTest.php | 3 + 8 files changed, 122 insertions(+), 39 deletions(-) create mode 100644 cosmogramme/VERSIONS_HOTLINE/82630 create mode 100644 cosmogramme/tests/php/classes/unimarc_mementos.txt diff --git a/cosmogramme/VERSIONS_HOTLINE/82630 b/cosmogramme/VERSIONS_HOTLINE/82630 new file mode 100644 index 00000000000..af91c4ca396 --- /dev/null +++ b/cosmogramme/VERSIONS_HOTLINE/82630 @@ -0,0 +1 @@ + - ticket #82630 : Ajout du dédoublonnage des notices sur le champ 001 par site. \ No newline at end of file diff --git a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php index 4d8e068cb57..9af40c22013 100644 --- a/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php +++ b/cosmogramme/tests/php/classes/KohaRecordIntegrationTest.php @@ -23,7 +23,8 @@ require_once('NoticeIntegrationTest.php'); abstract class KohaRecordIntegrationTestCase extends NoticeIntegrationTestCase { - protected $_storm_default_to_volatile = true; + protected $_sigb = Class_IntBib::COM_KOHA; + public function getProfilDonnees() { return Class_IntProfilDonnees::forKoha()->getRawAttributes(); @@ -32,6 +33,7 @@ abstract class KohaRecordIntegrationTestCase extends NoticeIntegrationTestCase { + class KohaRecordIntegrationBadUnimarcTest extends KohaRecordIntegrationTestCase { public function setUp() { parent::setUp(); @@ -174,7 +176,7 @@ class KohaRecordIntegrationFacetPresseTest extends KohaRecordIntegrationTestCase ]); - Class_CosmoVar::setValueOf('mode_doublon', '1'); + Class_CosmoVar::setValueOf('mode_doublon', Class_CosmoVar::DOUBLE_SEARCH_ALPHA_KEY); $this->loadNotice('unimarc_koha_okapi'); } @@ -216,7 +218,7 @@ class KohaRecordIntegrationFacetPresseTest extends KohaRecordIntegrationTestCase /** @test */ public function facettesShouldContainsT2AndHANNE0001AndHMOIS0001AndJOUR0001() { - $this->assertEquals('HANNE0001 HMOIS0001 HJOUR0001 T2 B1 YMEDSTMAR', + $this->assertEquals('HANNE0001 HMOIS0001 HJOUR0001 Lfre T2 B1 YMEDSTMAR', Class_Notice::find(1) ->updateFacetsFromExemplaires() ->getFacettes()); @@ -225,7 +227,7 @@ class KohaRecordIntegrationFacetPresseTest extends KohaRecordIntegrationTestCase /** @test */ public function facettesForRecord25ShouldContainsT2AndHANNE0001AndHMOIS0001() { - $this->assertEquals('HANNE0001 HMOIS0007 HJOUR0006 T2 B1 YMEDSTMAR', + $this->assertEquals('HANNE0001 HMOIS0007 HJOUR0006 Lfre T2 B1 YMEDSTMAR', Class_Notice::find(25) ->updateFacetsFromExemplaires() ->getFacettes()); @@ -556,3 +558,56 @@ class KohaRecordIntegrationBdMilleniumWithAuthorityTest extends KohaRecordIntegr ])); } } + + + + +class KohaRecordIntegrationDeduplicateTest extends KohaRecordIntegrationTestCase { + public function setUp() { + parent::setUp(); + Class_CosmoVar::setValueOf('mode_doublon', Class_CosmoVar::DOUBLE_SEARCH_NONE); + $this->loadRecordsFromFile('unimarc_mementos'); + + $this->fixture('Class_IntBib', + ['id' => 2, + 'nom' => 'My other library', + 'nom_court' => 'MOL', + 'mail' => '', + 'qualite' => 10, + 'dernier_ajout' => '2015-01-01', + 'ecart_ajouts' => '0', + 'date_mail' => '', + 'sigb' => $this->_sigb, + 'planif_mode' => 'r', + 'comm_sigb' => 0, + 'comm_params' => 'N']); + + $this->loadRecordsFromFile('unimarc_mementos', 2); + $this->loadRecordsFromFile('unimarc_mementos'); + } + + + /** @test */ + public function numberOfRecordsShouldBeSix() { + $this->assertEquals(6, Class_Notice::countBy([])); + } + + + /** @test */ + public function firstIntBibShouldHaveFourItems() { + $this->assertEquals(4, Class_Exemplaire::countBy(['id_int_bib' => 1])); + } + + + /** @test */ + public function secondIntBibShouldHaveTwoItems() { + $this->assertEquals(4, Class_Exemplaire::countBy(['id_int_bib' => 2])); + } + + + /** @test */ + public function recordOnFirstIntBibWithId397126ShouldHaveTwoItems() { + $this->assertEquals(2, Class_Exemplaire::countBy(['id_int_bib' => 2, + 'id_origine' => 397126])); + } +} \ No newline at end of file diff --git a/cosmogramme/tests/php/classes/ModelTestCase.php b/cosmogramme/tests/php/classes/ModelTestCase.php index c34a5d3642a..ac4076cfcb6 100644 --- a/cosmogramme/tests/php/classes/ModelTestCase.php +++ b/cosmogramme/tests/php/classes/ModelTestCase.php @@ -39,7 +39,7 @@ abstract class TestFixtures { abstract class ModelTestCase extends PHPUnit_Framework_TestCase { use Storm_Test_THelpers; - protected $_storm_default_to_volatile = false; + protected $_storm_default_to_volatile = true; protected function _buildTableMock($model, $methods) { $table = $this->getMock('Storm_Model_Table'.$model,$methods); diff --git a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php index cc0fc85e4fc..236d240ea66 100644 --- a/cosmogramme/tests/php/classes/NoticeIntegrationTest.php +++ b/cosmogramme/tests/php/classes/NoticeIntegrationTest.php @@ -28,7 +28,8 @@ abstract class NoticeIntegrationTestCase extends ModelTestCase { protected $notice_sgbd, $_mock_sql, - $_insert_increment; + $_insert_increment, + $_sigb = Class_IntBib::COM_PERGAME; public function getProfilDonnees() { @@ -95,19 +96,14 @@ abstract class NoticeIntegrationTestCase extends ModelTestCase { 'unicite_code_barres' => Class_CosmoVar::UNIQ_BARCODE_ONLY, 'champs_sup' => '', 'ean_345' => '']) - ->setListeCache(['nature_docs'=> "1:Collection\r\n2:Dataset\r\n3:Event\r\n4:Image", - 'types_docs' => "0:non identifié\r\n1:livres\r\n2:périodiques\r\n3:disques\r\n4:DVD\r\n5:cédéroms\r\n8:articles cms\r\n9:fils rss\r\n10:sites internet\r\n100:Livre Numérique\r\n101:Diaporamas\r\n102:Type doc\r\n103:OAI\r\n104:Type doc\r\n105:Formation Vodéclic\r\n106:Livres Numériques\r\n107:Vidéos à la demande\r\n108:Tout apprendre\r\n109:Enregistrement audio\r\n110:Numérique Premium"]); - - Class_Notice::beVolatile(); - Class_Exemplaire::beVolatile(); - Class_CodifCentreInteret::beVolatile(); - Class_CodifAuteur::beVolatile(); - Class_CodifMatiere::beVolatile(); - Class_CodifGenre::beVolatile(); - Class_CodifDewey::beVolatile(); - Class_CodifPcdm4::beVolatile(); - Class_Notice_SerialArticles::beVolatile(); - Class_CosmoVar::beVolatile(); + ->setListeCache(['nature_docs'=> "1:Collection\r\n2:Dataset\r\n3:Event\r\n4:Image"]); + + Codif_Langue::getInstance() + ->setCodif(['fre' => ['id_langue' => 'fre', + 'libelle' => 'français']]); + $this->fixture('Class_CodifLangue', + ['id' => 'fre', 'libelle' => 'Français']); + $this->fixture('Class_IntBib', ['id' => 1, @@ -118,12 +114,12 @@ abstract class NoticeIntegrationTestCase extends ModelTestCase { 'dernier_ajout' => '2015-01-01', 'ecart_ajouts' => '0', 'date_mail' => '', - 'sigb' => 1, + 'sigb' => $this->_sigb, 'planif_mode' => 'r', 'comm_sigb' => 0, 'comm_params' => 'N']); - $this->notice_sgbd=new notice_unimarc(); + $this->notice_sgbd = new notice_unimarc(); $this->setupProfilDonnees(); } @@ -133,9 +129,13 @@ abstract class NoticeIntegrationTestCase extends ModelTestCase { } - public function loadNoticeFromString($unimarc) { + public function loadNoticeFromString($unimarc, $id_bib = 1) { $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->setParamsIntegration($id_bib, + 0, + isset($this->_profil_donnees['id_profil']) + ? $this->_profil_donnees['id_profil'] + : 1); $this->_service_runner = $this->mock() ->whenCalled('run') @@ -147,12 +147,14 @@ abstract class NoticeIntegrationTestCase extends ModelTestCase { } - public function loadRecordsFromFile($filename) { + public function loadRecordsFromFile($filename, $id_bib = 1) { $contents = file_get_contents(dirname(__FILE__) . "/" . $filename . '.txt'); - array_map([$this, 'loadNoticeFromString'], + array_map(function($content) use ($id_bib) + { + return $this->loadNoticeFromString($content, $id_bib); + }, preg_split('/'.chr(30).chr(29).'/', $contents)); - } } @@ -160,6 +162,11 @@ abstract class NoticeIntegrationTestCase extends ModelTestCase { class NoticeIntegrationLollipopGeneratedNoticeRecordTest extends NoticeIntegrationTestCase { + public function getProfilDonnees() { + return Class_IntProfilDonnees::forNanook()->getRawAttributes(); + } + + public function setUp() { parent::setUp(); diff --git a/cosmogramme/tests/php/classes/unimarc_mementos.txt b/cosmogramme/tests/php/classes/unimarc_mementos.txt new file mode 100644 index 00000000000..bad45e26359 --- /dev/null +++ b/cosmogramme/tests/php/classes/unimarc_mementos.txt @@ -0,0 +1 @@ +02549cam a2200493 4500001000700000010002000007090001100027099007000038100004100108101000800149102000700157200047900164205001800643210007900661212000900740215002300749225002600772609003300798609003300831609002800864609003300892609002700925609003900952609002200991609003301013610000901046610002601055610001501081610003201096610002001128610002501148610002101173610002601194610002601220611000901246710015301255711011301408711009901521801004801620003004701668461004101715995012301756995017601879397126 a2110879467bbr. a397126 tOUVRAGEyTRAVAILEMPLOIbBiblibre Biblibrec2004-06-16d2019-07-08 a19951204d1995 m h0frey50 ba0 afre aFR1 aMémento de contrôleh11Ciles risques chimiquesbOUVRAGEeréglementationsf[Ministère du travail, de l'emploi et de la formation professionnelle], Direction de l'administration générale et de la modernisation des services, Mission centrale d'appui et de coordination des SDTE ; Institut national du travail, de l'emploi et de la formation professionnelle ; Direction des relations du travail, Sous-direction des conditions de travail, hygiène en milieu de travail CT4 a2e éd., 1995 aPariscDirection des relation du travaild1995e07-AubenasgImpr. Lienhart a1995 a183 p.d21 x 30 cm aMémento de contrôle 938318aInspection du travail 939796aContrôle de l'emploi 937715aProduit chimique 9208621aSubstance dangereuse 937355aRéglementation 939470aProduit phytopharmaceutique 941890aEtiquetage 942250aInstallation classée a1995 aInstallation classée aEtiquetage aProduit phytopharmaceutique aRéglementation aSubstance dangereuse aProduit chimique aContrôle de l'emploi aInspection du travail a1995 312498113aFrancebMission centrale d'appui et de coordination des services déconcentrés du travail, de l'emploi et de la formation professionnelle 311863926aFrancebSous-direction des conditions de travail et de la protection contre les risques du travail 312006950aInstitut national du travail, de l'emploi et de la formation professionnellecFrance 0aFRbFR-751131015c19951204gAFNOR2intermrchttp://catalogue.bnf.fr/ark:/12148/cb35782347w 0034333559tMémento de contrôle.v11 10203052018-07-029351579bINTEFPcINTEFPeINTEFPfINTEFP351579i2018-07-02k0124-03o0rOUVRAGEs012403y2018-07-02 0010203052019-07-089371539bTRAVARAcTRAVARAeTRAVARASfTRAVARA19079136hENSALLEi2019-07-08kDARA VII 12o0qFACTUELrOUVRAGEsDARA_VII_12_000000000000000y2019-07-0802426cam a2200481 4500001000700000010002000007090001100027099008600038100004100124101000800165102000700173200047600180205001800656210007900674212000900753215002300762225002600785609003300811609003300844609002800877609003300905609002700938609003900965609002201004609003301026610000901059610002601068610001501094610003201109610002001141610002501161610002101186610002601207610002601233611000901259710015301268711011301421711009901534801005001633003004701683461004101730995017301771439408 a2110879467bbr. a439408 tOUVRAGEyTRAVAILEMPLOIbBiblibre BiblibreaAngelique BACHc2019-07-08d2019-07-08 a19951204d1988 m||h0frey50 ba0 afre aFR1 aMémento de contrôleh11Ailes risques chimiquesbOUVRAGEeMéthodologief[Ministère du travail, de l'emploi et de la formation professionnelle], Direction de l'administration générale et de la modernisation des services, Mission centrale d'appui et de coordination des SDTE ; Institut national du travail, de l'emploi et de la formation professionnelle ; Direction des relations du travail, Sous-direction des conditions de travail, hygiène en milieu de travail CT4 a2e éd., 1995 aPariscDirection des relation du travaild1988e07-AubenasgImpr. Lienhart a1988 a183 p.d21 x 30 cm aMémento de contrôle 938318aInspection du travail 939796aContrôle de l'emploi 937715aProduit chimique 9208621aSubstance dangereuse 937355aRéglementation 939470aProduit phytopharmaceutique 941890aEtiquetage 942250aInstallation classée a1988 aInstallation classée aEtiquetage aProduit phytopharmaceutique aRéglementation aSubstance dangereuse aProduit chimique aContrôle de l'emploi aInspection du travail a1988 312498113aFrancebMission centrale d'appui et de coordination des services déconcentrés du travail, de l'emploi et de la formation professionnelle 311863926aFrancebSous-direction des conditions de travail et de la protection contre les risques du travail 312006950aInstitut national du travail, de l'emploi et de la formation professionnellecFrance 0aFRbFR-751131015c2019-07-08gAFNOR2intermrchttp://catalogue.bnf.fr/ark:/12148/cb35782347w 0034333559tMémento de contrôle.v11 10203052019-07-089371541bTRAVARAcTRAVARAeTRAVARASfTRAVARA19079137hENSALLEi2019-07-08kDARA VII 12o0qFACTUELrOUVRAGEsDARA_VII_12_000000000000000y2019-07-0802149cam a2200445 4500001000700000010002000007090001100027099008600038100004100124101000800165102000700173200032200180210005700502212000900559215002300568330014400591410003600735609003300771609003300804609002800837609003300865609002700898609003900925609002200964609003300986610000901019610002601028610001501054610003201069610002001101610002501121610002101146610002601167610002601193611000901219710015301228711009901381801005001480995017301530439409 a2110879467bbr. a439409 tOUVRAGEyTRAVAILEMPLOIbBiblibre BiblibreaAngelique BACHc2019-07-08d2019-07-09 a19951204d1988 m||h0frey50 ba0 afre aFR1 aMémento de contrôleh11Biles risques chimiquesbOUVRAGEeNotions de basef[Ministère du travail, de l'emploi et de la formation professionnelle], Direction des relations du travail, Mission centrale d'appui et de coordination des SETE ; Institut national du travail, de l'emploi et de la formation professionnelle aPariscDirection des relation du travaild1988e g a1988 a183 p.d21 x 30 cm aCollection de documents pratiques de synthèse (par profession ou par thème) destinés aux agents de contrôle de l'Inspection du Travail. 950178tMémento de contrôlev 938318aInspection du travail 939796aContrôle de l'emploi 937715aProduit chimique 9208621aSubstance dangereuse 937355aRéglementation 939470aProduit phytopharmaceutique 941890aEtiquetage 942250aInstallation classée a1988 aInstallation classée aEtiquetage aProduit phytopharmaceutique aRéglementation aSubstance dangereuse aProduit chimique aContrôle de l'emploi aInspection du travail a1988 312498113aFrancebMission centrale d'appui et de coordination des services déconcentrés du travail, de l'emploi et de la formation professionnelle 312006950aInstitut national du travail, de l'emploi et de la formation professionnellecFrance 0aFRbFR-751131015c2019-07-09gAFNOR2intermrc 10203052019-07-089371542bTRAVARAcTRAVARAeTRAVARASfTRAVARA19079138hENSALLEi2019-07-08kDARA VII 12o0qFACTUELrOUVRAGEsDARA_VII_12_000000000000000y2019-07-08 \ No newline at end of file diff --git a/library/Class/IntBib.php b/library/Class/IntBib.php index 5b0ca78e9fc..771ef9c772e 100644 --- a/library/Class/IntBib.php +++ b/library/Class/IntBib.php @@ -311,7 +311,9 @@ class Class_IntBib extends Storm_Model_Abstract { public function isPergame() { - return in_array($this->getSigb(), [1, 13]); + return in_array($this->getSigb(), + [static::SIGB_PERGAME, + static::SIGB_NANOOK]); } diff --git a/library/Class/Notice/DoubleFinder.php b/library/Class/Notice/DoubleFinder.php index a50221ac582..fa1c28d72d2 100644 --- a/library/Class/Notice/DoubleFinder.php +++ b/library/Class/Notice/DoubleFinder.php @@ -49,28 +49,30 @@ class Class_Notice_DoubleFinder { protected function _buildStrategy() { - $strategy_name = $this->_strategyName(); + return $this->_strategy = $this->_chooseStrategy(); + } + + + protected function _chooseStrategy() { $library_limit = ($this->_barcode_uniq_mode == Class_CosmoVar::UNIQ_BARCODE_WITHIN_LIBRARY) ? (int) $this->_library->getId() : null; - $this->_strategy = new $strategy_name($library_limit); - } - - - protected function _strategyName() { if ($this->_profil && ($this->_profil->isFormatDublinCore() || $this->_profil->isBibliondemand())) - return 'Class_Notice_DoubleFinder_BarcodeStrategy'; + return new Class_Notice_DoubleFinder_BarcodeStrategy($library_limit); if (($this->_double_mode == Class_CosmoVar::DOUBLE_SEARCH_NONE) && $this->_library->isPergame()) - return 'Class_Notice_DoubleFinder_NoDedupStrategy'; + return new Class_Notice_DoubleFinder_GlobalNoDedupStrategy($library_limit); + + if ($this->_double_mode == Class_CosmoVar::DOUBLE_SEARCH_NONE) + return new Class_Notice_DoubleFinder_NoDedupStrategy($this->_library->getId()); if ($this->_double_mode == Class_CosmoVar::DOUBLE_SEARCH_ALPHA_KEY) - return 'Class_Notice_DoubleFinder_AlphaKeyStrategy'; + return new Class_Notice_DoubleFinder_AlphaKeyStrategy($library_limit); - return 'Class_Notice_DoubleFinder_IdsStrategy'; + return new Class_Notice_DoubleFinder_IdsStrategy($library_limit); } @@ -203,7 +205,7 @@ class Class_Notice_DoubleFinder_BarcodeStrategy extends Class_Notice_DoubleFinde -class Class_Notice_DoubleFinder_NoDedupStrategy extends Class_Notice_DoubleFinder_Strategy { +class Class_Notice_DoubleFinder_GlobalNoDedupStrategy extends Class_Notice_DoubleFinder_Strategy { public function find($data) { $this->_id = null; $this->_data = $data; @@ -250,7 +252,8 @@ class Class_Notice_DoubleFinder_NoDedupStrategy extends Class_Notice_DoubleFinde if ($this->_data->gettype_doc() != $item->getTypeDoc()) return false; - if ($this->_data->getid_origine() != $item->getIdOrigine()) { + if (!empty($this->_data->getid_origine()) + && ($this->_data->getid_origine() != $item->getIdOrigine())) { $item->delete(); return false; } @@ -261,6 +264,7 @@ class Class_Notice_DoubleFinder_NoDedupStrategy extends Class_Notice_DoubleFinde + abstract class Class_Notice_DoubleFinder_KeysStrategy extends Class_Notice_DoubleFinder_Strategy { public function find($data) { $this->_id = null; @@ -327,4 +331,14 @@ class Class_Notice_DoubleFinder_AlphaKeyStrategy extends Class_Notice_DoubleFind protected function _recordAttributes() { return [ ['clef_alpha', $this->_data->getclef_alpha()] ]; } +} + + + + +class Class_Notice_DoubleFinder_NoDedupStrategy extends Class_Notice_DoubleFinder_GlobalNoDedupStrategy { + protected function _findByIdOrigine() { + return $this->_getRecordIdByItem(['id_origine' => $this->_data->getid_origine(), + 'id_int_bib' => $this->_library_limit]); + } } \ No newline at end of file diff --git a/tests/library/Class/Notice/DoubleFinderTest.php b/tests/library/Class/Notice/DoubleFinderTest.php index ffde3b95af5..5d727556eb5 100644 --- a/tests/library/Class/Notice/DoubleFinderTest.php +++ b/tests/library/Class/Notice/DoubleFinderTest.php @@ -133,6 +133,7 @@ abstract class DoubleFinderWithRecordMatchingTestCase extends DoubleFinderTestCa + class DoubleFinderWithExistingItemTest extends DoubleFinderWithRecordMatchingTestCase { protected $_data = ['type_doc' => Class_TypeDoc::LIVRE, 'statut_exemplaires' => ['nb_ex' => 1], @@ -230,6 +231,7 @@ class DoubleFinderWithExistingItemInAnotherLibraryTest extends DoubleFinderTestC + class DoubleFinderWithExistingItemAndNoDedupModeTest extends DoubleFinderWithRecordMatchingTestCase { protected $_data = ['type_doc' => Class_TypeDoc::LIVRE, 'statut_exemplaires' => ['nb_ex' => 1], @@ -252,6 +254,7 @@ class DoubleFinderWithExistingItemAndNoDedupModeTest extends DoubleFinderWithRec + class DoubleFinderWithExistingIdOrigneNoDedupModeDefaultTest extends DoubleFinderTestCase { protected $_data = ['type_doc' => Class_TypeDoc::LIVRE, 'id_origine' => '88903']; -- GitLab