src/Response/Beauty/Offer/Factory/MasterResponseFactory.php line 64

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Slivki\Response\Beauty\Offer\Factory;
  4. use Slivki\Dao\Category\Rating\DirectorRatingDaoInterface;
  5. use Slivki\Entity\BeautyMaster;
  6. use Slivki\Entity\Category;
  7. use Slivki\Entity\Director;
  8. use Slivki\Entity\Offer;
  9. use Slivki\Entity\PhoneNumber;
  10. use Slivki\Enum\Beauty\MasterWorkPlaceType;
  11. use Slivki\Response\Beauty\Offer\MasterLocationResponse;
  12. use Slivki\Response\Beauty\Offer\MasterResponse;
  13. use Slivki\Response\OnlineOrder\Director\DirectorResponse;
  14. use Slivki\Services\ImageService;
  15. use Slivki\Services\Offer\OfferCacheService;
  16. use function array_map;
  17. use function array_values;
  18. use function count;
  19. use function array_sum;
  20. use function implode;
  21. use function round;
  22. final class MasterResponseFactory
  23. {
  24.     private ImageService $imageService;
  25.     private DirectorRatingDaoInterface $directorRatingDao;
  26.     private OfferCacheService $offerCacheService;
  27.     private ?array $ratingDirectors null;
  28.     public function __construct(
  29.         ImageService $imageService,
  30.         DirectorRatingDaoInterface $directorRatingDao,
  31.         OfferCacheService $offerCacheService
  32.     ) {
  33.         $this->imageService $imageService;
  34.         $this->directorRatingDao $directorRatingDao;
  35.         $this->offerCacheService $offerCacheService;
  36.     }
  37.     public function create(BeautyMaster $beautyMaster): MasterResponse
  38.     {
  39.         $ratingArray = [];
  40.         /** @var Category $category */
  41.         foreach ($beautyMaster->getCategories() as $category) {
  42.             if ($category->getSubCategories()->count() > 0) {
  43.                 continue;
  44.             }
  45.             $ratingArray[] = $this->getRating($category->getID(), $beautyMaster->getDirector());
  46.         }
  47.         $rating 0;
  48.         if (count($ratingArray) > 0) {
  49.             $rating array_sum($ratingArray) / count($ratingArray);
  50.         }
  51.         return $this->createResponse($beautyMaster$rating);
  52.     }
  53.     public function createForCategory(BeautyMaster $beautyMasterint $categoryId): MasterResponse
  54.     {
  55.         return $this->createResponse(
  56.             $beautyMaster,
  57.             $this->getRating($categoryId$beautyMaster->getDirector()),
  58.         );
  59.     }
  60.     private function createResponse(BeautyMaster $beautyMasterfloat $rating): MasterResponse
  61.     {
  62.         $director $beautyMaster->getDirector();
  63.         $locations = [];
  64.         $offerIds = [];
  65.         $categoryIds = [];
  66.         foreach ($beautyMaster->getLocations() as $location) {
  67.             $locations[] = new MasterLocationResponse(
  68.                 $location->getId(),
  69.                 implode(', ', [$location->getCity(), $location->getStreet(), $location->getHouse()]),
  70.                 array_map(
  71.                     static fn (PhoneNumber $phoneNumber) => $phoneNumber->getNumber(),
  72.                     $location->getPhoneNumbers()->toArray(),
  73.                 ),
  74.                 null === $location->getLatitude() ? null : (float) $location->getLatitude(),
  75.                 null === $location->getLongitude() ? null : (float) $location->getLongitude(),
  76.             );
  77.             $firstOffer $location->firstOffer();
  78.             if ($firstOffer->isActive()) {
  79.                 $locationId $firstOffer->getID();
  80.                 $offerIds[$locationId] = $locationId;
  81.             }
  82.         }
  83.         foreach ($beautyMaster->getCategories() as $category) {
  84.             $categoryIds[] = $category->getID();
  85.         }
  86.         [$telegram$viber] = $this->getSocial($beautyMaster$offerIds);
  87.         return new MasterResponse(
  88.             $beautyMaster->getId(),
  89.             MasterWorkPlaceType::getByStatus($beautyMaster->getStatus()),
  90.             $beautyMaster->getFirstName(),
  91.             $beautyMaster->getLastName(),
  92.             $this->imageService->getImageURLCachedWithDomain($beautyMaster->getPhoto(), 00),
  93.             $rating,
  94.             $beautyMaster->getDescription(),
  95.             $telegram,
  96.             $viber,
  97.             $beautyMaster->getSalon(),
  98.             $locations,
  99.             array_map(static fn (Category $tag) => $tag->getName(), $beautyMaster->getTags()->toArray()),
  100.             array_values($offerIds),
  101.             $director !== null
  102.                 ? new DirectorResponse(
  103.                 $director->getID(),
  104.                 $this->imageService->getImageURLCachedWithDomain($director->getOnlinePaymentLogo(), 00),
  105.                 $director->getName(),
  106.                 $director->getLegalEntity(),
  107.                 $director->getTaxID(),
  108.             )
  109.                 : null,
  110.             array_values($categoryIds),
  111.             $beautyMaster->getOnlineOrderUrl(),
  112.             $beautyMaster->getLevel()
  113.         );
  114.     }
  115.     private function getSocial(BeautyMaster $beautyMaster, array $offerIds): array
  116.     {
  117.         $telegram $beautyMaster->getTelegram();
  118.         $viber $beautyMaster->getViber();
  119.         if ($telegram === null || $viber === null) {
  120.             foreach ($offerIds as $offerId) {
  121.                 $offer $this->offerCacheService->getOffer($offerId);
  122.                 if ($offer instanceof Offer) {
  123.                     if ($telegram === null) {
  124.                         $telegram $offer->getTelegram();
  125.                     }
  126.                     if ($viber === null) {
  127.                         $viber $offer->getViber();
  128.                     }
  129.                     break;
  130.                 }
  131.             }
  132.         }
  133.         return [
  134.             empty($telegram) ? Offer::DEFAULT_TELEGRAM $telegram,
  135.             empty($viber) ? Offer::DEFAULT_VIBER $viber
  136.         ];
  137.     }
  138.     private function getRating(int $categoryId, ?Director $director): float
  139.     {
  140.         if ($director === null) {
  141.             return 0;
  142.         }
  143.         if ($this->ratingDirectors === null) {
  144.             $this->ratingDirectors $this->directorRatingDao->findDirectorRatingByCategoryId($categoryId);
  145.         }
  146.         foreach ($this->ratingDirectors as $ratingDirector) {
  147.             if ($ratingDirector->getDirectorId() === $director->getID()) {
  148.                 return round($ratingDirector->getAvgCommentRating(), 2);
  149.             }
  150.         }
  151.         return 0;
  152.     }
  153. }