From 2d4603a183b6f634baec01935ccb7034fd51bcb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?ANDRE=20s=C3=A9bastien?= <sandre@afi-sa.fr>
Date: Fri, 21 Jul 2023 14:17:00 +0000
Subject: [PATCH] hotline : #170571 : cosmo import basket with deleted records

---
 VERSIONS_HOTLINE/170571                       |  1 +
 .../Cosmogramme/Integration/PhasePanier.php   | 35 ++++---
 .../Integration/PhasePanierTest.php           | 92 ++++++++++++++++++-
 .../Integration/baskets-deleted-records.txt   |  4 +
 4 files changed, 118 insertions(+), 14 deletions(-)
 create mode 100644 VERSIONS_HOTLINE/170571
 create mode 100644 tests/library/Class/Cosmogramme/Integration/baskets-deleted-records.txt

diff --git a/VERSIONS_HOTLINE/170571 b/VERSIONS_HOTLINE/170571
new file mode 100644
index 00000000000..a8461b284e6
--- /dev/null
+++ b/VERSIONS_HOTLINE/170571
@@ -0,0 +1 @@
+ - correctif #170571 : Cosmogramme : Import de panier avec des notices supprimées, doit aussi les supprimer dans le panier coté Bokeh
\ No newline at end of file
diff --git a/library/Class/Cosmogramme/Integration/PhasePanier.php b/library/Class/Cosmogramme/Integration/PhasePanier.php
index 8ffdadbc7c6..faad65358f2 100644
--- a/library/Class/Cosmogramme/Integration/PhasePanier.php
+++ b/library/Class/Cosmogramme/Integration/PhasePanier.php
@@ -26,14 +26,15 @@ class Class_Cosmogramme_Integration_PhasePanier
   const MY_ID = 15;
 
   protected $_label = 'Intégration des fichiers paniers';
