From 8c0de6d29c7c7da7589652f0a44b1331f37853a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Guillop=C3=A9?= Date: Wed, 26 Feb 2025 10:59:54 +0100 Subject: [PATCH 1/7] feat: add a "tourName" property in deliveries import --- app/config/services.yml | 2 ++ src/Entity/TourRepository.php | 27 +++++++++++++-- src/Spreadsheet/DeliverySpreadsheetParser.php | 33 +++++++++++++++++-- .../spreadsheet/deliveries_with_tour.csv | 3 ++ .../DeliverySpreadsheetParserTest.php | 33 +++++++++++++++---- 5 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 tests/AppBundle/Resources/spreadsheet/deliveries_with_tour.csv diff --git a/app/config/services.yml b/app/config/services.yml index f77b8a7c90..f909dd0758 100755 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -643,6 +643,8 @@ services: AppBundle\Entity\TaskListRepository: ~ + AppBundle\Entity\TourRepository: ~ + AppBundle\Entity\Task\RecurrenceRuleRepository: ~ AppBundle\Service\Routing\Osrm: ~ diff --git a/src/Entity/TourRepository.php b/src/Entity/TourRepository.php index 37f78f636c..8f2179b827 100644 --- a/src/Entity/TourRepository.php +++ b/src/Entity/TourRepository.php @@ -4,12 +4,22 @@ use AppBundle\Entity\Task; use AppBundle\Entity\TaskCollectionItem; -use Doctrine\ORM\EntityRepository; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Query\Expr; +use Doctrine\Persistence\ManagerRegistry; -class TourRepository extends EntityRepository +class TourRepository extends ServiceEntityRepository { - public function findOneByTask(Task $task) + public function __construct( + private readonly EntityManagerInterface $entityManager, + ManagerRegistry $registry + ) + { + parent::__construct($registry, Tour::class); + } + + public function findOneByTask(Task $task): ?Tour { return $this->createQueryBuilder('to') ->join(TaskCollectionItem::class, 'tci', Expr\Join::WITH, 'tci.parent = to.id') @@ -18,4 +28,15 @@ public function findOneByTask(Task $task) ->getQuery() ->getOneOrNullResult(); } + + public function findByNameAndDate(string $name, \DateTime $date): ?Tour + { + return $this->createQueryBuilder('to') + ->where('to.name = :name') + ->andWhere('to.date = :date') + ->setParameter('name', $name) + ->setParameter('date', $date) + ->getQuery() + ->getOneOrNullResult(); + } } diff --git a/src/Spreadsheet/DeliverySpreadsheetParser.php b/src/Spreadsheet/DeliverySpreadsheetParser.php index bc8d9dde65..01df6e3d1d 100644 --- a/src/Spreadsheet/DeliverySpreadsheetParser.php +++ b/src/Spreadsheet/DeliverySpreadsheetParser.php @@ -8,6 +8,8 @@ use AppBundle\Entity\Delivery; use AppBundle\Entity\Tag; use AppBundle\Entity\Task; +use AppBundle\Entity\Tour; +use AppBundle\Entity\TourRepository; use AppBundle\Exception\DateTimeParseException; use AppBundle\Service\Geocoder; use AppBundle\Service\SettingsManager; @@ -32,7 +34,8 @@ public function __construct( private EntityManagerInterface $entityManager, private SlugifyInterface $slugify, private TranslatorInterface $translator, - private SettingsManager $settingsManager + private SettingsManager $settingsManager, + private TourRepository $tourRepository ) { } @@ -147,6 +150,10 @@ public function parseData(array $data, array $options = []): SpreadsheetParseRes $this->applyTags($delivery->getDropoff(), $record['dropoff.tags']); } + if (isset($record['tourName']) && !empty($record['tourName'])) { + $this->setTour($delivery, $record['tourName']); + } + if (!$parseResult->rowHasErrors($rowNumber)) { $parseResult->addData($rowNumber, $delivery); } @@ -241,6 +248,24 @@ private function applyTags(TaggableInterface $task, $tagsAsString) } } + private function setTour(Delivery $delivery, string $routeName) { + foreach ($delivery->getTasks() as $task) { + + $date = $task->getAfter(); + $tour = $this->tourRepository->findByNameAndDate($routeName, $date); + + if (is_null($tour)) { + $tour = new Tour(); + $tour->setName($routeName); + $tour->setDate($date); + $this->entityManager->persist($tour); + $this->entityManager->flush(); + } + + $tour->addTask($task); + } + } + public function getExampleData(): array { return [ @@ -262,7 +287,8 @@ public function getExampleData(): array 'dropoff.packages' => 'small-box=1 big-box=2', 'dropoff.tags' => 'warn heavy', 'dropoff.metadata' => 'external_system_id=10', - 'weight' => '5.5' + 'weight' => '5.5', + 'tourName' => 'my tour name' ], [ 'pickup.address' => '24 rue de rivoli paris', @@ -280,7 +306,8 @@ public function getExampleData(): array 'dropoff.timeslot' => '2019-12-12 12:00 - 2019-12-12 13:00', 'dropoff.packages' => 'small-box=1 big-box=2', 'dropoff.tags' => 'warn', - 'weight' => '8.0' + 'weight' => '8.0', + 'tourName' => 'another tour name' ], ]; } diff --git a/tests/AppBundle/Resources/spreadsheet/deliveries_with_tour.csv b/tests/AppBundle/Resources/spreadsheet/deliveries_with_tour.csv new file mode 100644 index 0000000000..42af74f320 --- /dev/null +++ b/tests/AppBundle/Resources/spreadsheet/deliveries_with_tour.csv @@ -0,0 +1,3 @@ +pickup.address,pickup.address.name,pickup.address.description,pickup.address.telephone,pickup.comments,pickup.timeslot,dropoff.address,dropoff.address.name,dropoff.address.description,dropoff.address.telephone,dropoff.comments,dropoff.timeslot,dropoff.packages,weight,pickup.metadata,dropoff.metadata,tourName +"Via Pippo Spano 17, 50129, Firenze",,,,,16/01/2024 09:00 - 16/01/2024 18:00,"Via Pippo Spano 17, 50129, Firenze",,,, ,16/01/2024 09:00 - 16/01/2024 18:00,,,blu=bla foo=fly,foo=bar,test route +"Via Pippo Spano 17, 50129, Firenze",,,,,16/01/2024 09:00 - 16/01/2024 18:00,"Via Pippo Spano 17, 50129, Firenze",,,, ,16/01/2024 09:00 - 16/01/2024 18:00,,,blu=bla foo=fly,foo=bar,test route \ No newline at end of file diff --git a/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php b/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php index 870cc925a2..ecac4cd3aa 100644 --- a/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php +++ b/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php @@ -6,12 +6,14 @@ use AppBundle\Entity\Delivery; use AppBundle\Entity\Base\GeoCoordinates; use AppBundle\Entity\Package; +use AppBundle\Entity\TourRepository; use AppBundle\Service\Geocoder; use AppBundle\Service\SettingsManager; use AppBundle\Spreadsheet\AbstractSpreadsheetParser; use AppBundle\Spreadsheet\DeliverySpreadsheetParser; use Cocur\Slugify\SlugifyInterface; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Mapping\Entity; use Doctrine\Persistence\ObjectRepository; use Exception; use Prophecy\Argument; @@ -21,9 +23,13 @@ class DeliverySpreadsheetParserTest extends TestCase { + protected $settingManager; + protected $geocoder; + protected $tourRepository; + protected function createParser(): AbstractSpreadsheetParser { - $this->entityManager = $this->prophesize(EntityManagerInterface::class); + $this->entityManager = self::getContainer()->get(EntityManagerInterface::class); $this->slugify = $this->prophesize(SlugifyInterface::class); $this->settingManager = $this->prophesize(SettingsManager::class); @@ -56,18 +62,17 @@ protected function createParser(): AbstractSpreadsheetParser $this->packageRepository = $this->prophesize(ObjectRepository::class); - $this->entityManager - ->getRepository(Package::class) - ->willReturn($this->packageRepository->reveal()); + $this->tourRepository = self::getContainer()->get(TourRepository::class); return new DeliverySpreadsheetParser( $this->geocoder->reveal(), PhoneNumberUtil::getInstance(), 'fr', - $this->entityManager->reveal(), + $this->entityManager, $this->slugify->reveal(), $this->translator, - $this->settingManager->reveal() + $this->settingManager->reveal(), + $this->tourRepository ); } @@ -158,4 +163,20 @@ public function testWithMetadata() $this->assertEquals($delivery->getPickup()->getMetadata()['blu'], 'bla'); $this->assertEquals($delivery->getDropoff()->getMetadata()['foo'], 'bar'); } + + public function testWithTour() + { + $filename = realpath(__DIR__ . '/../Resources/spreadsheet/deliveries_with_tour.csv'); + + $parseResult = $this->parser->parse($filename); + $data = $parseResult->getData(); + + $tour = $this->tourRepository->findByNameAndDate('test route', new \DateTime('2024-01-16')); + $this->assertNotNull($tour); + $this->assertEquals(count($tour->getTasks()), 4); + + /** @var Delivery */ + $delivery = array_shift($data); + $this->assertEquals($delivery->getPickup(), $tour->getTasks()[0]); + } } From 867c6df1519dbf61c8e47aa20c838f14803fb11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Guillop=C3=A9?= Date: Thu, 27 Feb 2025 10:01:26 +0100 Subject: [PATCH 2/7] clean: remove unused arg --- src/Entity/TourRepository.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Entity/TourRepository.php b/src/Entity/TourRepository.php index 8f2179b827..df8eda9561 100644 --- a/src/Entity/TourRepository.php +++ b/src/Entity/TourRepository.php @@ -12,7 +12,6 @@ class TourRepository extends ServiceEntityRepository { public function __construct( - private readonly EntityManagerInterface $entityManager, ManagerRegistry $registry ) { From 0cc26499c204de75acc0b268484396e704e666aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Guillop=C3=A9?= Date: Tue, 4 Mar 2025 09:44:57 +0100 Subject: [PATCH 3/7] clean: change CSV field name --- src/Spreadsheet/DeliverySpreadsheetParser.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Spreadsheet/DeliverySpreadsheetParser.php b/src/Spreadsheet/DeliverySpreadsheetParser.php index 01df6e3d1d..4104d6f04a 100644 --- a/src/Spreadsheet/DeliverySpreadsheetParser.php +++ b/src/Spreadsheet/DeliverySpreadsheetParser.php @@ -150,8 +150,8 @@ public function parseData(array $data, array $options = []): SpreadsheetParseRes $this->applyTags($delivery->getDropoff(), $record['dropoff.tags']); } - if (isset($record['tourName']) && !empty($record['tourName'])) { - $this->setTour($delivery, $record['tourName']); + if (isset($record['tour.name']) && !empty($record['tour.name'])) { + $this->setTour($delivery, $record['tour.name']); } if (!$parseResult->rowHasErrors($rowNumber)) { @@ -288,7 +288,7 @@ public function getExampleData(): array 'dropoff.tags' => 'warn heavy', 'dropoff.metadata' => 'external_system_id=10', 'weight' => '5.5', - 'tourName' => 'my tour name' + 'tour.name' => 'my tour name' ], [ 'pickup.address' => '24 rue de rivoli paris', @@ -307,7 +307,7 @@ public function getExampleData(): array 'dropoff.packages' => 'small-box=1 big-box=2', 'dropoff.tags' => 'warn', 'weight' => '8.0', - 'tourName' => 'another tour name' + 'tour.name' => 'another tour name' ], ]; } From c8d54d5053bb096e8d46333361788173b68f6b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Guillop=C3=A9?= Date: Tue, 4 Mar 2025 11:13:29 +0100 Subject: [PATCH 4/7] fix: flush tour outside of parser --- src/Entity/Delivery.php | 17 +++++++++++ .../ImportDeliveriesHandler.php | 24 +++++++++++++++- src/Spreadsheet/DeliverySpreadsheetParser.php | 28 ++----------------- src/Spreadsheet/SpreadsheetParseResult.php | 2 +- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/Entity/Delivery.php b/src/Entity/Delivery.php index 0822fc6484..ab434d2f62 100644 --- a/src/Entity/Delivery.php +++ b/src/Entity/Delivery.php @@ -170,6 +170,11 @@ class Delivery extends TaskCollection implements TaskCollectionInterface, Packag */ private $arbitraryPrice; + /** + * @var string + */ + private $tourName; + const OPENAPI_CONTEXT_POST_PARAMETERS = [[ "name" => "delivery", "in" => "body", @@ -664,4 +669,16 @@ public function setArbitraryPrice(ArbitraryPrice $arbitraryPrice): self return $this; } + + public function getTourName(): ?string + { + return $this->tourName; + } + + public function setTourName(string $tourName): self + { + $this->tourName = $tourName; + + return $this; + } } diff --git a/src/MessageHandler/ImportDeliveriesHandler.php b/src/MessageHandler/ImportDeliveriesHandler.php index 35d13933e9..6510e6ecde 100644 --- a/src/MessageHandler/ImportDeliveriesHandler.php +++ b/src/MessageHandler/ImportDeliveriesHandler.php @@ -6,6 +6,8 @@ use AppBundle\Entity\Store; use AppBundle\Entity\Delivery\ImportQueue as DeliveryImportQueue; use AppBundle\Entity\Sylius\UsePricingRules; +use AppBundle\Entity\Tour; +use AppBundle\Entity\TourRepository; use AppBundle\Exception\Pricing\NoRuleMatchedException; use AppBundle\Message\ImportDeliveries; use AppBundle\Pricing\PricingManager; @@ -32,7 +34,9 @@ public function __construct( private PricingManager $pricingManager, private LiveUpdates $liveUpdates, private DeliveryManager $deliveryManager, - private LoggerInterface $logger) + private LoggerInterface $logger, + private TourRepository $tourRepository + ) { } @@ -95,6 +99,24 @@ public function __invoke(ImportDeliveries $message) $errorMessage = $this->translator->trans('delivery.price.error.priceCalculation', [], 'validators'); $result->addErrorToRow($rowNumber, $errorMessage); } + + if ($delivery->getTourName()) { + foreach ($delivery->getTasks() as $task) { + $tourName = $delivery->getTourName(); + $date = $task->getAfter(); + $tour = $this->tourRepository->findByNameAndDate($tourName, $date); + + if (is_null($tour)) { + $tour = new Tour(); + $tour->setName($tourName); + $tour->setDate($date); + $this->entityManager->persist($tour); + $this->entityManager->flush(); + } + + $tour->addTask($task); + } + } } $this->entityManager->flush(); diff --git a/src/Spreadsheet/DeliverySpreadsheetParser.php b/src/Spreadsheet/DeliverySpreadsheetParser.php index 4104d6f04a..b8d9a0c94c 100644 --- a/src/Spreadsheet/DeliverySpreadsheetParser.php +++ b/src/Spreadsheet/DeliverySpreadsheetParser.php @@ -8,8 +8,6 @@ use AppBundle\Entity\Delivery; use AppBundle\Entity\Tag; use AppBundle\Entity\Task; -use AppBundle\Entity\Tour; -use AppBundle\Entity\TourRepository; use AppBundle\Exception\DateTimeParseException; use AppBundle\Service\Geocoder; use AppBundle\Service\SettingsManager; @@ -34,10 +32,8 @@ public function __construct( private EntityManagerInterface $entityManager, private SlugifyInterface $slugify, private TranslatorInterface $translator, - private SettingsManager $settingsManager, - private TourRepository $tourRepository - ) - { } + private SettingsManager $settingsManager + ) {} /** * @inheritdoc @@ -151,7 +147,7 @@ public function parseData(array $data, array $options = []): SpreadsheetParseRes } if (isset($record['tour.name']) && !empty($record['tour.name'])) { - $this->setTour($delivery, $record['tour.name']); + $delivery->setTourName($record['tour.name']); } if (!$parseResult->rowHasErrors($rowNumber)) { @@ -248,24 +244,6 @@ private function applyTags(TaggableInterface $task, $tagsAsString) } } - private function setTour(Delivery $delivery, string $routeName) { - foreach ($delivery->getTasks() as $task) { - - $date = $task->getAfter(); - $tour = $this->tourRepository->findByNameAndDate($routeName, $date); - - if (is_null($tour)) { - $tour = new Tour(); - $tour->setName($routeName); - $tour->setDate($date); - $this->entityManager->persist($tour); - $this->entityManager->flush(); - } - - $tour->addTask($task); - } - } - public function getExampleData(): array { return [ diff --git a/src/Spreadsheet/SpreadsheetParseResult.php b/src/Spreadsheet/SpreadsheetParseResult.php index b83d829b30..9d916b1899 100644 --- a/src/Spreadsheet/SpreadsheetParseResult.php +++ b/src/Spreadsheet/SpreadsheetParseResult.php @@ -5,7 +5,7 @@ /** * A class to keep the relation between a row from a file * and the entity that is created or the errors that occurs - * when the import and parse of that fail happens. + * during parsing. */ class SpreadsheetParseResult { From 9eecd68fdb91f5e75795ee0c3ee03929bc50d8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Guillop=C3=A9?= Date: Tue, 4 Mar 2025 11:33:18 +0100 Subject: [PATCH 5/7] fix: tests --- .../spreadsheet/deliveries_with_tour.csv | 2 +- .../DeliverySpreadsheetParserTest.php | 21 ++++++------------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/tests/AppBundle/Resources/spreadsheet/deliveries_with_tour.csv b/tests/AppBundle/Resources/spreadsheet/deliveries_with_tour.csv index 42af74f320..40ff72b16b 100644 --- a/tests/AppBundle/Resources/spreadsheet/deliveries_with_tour.csv +++ b/tests/AppBundle/Resources/spreadsheet/deliveries_with_tour.csv @@ -1,3 +1,3 @@ -pickup.address,pickup.address.name,pickup.address.description,pickup.address.telephone,pickup.comments,pickup.timeslot,dropoff.address,dropoff.address.name,dropoff.address.description,dropoff.address.telephone,dropoff.comments,dropoff.timeslot,dropoff.packages,weight,pickup.metadata,dropoff.metadata,tourName +pickup.address,pickup.address.name,pickup.address.description,pickup.address.telephone,pickup.comments,pickup.timeslot,dropoff.address,dropoff.address.name,dropoff.address.description,dropoff.address.telephone,dropoff.comments,dropoff.timeslot,dropoff.packages,weight,pickup.metadata,dropoff.metadata,tour.name "Via Pippo Spano 17, 50129, Firenze",,,,,16/01/2024 09:00 - 16/01/2024 18:00,"Via Pippo Spano 17, 50129, Firenze",,,, ,16/01/2024 09:00 - 16/01/2024 18:00,,,blu=bla foo=fly,foo=bar,test route "Via Pippo Spano 17, 50129, Firenze",,,,,16/01/2024 09:00 - 16/01/2024 18:00,"Via Pippo Spano 17, 50129, Firenze",,,, ,16/01/2024 09:00 - 16/01/2024 18:00,,,blu=bla foo=fly,foo=bar,test route \ No newline at end of file diff --git a/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php b/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php index ecac4cd3aa..55b9479cec 100644 --- a/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php +++ b/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php @@ -6,30 +6,26 @@ use AppBundle\Entity\Delivery; use AppBundle\Entity\Base\GeoCoordinates; use AppBundle\Entity\Package; -use AppBundle\Entity\TourRepository; use AppBundle\Service\Geocoder; use AppBundle\Service\SettingsManager; use AppBundle\Spreadsheet\AbstractSpreadsheetParser; use AppBundle\Spreadsheet\DeliverySpreadsheetParser; use Cocur\Slugify\SlugifyInterface; -use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\EntityManager; use Doctrine\Persistence\ObjectRepository; use Exception; use Prophecy\Argument; use libphonenumber\PhoneNumberUtil; -use Symfony\Contracts\Translation\TranslatorInterface; use TypeError; class DeliverySpreadsheetParserTest extends TestCase { protected $settingManager; protected $geocoder; - protected $tourRepository; protected function createParser(): AbstractSpreadsheetParser { - $this->entityManager = self::getContainer()->get(EntityManagerInterface::class); + $this->entityManager = $this->prophesize(EntityManager::class); $this->slugify = $this->prophesize(SlugifyInterface::class); $this->settingManager = $this->prophesize(SettingsManager::class); @@ -62,17 +58,16 @@ protected function createParser(): AbstractSpreadsheetParser $this->packageRepository = $this->prophesize(ObjectRepository::class); - $this->tourRepository = self::getContainer()->get(TourRepository::class); + $this->entityManager->getRepository(Package::class)->willReturn($this->packageRepository->reveal()); return new DeliverySpreadsheetParser( $this->geocoder->reveal(), PhoneNumberUtil::getInstance(), 'fr', - $this->entityManager, + $this->entityManager->reveal(), $this->slugify->reveal(), $this->translator, - $this->settingManager->reveal(), - $this->tourRepository + $this->settingManager->reveal() ); } @@ -171,12 +166,8 @@ public function testWithTour() $parseResult = $this->parser->parse($filename); $data = $parseResult->getData(); - $tour = $this->tourRepository->findByNameAndDate('test route', new \DateTime('2024-01-16')); - $this->assertNotNull($tour); - $this->assertEquals(count($tour->getTasks()), 4); - /** @var Delivery */ $delivery = array_shift($data); - $this->assertEquals($delivery->getPickup(), $tour->getTasks()[0]); + $this->assertEquals($delivery->getTourName(), 'test route'); } } From 3fe163202c23f348f32c1fb8233b1660e8f36321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Guillop=C3=A9?= Date: Tue, 4 Mar 2025 11:45:41 +0100 Subject: [PATCH 6/7] feat: do not auto-assign tasks if they are part of a tour --- .../EventSubscriber/TaskSubscriber/TaskListProvider.php | 2 +- src/Entity/Listener/DeliveryListener.php | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Doctrine/EventSubscriber/TaskSubscriber/TaskListProvider.php b/src/Doctrine/EventSubscriber/TaskSubscriber/TaskListProvider.php index 5c5a4c7f13..2082a3cc76 100644 --- a/src/Doctrine/EventSubscriber/TaskSubscriber/TaskListProvider.php +++ b/src/Doctrine/EventSubscriber/TaskSubscriber/TaskListProvider.php @@ -17,7 +17,7 @@ public function __construct(EntityManagerInterface $objectManager) $this->objectManager = $objectManager; } - public function getTaskList(Task $task, UserInterface $courier) + public function getTaskList(Task $task, UserInterface $courier) : TaskList { // FIXME // 1. if task->assignedOn is set, we have explictly set the assignment date -> good, we get the proper TaskList diff --git a/src/Entity/Listener/DeliveryListener.php b/src/Entity/Listener/DeliveryListener.php index 145e10a70a..3034e9a578 100644 --- a/src/Entity/Listener/DeliveryListener.php +++ b/src/Entity/Listener/DeliveryListener.php @@ -6,6 +6,7 @@ use AppBundle\Entity\Delivery; use AppBundle\Entity\Task; use AppBundle\Entity\TaskList\Item; +use AppBundle\Entity\TourRepository; use Doctrine\ORM\EntityManagerInterface; use Doctrine\Persistence\Event\LifecycleEventArgs; @@ -13,7 +14,8 @@ class DeliveryListener { public function __construct( protected EntityManagerInterface $entityManager, - protected TaskListProvider $taskListProvider + protected TaskListProvider $taskListProvider, + protected TourRepository $tourRepository ) { @@ -69,6 +71,11 @@ public function postPersist(Delivery $delivery) $courier = $delivery->getStore()->getDefaultCourier(); foreach ($delivery->getTasks() as $task) { + // Ignore tasks that are part of a tour, that is the tour itself that should be assigned + if ($this->tourRepository->findOneByTask($task)) { + continue; + } + $taskList = $this->taskListProvider->getTaskList($task, $courier); $taskList->appendTask($task); } From 261f85e9942dd5a688a9529978dbc252b8598a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alo=C3=AFs=20Guillop=C3=A9?= Date: Thu, 6 Mar 2025 10:53:46 +0100 Subject: [PATCH 7/7] clean: do no set tourName on delivery entity --- src/Entity/Delivery.php | 17 ----------------- src/MessageHandler/ImportDeliveriesHandler.php | 8 +++++--- src/Spreadsheet/DeliverySpreadsheetParser.php | 9 +++++---- .../DeliverySpreadsheetParserTest.php | 12 ++++++------ 4 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/Entity/Delivery.php b/src/Entity/Delivery.php index ab434d2f62..0822fc6484 100644 --- a/src/Entity/Delivery.php +++ b/src/Entity/Delivery.php @@ -170,11 +170,6 @@ class Delivery extends TaskCollection implements TaskCollectionInterface, Packag */ private $arbitraryPrice; - /** - * @var string - */ - private $tourName; - const OPENAPI_CONTEXT_POST_PARAMETERS = [[ "name" => "delivery", "in" => "body", @@ -669,16 +664,4 @@ public function setArbitraryPrice(ArbitraryPrice $arbitraryPrice): self return $this; } - - public function getTourName(): ?string - { - return $this->tourName; - } - - public function setTourName(string $tourName): self - { - $this->tourName = $tourName; - - return $this; - } } diff --git a/src/MessageHandler/ImportDeliveriesHandler.php b/src/MessageHandler/ImportDeliveriesHandler.php index 6510e6ecde..271ced9501 100644 --- a/src/MessageHandler/ImportDeliveriesHandler.php +++ b/src/MessageHandler/ImportDeliveriesHandler.php @@ -69,7 +69,9 @@ public function __invoke(ImportDeliveries $message) $result = $this->spreadsheetParser->parse($tempnam, $message->getOptions()); - foreach ($result->getData() as $rowNumber => $delivery) { + foreach ($result->getData() as $rowNumber => $deliveryImportData) { + + $delivery = $deliveryImportData['delivery']; // Validate data $violations = $this->validator->validate($delivery); @@ -100,9 +102,9 @@ public function __invoke(ImportDeliveries $message) $result->addErrorToRow($rowNumber, $errorMessage); } - if ($delivery->getTourName()) { + if ($deliveryImportData['tourName']) { foreach ($delivery->getTasks() as $task) { - $tourName = $delivery->getTourName(); + $tourName = $deliveryImportData['tourName']; $date = $task->getAfter(); $tour = $this->tourRepository->findByNameAndDate($tourName, $date); diff --git a/src/Spreadsheet/DeliverySpreadsheetParser.php b/src/Spreadsheet/DeliverySpreadsheetParser.php index b8d9a0c94c..dda511b8b9 100644 --- a/src/Spreadsheet/DeliverySpreadsheetParser.php +++ b/src/Spreadsheet/DeliverySpreadsheetParser.php @@ -146,12 +146,13 @@ public function parseData(array $data, array $options = []): SpreadsheetParseRes $this->applyTags($delivery->getDropoff(), $record['dropoff.tags']); } - if (isset($record['tour.name']) && !empty($record['tour.name'])) { - $delivery->setTourName($record['tour.name']); - } + $tourName = isset($record['tour.name']) && !empty($record['tour.name']) ? $record['tour.name'] : null; if (!$parseResult->rowHasErrors($rowNumber)) { - $parseResult->addData($rowNumber, $delivery); + $parseResult->addData( + $rowNumber, + ['delivery' => $delivery, 'tourName' => $tourName] + ); } } diff --git a/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php b/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php index 55b9479cec..e158809edd 100644 --- a/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php +++ b/tests/AppBundle/Spreadsheet/DeliverySpreadsheetParserTest.php @@ -80,7 +80,7 @@ public function testCsvWithEmptyLines() $this->geocoder->geocode(null)->shouldNotBeCalled(); // not called with empty lines /** @var Delivery */ - $delivery = array_shift($data); + $delivery = array_shift($data)['delivery']; $this->assertEquals($delivery->getPickup()->getAddress()->getStreetAddress(), 'street address'); $this->assertEquals($delivery->getDropoff()->getAddress()->getStreetAddress(), 'street address'); @@ -93,7 +93,7 @@ public function testWithInvalidPickupAddressWithCreateFlag() $data = $parseResult->getData(); /** @var Delivery */ - $delivery = array_shift($data); + $delivery = array_shift($data)['delivery']; $this->assertEquals($delivery->getPickup()->getAddress()->getStreetAddress(), 'INVALID ADDRESS'); $this->assertEquals($delivery->getPickup()->getAddress()->getGeo()->getLatitude(), 48.8534); $this->assertEquals($delivery->getPickup()->getAddress()->getGeo()->getLongitude(), 2.3488); @@ -124,7 +124,7 @@ public function testWithAddressThatThrowsAndCreateDeliveryAnyway() $data = $parseResult->getData(); /** @var Delivery */ - $delivery = array_shift($data); + $delivery = array_shift($data)['delivery']; $this->assertEquals($delivery->getDropoff()->getAddress()->getGeo()->getLatitude(), 48.8534); $this->assertEquals($delivery->getDropoff()->getAddress()->getGeo()->getLongitude(), 2.3488); @@ -153,7 +153,7 @@ public function testWithMetadata() $data = $parseResult->getData(); /** @var Delivery */ - $delivery = array_shift($data); + $delivery = array_shift($data)['delivery']; $this->assertEquals($delivery->getPickup()->getMetadata()['foo'], 'fly'); $this->assertEquals($delivery->getPickup()->getMetadata()['blu'], 'bla'); $this->assertEquals($delivery->getDropoff()->getMetadata()['foo'], 'bar'); @@ -167,7 +167,7 @@ public function testWithTour() $data = $parseResult->getData(); /** @var Delivery */ - $delivery = array_shift($data); - $this->assertEquals($delivery->getTourName(), 'test route'); + $result = array_shift($data); + $this->assertEquals($result['tourName'], 'test route'); } }