Skip to content

Commit

Permalink
[PAP] improve building stats rows
Browse files Browse the repository at this point in the history
  • Loading branch information
ottaviano committed May 17, 2024
1 parent c4d32ba commit 91ec81c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 55 deletions.
2 changes: 1 addition & 1 deletion src/Controller/Api/Pap/BuildingEventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#[Security("is_granted('ROLE_OAUTH_SCOPE_JEMARCHE_APP') and is_granted('ROLE_PAP_USER')")]
class BuildingEventController extends AbstractController
{
#[Route(path: '/v3/pap/buildings/{uuid}/events', requirements: ['uuid' => '%pattern_uuid%'], name: 'api_create_building_event', methods: ['POST'])]
#[Route(path: '/v3/pap/buildings/{uuid}/events', name: 'api_create_building_event', requirements: ['uuid' => '%pattern_uuid%'], methods: ['POST'])]
public function __invoke(
Request $request,
Building $building,
Expand Down
9 changes: 8 additions & 1 deletion src/Entity/Pap/Building.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ public function setType(string $type): void
*/
public function getCampaignStatistics(): ?CampaignStatisticsInterface
{
return $this->currentCampaign ? $this->findStatisticsForCampaign($this->currentCampaign) : new BuildingStatistics($this, $this->currentCampaign);
if ($this->currentCampaign) {
return $this->findStatisticsForCampaign($this->currentCampaign) ?? new BuildingStatistics(
$this,
$this->currentCampaign
);
}

return null;
}
}
18 changes: 9 additions & 9 deletions src/Pap/BuildingStatisticsManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,8 @@ public function __construct(
$this->campaignHistoryRepository = $campaignHistoryRepository;
}

public function updateStats(Building $building, Campaign $campaign): void
public function updateStats(Building $building, Campaign $campaign): BuildingStatistics
{
$campaignHistory = $this->campaignHistoryRepository->findLastFor($building, $campaign);

if (!$campaignHistory) {
return;
}

// building stats
if (!$buildingStats = $building->findStatisticsForCampaign($campaign)) {
$building->addStatistic($buildingStats = new BuildingStatistics(
Expand All @@ -48,8 +42,12 @@ public function updateStats(Building $building, Campaign $campaign): void
if ($buildingStats->isTodo()) {
$buildingStats->setStatus(BuildingStatusEnum::ONGOING);
}
$buildingStats->setLastPassage($campaignHistory->getUpdatedAt());
$buildingStats->setLastPassageDoneBy($campaignHistory->getQuestioner());

if ($campaignHistory = $this->campaignHistoryRepository->findLastFor($building, $campaign)) {
$buildingStats->setLastPassage($campaignHistory->getUpdatedAt());
$buildingStats->setLastPassageDoneBy($campaignHistory->getQuestioner());
}

$buildingStats->setNbVisitedDoors($this->campaignHistoryRepository->countDoorsForBuilding($building));
$buildingStats->setNbSurveys($this->dataSurveyRepository->countSurveysForBuilding($building));

Expand Down Expand Up @@ -97,5 +95,7 @@ public function updateStats(Building $building, Campaign $campaign): void
}

$this->em->flush();

return $buildingStats;
}
}
25 changes: 15 additions & 10 deletions src/Pap/Handler/BuildingEventCommandHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@
use App\Entity\Pap\CampaignStatisticsOwnerInterface;
use App\Pap\BuildingEventActionEnum;
use App\Pap\BuildingEventTypeEnum;
use App\Pap\BuildingStatisticsManager;
use App\Pap\BuildingStatusEnum;
use App\Pap\Command\BuildingEventAsyncCommand;
use App\Pap\Command\BuildingEventCommandInterface;
use App\Repository\Pap\BuildingEventRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

class BuildingEventCommandHandler implements MessageHandlerInterface
{
private EntityManagerInterface $entityManager;
private BuildingEventRepository $buildingEventRepository;

public function __construct(EntityManagerInterface $entityManager, BuildingEventRepository $buildingEventRepository)
{
$this->entityManager = $entityManager;
$this->buildingEventRepository = $buildingEventRepository;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly BuildingEventRepository $buildingEventRepository,
private readonly BuildingStatisticsManager $buildingStatisticsManager,
) {
}

public function __invoke(BuildingEventCommandInterface $command): void
Expand Down Expand Up @@ -64,21 +64,26 @@ public function __invoke(BuildingEventCommandInterface $command): void
throw new \InvalidArgumentException(sprintf('Type %s is not supported for creation a building statistics', $type));
}

$this->updateStatisticsCloseInfo($objectWithStats, $buildingEvent);
$this->updateStatisticsCloseInfo($objectWithStats, $buildingEvent, $command instanceof BuildingEventAsyncCommand);
}

$this->entityManager->flush();
}

