resq/src/Command/UpdateUnacceptedJobOrdersCommand.php
2023-06-13 20:33:58 +08:00

153 lines
4.9 KiB
PHP

<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Entity\JobOrder;
use App\Entity\Rider;
use PDO;
class UpdateUnacceptedJobOrdersCommand extends Command
{
protected $em;
protected $mclient;
// NOTE: for resq2 app
protected $mclientv2;
protected $fcmclient;
public function __construct(EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
$this->em = $em;
$this->mclient = $mclient;
// NOTE: for resq2 app
$this->mclientv2 = $mclientv2;
$this->fcmclient = $fcmclient;
parent::__construct();
}
protected function configure()
{
$this->setName('joborder:reassignunaccepted')
->setDescription('Requeue for rider assignment assigned but unaccepted job orders that have been assigned for more than 3 mins.')
->setHelp('Requeue for rider assignment assigned but unaccepted job orders that have been assigned for more than 3 mins.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->em;
$mclient = $this->mclient;
// NOTE: for resq2 app
$mclientv2 = $this->mclientv2;
$fcmclient = $this->fcmclient;
// TODO: get the timeout limit from .env
$timeout = 3;
$current_status = 'assigned';
$new_status = 'rider_assign';
// pdo connection
$db = $em->getConnection();
// since we need the actual job orders for mqtt events, we need to get the ids of the job orders
// that will be updated
// need rider id to set rider to available since rider becomes unavailable
// the minute JO is assigned to rider
$query_sql = 'SELECT id FROM job_order WHERE status = :current_status and TIMESTAMPDIFF(MINUTE, date_assign, NOW()) >= :timeout';
$query_stmt = $db->prepare($query_sql);
$query_stmt->execute([
'current_status' => $current_status,
'timeout' => $timeout,
]);
// go through rows
$requeued_jos = [];
while ($row = $query_stmt->fetch(PDO::FETCH_NUM))
{
// $row[0] is the jo id
// store the jos for now for the event sending after update of JOs
// and the updating of rider's availability
$jo_id = $row[0];
$requeued_jo = $em->getRepository(JobOrder::class)->find($jo_id);
$requeued_jos[] = [
'jo' => $requeued_jo,
];
$update_sql = 'UPDATE job_order SET status = :new_status, rider_id = null WHERE id = :jo_id';
$update_stmt = $db->prepare($update_sql);
$update_stmt->execute([
'new_status' => $new_status,
'jo_id' => $jo_id,
]);
}
foreach ($requeued_jos as $jo_info)
{
$jo = $jo_info['jo'];
if ($jo != null)
{
// $output->writeln('Requeuing for rider assignment ' . $jo->getID());
$id = $jo->getID();
// send notifications to rider app, telling rider that jo has been requeued
$rider_payload = [
'event' => 'cancelled',
'reason' => 'Reassigned',
'jo_id' => $id,
];
$mclient->sendRiderEvent($jo, $rider_payload);
// send outlet assign since order should go back to hub and await reassignment to another rider
$payload = [
'event' => 'outlet_assign',
'jo_id' => $id,
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
}
$rider = $jo->getRider();
if ($rider != null)
{
// check rider's current job order before changing rider's availability
// since rider's current job order is set when JO is assigned to rider
if ($rider->getCurrentJobOrder() != null)
{
if ($rider->getCurrentJobOrder()->getID() == $jo->getID())
{
// reset rider's availability to true
$rider->setAvailable(true);
// set rider's current job order to null
$rider->setCurrentJobOrder();
}
}
}
}
$em->flush();
return 0;
}
}