+  protected array $_idsigb_basket = [];
 
   protected function _init($new_phase) {}
 
   protected function _validateProfil($integration) {
-    if (!$profil = $integration->getProfilDonnees())
+    if ( ! $profil = $integration->getProfilDonnees())
       return false;
 
-    if (!$profil->isBaskets())
+    if ( ! $profil->isBaskets())
       return false;
 
     $errors = [];
@@ -77,11 +78,11 @@ class Class_Cosmogramme_Integration_PhasePanier
 
 
   protected function mapRecordColumns($integration, $datas) {
-    if(!$fields = $this->getFields($integration->getProfilDonnees()))
+    if ( ! $fields = $this->getFields($integration->getProfilDonnees()))
       return [];
 
     $map = [];
-    foreach($fields as $k => $name)
+    foreach ($fields as $k => $name)
       $map[strtolower($name)] = isset($datas[$k]) ? $datas[$k] : '';
 
     return $map;
@@ -95,10 +96,10 @@ class Class_Cosmogramme_Integration_PhasePanier
 
 
   protected function importBasketRecord($datas, $integration) {
-    if (!$map = $this->mapRecordColumns($integration, $datas))
+    if ( ! $map = $this->mapRecordColumns($integration, $datas))
       return $this->_log->error($this->_('Pas de donnée trouvée avec le profil de données sélectionné'));
 
-    if (!$map['libelle'])
+    if ( ! $map['libelle'])
       return $this->_log->log($this->_('Ligne non traitée car le libellé n\'a pas pu être lu'));
 
     $id_int_bib = $integration->getIdBib();
@@ -116,13 +117,7 @@ class Class_Cosmogramme_Integration_PhasePanier
 
     $owner = $owners->first();
 
-    $id_sigb = $map['id_sigb'];
-    $basket = Class_PanierNotice::findFirstBy(['id_sigb' => $id_sigb]);
-
-    if ($id_sigb == null || !$basket)
-      $basket = Class_PanierNotice::newForUser($owner);
-
-    $basket
+    $this->_basketByIdSIGB($map, $owner)
       ->setLibelle($map['libelle'])
       ->setIdSigb($map['id_sigb'])
       ->setIdIntBib($id_int_bib)
@@ -134,6 +129,20 @@ class Class_Cosmogramme_Integration_PhasePanier
   }
 
 
+  protected function _basketByIdSIGB(array $map, Class_Users $owner) : Class_PanierNotice {
+    $id_sigb = $map['id_sigb'];
+    if ($basket = ($this->_idsigb_basket[$id_sigb] ?? null))
+      return $basket;
+
+    $this->_idsigb_basket [$id_sigb] =
+      (($id_sigb && ($basket = Class_PanierNotice::findFirstBy(['id_sigb' => $id_sigb])))
+       ? $basket->setNotices('')
+       : Class_PanierNotice::newForUser($owner));
+
+    return $this->_idsigb_basket[$id_sigb];
+  }
+
+
   protected function _getItem(string $id_notice_sigb, int  $id_int_bib) : Class_Exemplaire {
     return ($items = Class_Exemplaire::findAllBy(['id_origine' => $id_notice_sigb]))
       ? $this->_findItem($items, $id_notice_sigb, $id_int_bib)
diff --git a/tests/library/Class/Cosmogramme/Integration/PhasePanierTest.php b/tests/library/Class/Cosmogramme/Integration/PhasePanierTest.php
index be4eba5ca14..a7669472bc9 100644
--- a/tests/library/Class/Cosmogramme/Integration/PhasePanierTest.php
+++ b/tests/library/Class/Cosmogramme/Integration/PhasePanierTest.php
@@ -19,8 +19,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
+
 abstract class PhasePanierTestCase extends Class_Cosmogramme_Integration_PhaseTestCase {
-  protected $_storm_default_to_volatile = true;
 
   protected function _getPreviousPhase() {
     return (new Class_Cosmogramme_Integration_Phase(14))
@@ -69,6 +69,7 @@ abstract class PhasePanierTestCase extends Class_Cosmogramme_Integration_PhaseTe
 
   public function setUp() {
     parent::setUp();
+
     $this->_phase = $this->_buildPhase('Panier')
                          ->setMemoryCleaner(function() {})
                          ->setPrinter($this->_printer)
@@ -80,8 +81,10 @@ abstract class PhasePanierTestCase extends Class_Cosmogramme_Integration_PhaseTe
 
 
 class PhasePanierFullImportWithWrongProfilTest extends PhasePanierTestCase {
+
   protected function _prepareFixtures() {
     parent::_prepareFixtures();
+
     Class_IntProfilDonnees::find(102)
       ->setAttributs([3 => ['champs' => 'LIBELLE']])
       ->save();
@@ -110,6 +113,7 @@ class PhasePanierFullImportWithWrongProfilTest extends PhasePanierTestCase {
 
 
 abstract class PhasePanierKohaTestCase extends PhasePanierTestCase {
+
   protected function _prepareFixtures() {
     parent::_prepareFixtures();
 
@@ -185,6 +189,7 @@ abstract class PhasePanierKohaTestCase extends PhasePanierTestCase {
 
 
 class PhasePanierFullImportWithLinkedToDomainTest extends PhasePanierKohaTestCase {
+
   protected function _prepareFixtures() {
     parent::_prepareFixtures();
 
@@ -202,6 +207,7 @@ class PhasePanierFullImportWithLinkedToDomainTest extends PhasePanierKohaTestCas
                  'libelle' => 'will not be killed due to domain link',
                  'notices' => 'VOL714'])
       ->setDomaineIds(42);
+
     $linked_to_domain_cart->assertSave();
   }
 
@@ -223,6 +229,7 @@ class PhasePanierFullImportWithLinkedToDomainTest extends PhasePanierKohaTestCas
 
 
 class PhasePanierFullImportTest extends PhasePanierKohaTestCase {
+
   /** @test */
   public function newPhaseShouldBe17() {
     $this->assertTrue($this->_phase->isId(15));
@@ -384,6 +391,7 @@ class PhasePanierFullImportTest extends PhasePanierKohaTestCase {
 
 
 class PhasePanierFullImportWithCSVSemicolonTest extends PhasePanierFullImportTest {
+
   protected function _prepareFixtures() {
     parent::_prepareFixtures();
 
@@ -413,8 +421,10 @@ class PhasePanierFullImportWithCSVSemicolonTest extends PhasePanierFullImportTes
 
 
 class PhasePanierFullImportWithCSVPipedTest extends PhasePanierFullImportTest {
+
   protected function _prepareFixtures() {
     parent::_prepareFixtures();
+
     $this->fixture(Class_IntProfilDonnees::class,
                    ['id' => 104,
                     'libelle' => 'Koha Baskets',
@@ -441,8 +451,10 @@ class PhasePanierFullImportWithCSVPipedTest extends PhasePanierFullImportTest {
 
 
 class PhasePanierPartialImportTest extends PhasePanierKohaTestCase {
+
   protected function _prepareFixtures() {
     parent::_prepareFixtures();
+
     Class_Cosmogramme_Integration::find(999)->beIncrementImport()->save();
   }
 
@@ -460,6 +472,7 @@ class PhasePanierPartialImportTest extends PhasePanierKohaTestCase {
 
 
 abstract class PhasePanierNanookTestCase extends PhasePanierTestCase {
+
   protected $_basket;
 
   protected function _prepareFixtures() {
@@ -495,6 +508,7 @@ abstract class PhasePanierNanookTestCase extends PhasePanierTestCase {
 
 /** @see http://forge.afi-sa.fr/issues/33712 */
 class PhasePanierNanookTest extends PhasePanierNanookTestCase {
+
   protected $_basket;
 
   protected function _prepareFixtures() {
@@ -513,6 +527,7 @@ class PhasePanierNanookTest extends PhasePanierNanookTestCase {
 
   public function setUp() {
     parent::setUp();
+
     $this->_basket = Class_PanierNotice::findFirstBy([]);
   }
 
@@ -552,6 +567,7 @@ class PhasePanierNanookTest extends PhasePanierNanookTestCase {
 
 /** @see http://forge.afi-sa.fr/issues/163609 */
 class PhasePanierNanookWithGhostItemsTest extends PhasePanierNanookTestCase {
+
   protected $_basket;
 
   protected function _prepareFixtures() {
@@ -598,3 +614,77 @@ class PhasePanierNanookWithGhostItemsTest extends PhasePanierNanookTestCase {
     $this->assertContains('BOB MORANE AVENTURIER',Class_PanierNotice::findFirstBy(['id_sigb' => 509])->getNotices());
   }
 }
+
+
+
+
+/* @see https://forge.afi-sa.net/issues/170571 */
+class PhasePanierFullImportWithDeletedRecordsTest extends PhasePanierTestCase {
+
+  protected function _prepareFixtures() {
+    parent::_prepareFixtures();
+
+    $this->fixture(Class_PanierNotice::class,
+                   ['id' => 111,
+                    'id_sigb' => 23,
+                    'id_int_bib' => 2,
+                    'libelle' => 'Zoom Cuba',
+                    'notices' => 'ALPHAKEY-1;ALPHAKEY-2;ALPHAKEY-3;ALPHAKEY-4']);
+
+    $this->fixture(Class_Notice::class,
+                   ['id' => 222,
+                    'type_doc' => 1,
+                    'clef_alpha' => 'ALPHAKEY-1',
+                    'exemplaires' => [$this->fixture(Class_Exemplaire::class,
+                                                     ['id' => 333,
+                                                      'id_int_bib' => 2,
+                                                      'id_origine' => 44444])]]);
+    $this->fixture(Class_Notice::class,
+                   ['id' => 223,
+                    'type_doc' => 1,
+                    'clef_alpha' => 'ALPHAKEY-2',
+                    'exemplaires' => [$this->fixture(Class_Exemplaire::class,
+                                                     ['id' => 334,
+                                                      'id_int_bib' => 2,
+                                                      'id_origine' => 44445])]]);
+    $this->fixture(Class_Notice::class,
+                   ['id' => 224,
+                    'type_doc' => 1,
+                    'clef_alpha' => 'ALPHAKEY-3',
+                    'exemplaires' => [$this->fixture(Class_Exemplaire::class,
+                                                     ['id' => 335,
+                                                      'id_int_bib' => 2,
+                                                      'id_origine' => 44446])]]);
+    $this->fixture(Class_Notice::class,
+                   ['id' => 225,
+                    'type_doc' => 1,
+                    'clef_alpha' => 'ALPHAKEY-4',
+                    'exemplaires' => [$this->fixture(Class_Exemplaire::class,
+                                                     ['id' => 336,
+                                                      'id_int_bib' => 2,
+                                                      'id_origine' => 44447])]]);
+
+    Class_Cosmogramme_Integration::find(999)
+      ->setFichier('baskets-deleted-records.txt')
+      ->setProfilDonnees(Class_IntProfilDonnees::find(102))
+      ->save();
+  }
+
+
+  /** @test */
+  public function noticesAlphaKeyShouldBeUpdatedWith2Records() {
+    $this->assertEquals('ALPHAKEY-1;ALPHAKEY-2', Class_PanierNotice::find(111)->getNotices());
+  }
+
+
+  /** @test */
+  public function noticeId224ShouldNotHaveBeenDeleted() {
+    $this->assertNotNull(Class_Notice::find(224));
+  }
+
+
+  /** @test */
+  public function noticeId225ShouldNotHaveBeenDeleted() {
+    $this->assertNotNull(Class_Notice::find(225));
+  }
+}
diff --git a/tests/library/Class/Cosmogramme/Integration/baskets-deleted-records.txt b/tests/library/Class/Cosmogramme/Integration/baskets-deleted-records.txt
new file mode 100644
index 00000000000..db9a2dd4d68
--- /dev/null
+++ b/tests/library/Class/Cosmogramme/Integration/baskets-deleted-records.txt
@@ -0,0 +1,4 @@
+23,Zomm Cuba,,email@mail.com,1,44444
+23,Zomm Cuba,,email@mail.com,1,44445
+
+
-- 
GitLab