private function updateStatisticsCloseInfo(
CampaignStatisticsOwnerInterface $object,
BuildingEvent $buildingEvent
BuildingEvent $buildingEvent,
bool $isAsync
): void {
$status = BuildingEventActionEnum::CLOSE === $buildingEvent->getAction() ? BuildingStatusEnum::COMPLETED : BuildingStatusEnum::ONGOING;
$campaign = $buildingEvent->getCampaign();
/** @var CampaignStatisticsInterface $stats */
if (!$stats = $object->findStatisticsForCampaign($campaign)) {
throw new \RuntimeException(sprintf('Statistics not found for entity "%s" with id "%s" for PAP campaign with id "%s"', $object::class, $object->getId(), $campaign->getId()));
if ($isAsync && $object instanceof Building) {
$stats = $this->buildingStatisticsManager->updateStats($object, $campaign);
} else {
throw new \RuntimeException(sprintf('Statistics not found for entity "%s" with id "%s" for PAP campaign with id "%s"', $object::class, $object->getId(), $campaign->getId()));
}
}

$statusDetail = null;
Expand Down
48 changes: 14 additions & 34 deletions src/Repository/Pap/AddressRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use App\Entity\Pap\Address;
use App\Entity\Pap\Campaign;
use App\Entity\Pap\VotePlace;
use App\Pap\BuildingStatusEnum;
use App\Repository\GeoZoneTrait;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\Expr\Join;
Expand Down Expand Up @@ -41,16 +40,16 @@ public function findNear(
SELECT address.id
FROM pap_address AS address
INNER JOIN pap_building AS building ON building.address_id = address.id AND building.current_campaign_id IN ($activeCampaignsCondition)
WHERE
WHERE
address.offset_x BETWEEN :offset_x_1 AND :offset_x_2
AND address.offset_y BETWEEN :offset_y_1 AND :offset_y_2
ORDER BY
(6371 *
ORDER BY
(6371 *
ACOS(
COS(RADIANS(:latitude))
* COS(RADIANS(address.latitude))
* COS(RADIANS(address.longitude) - RADIANS(:longitude))
+ SIN(RADIANS(:latitude))
COS(RADIANS(:latitude))
* COS(RADIANS(address.latitude))
* COS(RADIANS(address.longitude) - RADIANS(:longitude))
+ SIN(RADIANS(:latitude))
* SIN(RADIANS(address.latitude))
))
LIMIT :limit
Expand Down Expand Up @@ -80,12 +79,12 @@ public function findNear(
->createQueryBuilder('address')
->select('address', 'building', 'stats')
->addSelect('
(6371 *
(6371 *
ACOS(
COS(RADIANS(:latitude))
* COS(RADIANS(address.latitude))
* COS(RADIANS(address.longitude) - RADIANS(:longitude))
+ SIN(RADIANS(:latitude))
COS(RADIANS(:latitude))
* COS(RADIANS(address.latitude))
* COS(RADIANS(address.longitude) - RADIANS(:longitude))
+ SIN(RADIANS(:latitude))
* SIN(RADIANS(address.latitude))
)) as HIDDEN distance
')
Expand All @@ -108,7 +107,7 @@ public function associatedCampaign(Campaign $campaign): void
$sql = <<<SQL
UPDATE pap_address AS address
INNER JOIN pap_building AS building ON building.address_id = address.id
LEFT JOIN pap_campaign AS current_campaign ON current_campaign.id = building.current_campaign_id
LEFT JOIN pap_campaign AS current_campaign ON current_campaign.id = building.current_campaign_id
SET building.current_campaign_id = :campaign_id
WHERE (current_campaign.id IS NULL OR current_campaign.finish_at < :start_date)
__VOTE_PLACE_CONDITION__
Expand Down Expand Up @@ -145,32 +144,13 @@ public function associatedCampaign(Campaign $campaign): void
$connection = $this->getEntityManager()->getConnection();
$connection->prepare($sql)->executeStatement($params);

// insert building statistics for new campaign
$sql = <<<SQL
INSERT IGNORE INTO pap_building_statistics (building_id, campaign_id, status, uuid, created_at, updated_at)
SELECT
building.id,
building.current_campaign_id,
:todo_status,
UUID(),
NOW(),
NOW()
FROM pap_building AS building
WHERE building.current_campaign_id = :campaign_id
SQL;

$connection->prepare($sql)->executeStatement([
'campaign_id' => $campaign->getId(),
'todo_status' => BuildingStatusEnum::TODO,
]);

// unlink campaign from buildings that not in campaign's vote places
if (isset($votePlaceIds)) {
$connection->prepare(<<<SQL
UPDATE pap_address AS address
INNER JOIN pap_building AS building ON building.address_id = address.id
SET building.current_campaign_id = NULL
WHERE building.current_campaign_id = :campaign_id
WHERE building.current_campaign_id = :campaign_id
AND address.vote_place_id NOT IN ($votePlaceIds)
SQL)->executeStatement([
'campaign_id' => $campaign->getId(),
Expand Down

0 comments on commit 91ec81c

Please sign in to comment.