From 53a45ac4f44c7c66b3ae859fbafed1db460548c8 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Thu, 5 Oct 2023 18:05:15 +0800 Subject: [PATCH 1/4] Add AggregatedRiderRating entity. Add command to process all rider ratings into AggregatedRiderRating. #764 --- .../LoadAggregateRiderRatingsComand.php | 112 ++++++++++++++++++ src/Entity/AggregatedRiderRating.php | 86 ++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 src/Command/LoadAggregateRiderRatingsComand.php create mode 100644 src/Entity/AggregatedRiderRating.php diff --git a/src/Command/LoadAggregateRiderRatingsComand.php b/src/Command/LoadAggregateRiderRatingsComand.php new file mode 100644 index 00000000..eb2eb3fd --- /dev/null +++ b/src/Command/LoadAggregateRiderRatingsComand.php @@ -0,0 +1,112 @@ +em = $em; + + parent::__construct(); + } + + protected function configure() + { + $this->setName('aggregated_rider_rating:load') + ->setDescription('Add rider ratings to aggregated rider rating.') + ->setHelp('Add rider ratings to aggregated rider rating.'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + // get the ids of all riders + $rider_id_list = $this->getRiderIds(); + + $this->processAggregateRiderRating($rider_id_list); + + return 0; + } + + protected function processAggregateRiderRating($rider_id_list) + { + $db = $this->em->getConnection(); + + $agg_rider_ratings = []; + + // get all rider ratings per rider + $rr_query_sql = 'SELECT rating FROM rider_rating WHERE rider_id = :id'; + $rr_query_stmt = $db->prepare($rr_query_sql); + foreach ($rider_id_list as $key => $rider_id) + { + $rr_query_stmt->bindValue('id', $rider_id); + $results = $rr_query_stmt->executeQuery(); + + $total_jos = 0; + $total_rating = 0; + while ($row = $results->fetchAssociative()) + { + $rating = $row['rating']; + + $total_rating = bcadd($total_rating, $rating, 2); + + // increment number of JOs per rider + $total_jos++; + } + + // compute average + $agg_rating = 0; + if ($total_jos > 0) + $agg_rating = bcdiv($total_rating, $total_jos, 2); + + $agg_rider_ratings[$rider_id] = [ + 'agg_rating' => $agg_rating, + 'agg_count' => $total_jos, + ]; + } + + // create aggregated rider rating + $this->createAggregatedRiderRating($agg_rider_ratings); + } + + protected function createAggregatedRiderRating($agg_rider_ratings) + { + error_log(print_r($agg_rider_ratings, true)); + + // TODO: create new AggregatedRiderRating object + // set fields + // save to database + } + + protected function getRiderIds() + { + $rider_ids = []; + $db = $this->em->getConnection(); + + $query_sql = 'SELECT id FROM rider'; + $query_stmt = $db->prepare($query_sql); + $results = $query_stmt->executeQuery(); + + while ($row = $results->fetchAssociative()) + { + $rider_ids[] = $row['id']; + } + + return $rider_ids; + } + +} diff --git a/src/Entity/AggregatedRiderRating.php b/src/Entity/AggregatedRiderRating.php new file mode 100644 index 00000000..4b1eb829 --- /dev/null +++ b/src/Entity/AggregatedRiderRating.php @@ -0,0 +1,86 @@ +aggregate_rating = 0; + $this->aggregate_count = 0; + } + + public function getID() + { + return $this->id; + } + + public function setRiderId($rider_id) + { + $this->rider_id = $rider_id; + return $this; + } + + public function getRiderId() + { + return $this->rider_id; + } + + public function setAggregateRating($aggregate_rating) + { + $this->aggregate_rating = $aggregate_rating; + return $this; + } + + public function getAggregateRating() + { + return $this->aggregate_rating; + } + + public function setAggregateCount($aggregate_count) + { + $this->aggregate_count = $aggregate_count; + return $this; + } + + public function getAggregateCount() + { + return $this->aggregate_count; + } + + +} From 83c0e1cd51cb544939a2b192b0b4ad7837ca73c0 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 6 Oct 2023 10:39:47 +0800 Subject: [PATCH 2/4] Add saving for aggregated rider rating. #764 --- .../LoadAggregateRiderRatingsComand.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Command/LoadAggregateRiderRatingsComand.php b/src/Command/LoadAggregateRiderRatingsComand.php index eb2eb3fd..7e10230f 100644 --- a/src/Command/LoadAggregateRiderRatingsComand.php +++ b/src/Command/LoadAggregateRiderRatingsComand.php @@ -9,7 +9,6 @@ use Symfony\Component\Console\Output\OutputInterface; use Doctrine\ORM\EntityManagerInterface; -use App\Entity\RiderRating; use App\Entity\AggregatedRiderRating; use PDO; @@ -87,9 +86,21 @@ class LoadAggregateRiderRatingsComand extends Command { error_log(print_r($agg_rider_ratings, true)); - // TODO: create new AggregatedRiderRating object - // set fields - // save to database + foreach ($agg_rider_ratings as $key => $data) + { + // create new AggregatedRiderRating object + $obj = new AggregatedRiderRating(); + + // set fields + $obj->setRiderId($key) + ->setAggregateRating($data['agg_rating']) + ->setAggregateCount($data['agg_count']); + + // save to database + $this->em->persist($obj); + } + + $this->em->flush(); } protected function getRiderIds() From 629829691cb725742784367c6746e8936f108032 Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 6 Oct 2023 15:25:09 +0800 Subject: [PATCH 3/4] Add saving to aggregated rider rating when adding a rider rating from app. #764 --- src/Controller/APIController.php | 60 ++++++++++++++++++- .../CustomerAppAPI/RiderController.php | 55 +++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php index 64662057..c1fb28ad 100644 --- a/src/Controller/APIController.php +++ b/src/Controller/APIController.php @@ -69,6 +69,7 @@ use App\Entity\Hub; use App\Entity\SAPBattery; use App\Entity\WarrantySerial; use App\Entity\CustomerMetadata; +use App\Entity\AggregatedRiderRating; use DateTime; use DateInterval; @@ -1705,7 +1706,13 @@ class APIController extends Controller implements LoggedController $em->persist($rating); $em->flush(); - // TODO: set average rating in rider entity + // need to update or add aggregated rider rating + $this->updateAggregatedRiderRating($em, $rider, $rating_num); + + // TODO: preliminary rating computation on the entity for now + $rider->updateRatingAverage(); + $em->persist($rider); + $em->flush(); $res->setData([]); @@ -4827,6 +4834,57 @@ class APIController extends Controller implements LoggedController return $jo_data; } + protected function updateAggregatedRiderRating($em, $rider, $rating_num) + { + $rider_id = $rider->getID(); + + // check if rider is in the the aggregated rider rating table + $agg_rider_rating = $em->getRepository(AggregatedRiderRating::class)->findOneBy(['rider_id' => $rider_id]); + if ($agg_rider_rating == null) + { + // new rider, new entry + $old_rating = 0; + $old_count = 0; + $new_count = 1; + $agg_rating = $this->computeAggregatedRiderRating($old_rating, $rating_num, $old_count, $new_count); + + $obj = new AggregatedRiderRating(); + $obj->setRiderId($rider_id) + ->setAggregateRating($agg_rating) + ->setAggregateCount($new_count); + + $em->persist($obj); + } + else + { + // existing rider, update entry + $r_rating = $agg_rider_rating->getAggregateRating(); + $r_count = $agg_rider_rating->getAggregateCount(); + + $new_count = ++$r_count; + + $agg_rating = $this->computeAggregatedRiderRating($r_rating, $rating_num, $r_count, $new_count); + + // set updated values for entry + $agg_rider_rating->setAggregateRating($agg_rating) + ->setAggregateCount($new_count); + } + + $em->flush(); + } + + protected function computeAggregatedRiderRating($old_rating, $new_rating, $r_count, $new_count) + { + // ((existing aggregate rating * existing aggregate count) + new rating) / new count + $agg_comp = bcmul($old_rating, $r_count, 2); + + $rating = bcadd($agg_comp, $new_rating, 2); + + $agg_rating = bcdiv($rating, $new_count, 2); + + return $agg_rating; + } + protected function normalizeString($string) { return trim(strtolower($string)); diff --git a/src/Controller/CustomerAppAPI/RiderController.php b/src/Controller/CustomerAppAPI/RiderController.php index 96557a54..bc563e09 100644 --- a/src/Controller/CustomerAppAPI/RiderController.php +++ b/src/Controller/CustomerAppAPI/RiderController.php @@ -9,6 +9,7 @@ use App\Ramcar\JOStatus; use App\Ramcar\APIRiderStatus; use App\Entity\RiderRating; use App\Entity\JobOrder; +use App\Entity\AggregatedRiderRating; use App\Service\RiderTracker; use Exception; @@ -230,6 +231,9 @@ class RiderController extends ApiController $this->em->persist($rating); $this->em->flush(); + // need to update or add aggregated rider rating + $this->updateAggregatedRiderRating($rider, $rating_num); + // TODO: preliminary rating computation on the entity for now $rider->updateRatingAverage(); $this->em->persist($rider); @@ -238,4 +242,55 @@ class RiderController extends ApiController // response return new ApiResponse(); } + + protected function updateAggregatedRiderRating($rider, $rating_num) + { + $rider_id = $rider->getID(); + + // check if rider is in the the aggregated rider rating table + $agg_rider_rating = $this->em->getRepository(AggregatedRiderRating::class)->findOneBy(['rider_id' => $rider_id]); + if ($agg_rider_rating == null) + { + // new rider, new entry + $old_rating = 0; + $old_count = 0; + $new_count = 1; + $agg_rating = $this->computeAggregatedRiderRating($old_rating, $rating_num, $old_count, $new_count); + + $obj = new AggregatedRiderRating(); + $obj->setRiderId($rider_id) + ->setAggregateRating($agg_rating) + ->setAggregateCount($new_count); + + $this->em->persist($obj); + } + else + { + // existing rider, update entry + $r_rating = $agg_rider_rating->getAggregateRating(); + $r_count = $agg_rider_rating->getAggregateCount(); + + $new_count = ++$r_count; + + $agg_rating = $this->computeAggregatedRiderRating($r_rating, $rating_num, $r_count, $new_count); + + // set updated values for entry + $agg_rider_rating->setAggregateRating($agg_rating) + ->setAggregateCount($new_count); + } + + $this->em->flush(); + } + + protected function computeAggregatedRiderRating($old_rating, $new_rating, $r_count, $new_count) + { + // ((existing aggregate rating * existing aggregate count) + new rating) / new count + $agg_comp = bcmul($old_rating, $r_count, 2); + + $rating = bcadd($agg_comp, $new_rating, 2); + + $agg_rating = bcdiv($rating, $new_count, 2); + + return $agg_rating; + } } From a3c875b907fa5865f7f3d35ff8183a191bb4ae5b Mon Sep 17 00:00:00 2001 From: Korina Cordero Date: Fri, 6 Oct 2023 15:59:32 +0800 Subject: [PATCH 4/4] Fix setting of rider's current rating. Fix issues found during testing. Remove debug messages. #764 --- src/Command/LoadAggregateRiderRatingsComand.php | 2 +- src/Controller/APIController.php | 11 +++++++---- src/Controller/CustomerAppAPI/RiderController.php | 9 ++++++--- src/Entity/AggregatedRiderRating.php | 2 +- src/Entity/Rider.php | 10 ++-------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Command/LoadAggregateRiderRatingsComand.php b/src/Command/LoadAggregateRiderRatingsComand.php index 7e10230f..b6c864c0 100644 --- a/src/Command/LoadAggregateRiderRatingsComand.php +++ b/src/Command/LoadAggregateRiderRatingsComand.php @@ -84,7 +84,7 @@ class LoadAggregateRiderRatingsComand extends Command protected function createAggregatedRiderRating($agg_rider_ratings) { - error_log(print_r($agg_rider_ratings, true)); + // error_log(print_r($agg_rider_ratings, true)); foreach ($agg_rider_ratings as $key => $data) { diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php index c1fb28ad..8614537e 100644 --- a/src/Controller/APIController.php +++ b/src/Controller/APIController.php @@ -1707,10 +1707,10 @@ class APIController extends Controller implements LoggedController $em->flush(); // need to update or add aggregated rider rating - $this->updateAggregatedRiderRating($em, $rider, $rating_num); + $average_rating = $this->updateAggregatedRiderRating($em, $rider, $rating_num); // TODO: preliminary rating computation on the entity for now - $rider->updateRatingAverage(); + $rider->updateRatingAverage($average_rating); $em->persist($rider); $em->flush(); @@ -4837,6 +4837,7 @@ class APIController extends Controller implements LoggedController protected function updateAggregatedRiderRating($em, $rider, $rating_num) { $rider_id = $rider->getID(); + $agg_rating = 0; // check if rider is in the the aggregated rider rating table $agg_rider_rating = $em->getRepository(AggregatedRiderRating::class)->findOneBy(['rider_id' => $rider_id]); @@ -4861,7 +4862,7 @@ class APIController extends Controller implements LoggedController $r_rating = $agg_rider_rating->getAggregateRating(); $r_count = $agg_rider_rating->getAggregateCount(); - $new_count = ++$r_count; + $new_count = $r_count + 1; $agg_rating = $this->computeAggregatedRiderRating($r_rating, $rating_num, $r_count, $new_count); @@ -4871,6 +4872,8 @@ class APIController extends Controller implements LoggedController } $em->flush(); + + return $agg_rating; } protected function computeAggregatedRiderRating($old_rating, $new_rating, $r_count, $new_count) @@ -4879,7 +4882,7 @@ class APIController extends Controller implements LoggedController $agg_comp = bcmul($old_rating, $r_count, 2); $rating = bcadd($agg_comp, $new_rating, 2); - + $agg_rating = bcdiv($rating, $new_count, 2); return $agg_rating; diff --git a/src/Controller/CustomerAppAPI/RiderController.php b/src/Controller/CustomerAppAPI/RiderController.php index bc563e09..3d143fbf 100644 --- a/src/Controller/CustomerAppAPI/RiderController.php +++ b/src/Controller/CustomerAppAPI/RiderController.php @@ -232,10 +232,10 @@ class RiderController extends ApiController $this->em->flush(); // need to update or add aggregated rider rating - $this->updateAggregatedRiderRating($rider, $rating_num); + $average_rating = $this->updateAggregatedRiderRating($rider, $rating_num); // TODO: preliminary rating computation on the entity for now - $rider->updateRatingAverage(); + $rider->updateRatingAverage($average_rating); $this->em->persist($rider); $this->em->flush(); @@ -246,6 +246,7 @@ class RiderController extends ApiController protected function updateAggregatedRiderRating($rider, $rating_num) { $rider_id = $rider->getID(); + $agg_rating = 0; // check if rider is in the the aggregated rider rating table $agg_rider_rating = $this->em->getRepository(AggregatedRiderRating::class)->findOneBy(['rider_id' => $rider_id]); @@ -270,7 +271,7 @@ class RiderController extends ApiController $r_rating = $agg_rider_rating->getAggregateRating(); $r_count = $agg_rider_rating->getAggregateCount(); - $new_count = ++$r_count; + $new_count = $r_count + 1; $agg_rating = $this->computeAggregatedRiderRating($r_rating, $rating_num, $r_count, $new_count); @@ -280,6 +281,8 @@ class RiderController extends ApiController } $this->em->flush(); + + return $agg_rating; } protected function computeAggregatedRiderRating($old_rating, $new_rating, $r_count, $new_count) diff --git a/src/Entity/AggregatedRiderRating.php b/src/Entity/AggregatedRiderRating.php index 4b1eb829..6d042359 100644 --- a/src/Entity/AggregatedRiderRating.php +++ b/src/Entity/AggregatedRiderRating.php @@ -28,7 +28,7 @@ class AggregatedRiderRating // average rating of rider /** - * @ORM\Column(type="integer") + * @ORM\Column(type="float") */ protected $aggregate_rating; diff --git a/src/Entity/Rider.php b/src/Entity/Rider.php index fcdb3ed2..2a078983 100644 --- a/src/Entity/Rider.php +++ b/src/Entity/Rider.php @@ -241,15 +241,9 @@ class Rider return $this->image_file; } - public function updateRatingAverage() + public function updateRatingAverage($rating) { - $total = 0; - - foreach ($this->ratings as $rating) { - $total += $rating->getRating(); - } - - $this->setCurrentRating(round($total / $this->ratings->count(), 2)); + $this->setCurrentRating($rating); } public function setCurrentRating($rating)