<?php
namespace AutomarketBundle\Services;
use CoreBundle\Entity\Brand;
use CoreBundle\Entity\Dealer;
use CoreBundle\Entity\Vehicles\CharacteristicValue;
use CoreBundle\Entity\Vehicles\Vehicle;
use CoreBundle\Entity\Vehicles\VehicleItem;
use CoreBundle\Model\Vehicles\Repository;
use CoreBundle\Model\Vehicles\VehicleType;
use CoreBundle\Services\MediaExtensionVidi;
use DcSiteBundle\Services\VehicleService;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\Expr\Join;
use Symfony\Component\Routing\RouterInterface;
class MainService
{
/**
* @var EntityManagerInterface
*/
private $em;
/**
* @var MediaExtensionVidi
*/
private $media;
/**
* @var RouterInterface
*/
private $router;
/**
* @var Repository
*/
private $vehicleRepository;
/**
* @var Repository
*/
private $catalogService;
/**
* @var VehicleService
*/
private $vehicleService;
/**
* @var string $lang
*/
private $lang = 'ua';
public function __construct(MediaExtensionVidi $media, RouterInterface $router, EntityManagerInterface $em,
Repository $vehicleRepository, CatalogService $catalogService, VehicleService $vehicleService)
{
$this->em = $em;
$this->router = $router;
$this->media = $media;
$this->vehicleRepository = $vehicleRepository;
$this->catalogService = $catalogService;
$this->vehicleService = $vehicleService;
}
public function setLang(string $lang): MainService
{
$this->lang = $lang;
return $this;
}
/**
* Отримати тип кузова
*
* @param Dealer $dealer
* @return array
*/
public function getBodyTypes(Dealer $dealer): array
{
$rows = $this->em
->getRepository(CharacteristicValue::class)
->getBodyTypesByDealer();
$bodyTypes = [];
/** @var CharacteristicValue $row */
foreach ($rows as $row){
$vehicleTypeData = VehicleType::getTypeDataById($row->getCharacteristic()->getVehicleType());
if($row->getCharacteristic()->getVehicleType() === VehicleType::MOTO_TYPE and $row->getId() !== 278){
continue;
}
$href = $this->router->generate('automarket_catalog_characteristic',['state' => 'used','type' => $vehicleTypeData['url'], 'param' => 'body', 'value' => $row->getUrl() ]);
if($row->getCharacteristic()->getVehicleType() === VehicleType::MOTO_TYPE){
$href = $this->router->generate('automarket_catalog',['state' => 'used','type' => $vehicleTypeData['url'] ]);
}
$bodyTypes[] = [
'id' => $row->getId(),
'title' => $row->getValue($this->lang),
'type' => $row->getUrl(),
'href' => $href,
];
}
return $bodyTypes;
}
/**
* Отримати бренди
*
* @param Dealer $dealer
* @return array
*/
public function getBrands(Dealer $dealer): array
{
$rows = $this->em->getRepository(Brand::class)
->createQueryBuilder('b')
->addSelect('COUNT(vi.id) AS count_vehicles')
->addSelect('MIN(CASE WHEN ( d.id in (32,33)) THEN (CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE (CASE WHEN vi.alt_rate > 0 THEN vi.alt_rate * vi.price ELSE vi.price * d.rate END) END) ELSE ( CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE vi.price END) END) AS min_price')
->innerJoin('b.models', 'm')
->innerJoin('m.vehicles', 'v', Join::WITH, 'v.state = 1')
->join('v.dealer', 'd')
->innerJoin('v.vehicle_items', 'vi', Join::WITH, 'vi.state = 1')
->where('v.is_used = 1')
->andWhere('v.vehicle_type = :type')->setParameter('type', 1)
->andWhere('vi.deposit = :deposit')->setParameter('deposit', false)
->andWhere('vi.sold = :sold')->setParameter('sold', false)
// ->andWhere('v.dealer = :dealer')->setParameter('dealer', $dealer->getId())
->groupBy('b.id')
->getQuery()
->getResult();
$rows = array_map(function($row) use ($dealer) {
/**
* @var Brand $brand
*/
$brand = $row[0];
$dollar = $dealer->getRate();
$price = $row['min_price'];
$priceDollar = ceil($price / $dollar);
return [
'id' => $brand->getId(),
'name' => $brand->getName(),
'count' => $row['count_vehicles'],
'price' => intval($priceDollar),
'url'=> $this->router->generate('automarket_catalog_brand',['state' => 'used', 'type' => 'car', 'brand' => $brand->getUrl() ]),
'media' => [
'image' => $this->media->getPath($brand->getLogo(), 'menu')
]
];
}, $rows);
usort($rows, fn($a, $b) => $b['count'] <=> $a['count']);
return $rows;
}
/**
* Отримати нові надходження
*
* @param Dealer $dealer
* @param $user
* @return array
*/
public function getNewArrivals(Dealer $dealer, $user, $isUsed, $lang): array
{
$newArrivalsVehicleItems = $this->vehicleRepository->getNewAddVehicleItem($isUsed, 5, $dealer);
return $this->catalogService->getVehicleCatalogItem($dealer, $newArrivalsVehicleItems, $user, $lang);
}
/**
* Отримати vehicle зі знижкою
*
* @param Dealer $dealer
* @param $user
* @return array
*/
public function getProposeVehicles(Dealer $dealer, $user, $isUsed, $lang, $vehicle, $vehicleItemID, $withDiscount = false): array
{
$brand = $vehicle->getModel()->getBrand();
$model = $vehicle->getModel();
$bodyType = $vehicle->getBodyType();
$price = $vehicle->price();
// 1. Brand + Model
$vehiclesSaleList = $this->vehicleRepository
->getProposeVehicleItem($isUsed, $brand, $model, null, $withDiscount);
// 2. BodyType + Price
$vehiclesByBodyType = $this->vehicleRepository
->getProposeVehicleItem($isUsed, null, null, $bodyType, $withDiscount);
$minPriceRange = $price - 20000;
$maxPriceRange = $price + 20000;
foreach ($vehiclesByBodyType as $vehicleByBodyType) {
$vehiclePrice = $vehicleByBodyType->getAltPrice() ? $vehicleByBodyType->calcPrice() : $vehicleByBodyType->getPrice();
if ($vehiclePrice < $minPriceRange || $vehiclePrice > $maxPriceRange ) continue;
$vehiclesSaleList[] = $vehicleByBodyType;
}
// 3. Brand
$vehiclesByBrand = $this->vehicleRepository
->getProposeVehicleItem($isUsed, $brand, null, null, $withDiscount);
foreach($vehiclesByBrand as $vehicle){
$vehiclesSaleList[] = $vehicle;
}
// Уніфікуємо автомобілі
$vehiclesSaleListID = [];
foreach ($vehiclesSaleList as $vehicleItem){
$vehiclesSaleListID[] = $vehicleItem->getId();
}
$vehiclesSaleListID = array_unique($vehiclesSaleListID);
// Видаляємо поточне авто
$index = array_search($vehicleItemID, $vehiclesSaleListID);
if ($index !== false) {
unset($vehiclesSaleListID[$index]);
}
$vehiclesSaleListID = count($vehiclesSaleListID) > 10 ? array_slice($vehiclesSaleListID, 0 , 10) : $vehiclesSaleListID;
$uniqueVehicleList = [];
foreach ($vehiclesSaleListID as $vehicleItemID){
$uniqueVehicleList[] = $this->em->getRepository(VehicleItem::class)->find($vehicleItemID);
}
return $this->catalogService->getVehicleCatalogItem($dealer, $uniqueVehicleList, $user, $lang);
}
/**
* Отримати наші добірки
*
* @return array
*/
public function getOurSelections(): array
{
$rows = $this->vehicleService->getRecommendGroup(true, true, true);
return array_map(function($row) {
/** @var Vehicle $firstVehicle */
$firstVehicle = $row->getVehicles()->first();
$vehicleTypeData = VehicleType::getTypeDataById($firstVehicle->getVehicleType());
return [
'id' => $row->getId(),
'title' => $row->getTitle($this->lang),
'url' => $this->router->generate('automarket_catalog_vehicle_collections', ['state' => 'used', 'type' => $vehicleTypeData['url'], 'recommendGroup' => $row->getUrl()]),
'media' => [
'image' => $this->media->getPath($row->getImage(), 'reference')
]
];
}, $rows);
}
}