- <?php
- /**
-  * Created by PhpStorm.
-  * User: serhii.patsai
-  * Date: 11.09.2019
-  * Time: 12:27
-  */
- namespace CoreBundle\Model;
- use DateTime;
- use CoreBundle\Entity\User;
- use CoreBundle\Entity\Dealer;
- use CoreBundle\Entity\VehicleEstimate;
- use CoreBundle\Factory\Vehicle;
- use CoreBundle\Model\Api\AutoRia\AutoRia;
- use CoreBundle\Model\Vehicles\Repository;
- use DcSiteBundle\Entity\Markdown;
- use Doctrine\ORM\EntityManagerInterface;
- use Doctrine\ORM\OptimisticLockException;
- class OnlineEstimateModel
- {
-     /**
-      * @var Rate
-      */
-     private $rateModel;
-     /**
-      * @var EntityManagerInterface
-      */
-     private $em;
-     /**
-      * @var AutoRia
-      */
-     private $AutoRia;
-     /**
-      * OnlineEstimateModel constructor.
-      * @param Rate $rate
-      * @param EntityManagerInterface $em
-      * @param Vehicle $VehicleFactory
-      * @param Repository $repository
-      */
-     public function __construct(Rate $rate, EntityManagerInterface $em, AutoRia $AutoRia)
-     {
-         $this->rateModel = $rate;
-         $this->em = $em;
-         $this->AutoRia = $AutoRia;
-     }
-     private function isSelect($params, $dealer = null, $isCRM = false) {
-         $old = (new DateTime())->format('Y')-$params['year'];
-         $mileage = explode('-', $params['mileage']);
-         if (count($mileage) == 2) {
-             $mileageTo = $mileage[1];
-         } else {
-             $mileage = $params['mileage'] < 1000 ? $params['mileage'] : ceil($params['mileage']/1000);
-             $mileageTo = $mileage + ($mileage*0.60);
-         }
-         $dealerInProgram = !$dealer || in_array($dealer->getId(), [8,27,35,34,3,29,28,32,33,37,38,15,30,9,31,39]);
-         $isOurBrand = in_array($params['brand']['id'], [55,47,58,75,24,15,76,31,37,28,128,85,56,5456,49]);
-         $inOld = $old <=5;
-         $inMileage = $mileageTo <= 100;
-         return $dealerInProgram && $isOurBrand && $inOld && $inMileage;
-     }
-     public function getPrices($estimate, $params)
-     {
-         $itemIds = [];
-         foreach ($estimate->result->search_result_common->data as $row) {
-             if($row->type == 'UsedAuto') {
-                 $itemIds[] = $row->id;
-             }
-         }
-         $fullItems = [];
-         $fuelId = $params['fuel'];
-         foreach ($itemIds as $id) {
-             $data = $this->AutoRia->getFullInfo($id);
-             if(!$data) {
-                 continue;
-             }
-             if(in_array($fuelId,[1,2,3,4]) && !in_array($data->autoData->fuelId,[1,2,3,4])) {
-                 continue;
-             }
-             $item['price'] = $data->UAH;
-             $item['year'] = $data->autoData->year;
-             $item['raceInt'] = $data->autoData->raceInt;
-             $item['fuelId'] = $data->autoData->fuelId;
-             $item['gearBoxId'] = $data->autoData->gearBoxId ?? null;
-             $fullItems[$id] = $item;
-         }
-         $yCof = [
-             '+' => [
-                 2022 => 0.85,
-                 2021 => 0.9,
-                 2020 => 0.93,
-                 2019 => 0.94,
-                 2018 => 0.94,
-                 2017 => 0.95,
-                 2016 => 0.95,
-                 2015 => 0.96,
-                 2014 => 0.96,
-                 2013 => 0.97,
-                 2012 => 0.97,
-                 2011 => 0.98,
-                 2010 => 0.98,
-                 2009 => 0.99,
-                 2008 => 0.99,
-             ],
-             '-' => [
-                 2021 => 1.15,
-                 2020 => 1.1,
-                 2019 => 1.07,
-                 2018 => 1.06,
-                 2017 => 1.06,
-                 2016 => 1.05,
-                 2015 => 1.05,
-                 2014 => 1.04,
-                 2013 => 1.04,
-                 2012 => 1.03,
-                 2011 => 1.03,
-                 2010 => 1.02,
-                 2009 => 1.02,
-                 2008 => 1.01,
-                 2007 => 1.01,
-             ]
-         ];
-         foreach($fullItems as $id => $item) {
-             $Cyear = $params['year'];
-             $mYear = $params['year']-1;
-             $pYear = $params['year']+1;
-             $uCoh = false;
-             if($item['year'] == $Cyear) {
-                 $uCoh = 1;
-             }
-             if($item['year'] == $mYear) {
-                 if(isset($yCof['-'][$mYear])) {
-                     $uCoh = $yCof['-'][$mYear];
-                 }
-             }
-             if($item['year'] == $pYear) {
-                 if(isset($yCof['+'][$pYear])) {
-                     $uCoh = $yCof['+'][$pYear];
-                 }
-             }
-             if(!$uCoh) {
-                 unset($fullItems[$id]);
-                 continue;
-             }
-             $fullItems[$id]['newPrice'] = $fullItems[$id]['price']*$uCoh;
-             if($fuelId == 2 && in_array($item['fuelId'],[1,3,4])) {
-                 $fullItems[$id]['newPrice'] *= 1.07;
-             }
-             if($item['fuelId'] == 2 && in_array($fuelId,[1,3,4])) {
-                 $fullItems[$id]['newPrice'] /= 1.07;
-             }
-         }
-         $raceC = [
-             '+' => [
-                 '0-50' => false,
-                 '51-100' => 1.1,
-                 '101-150' => 1.05,
-                 '151-200' => 1.05,
-                 '201-500' => 1.1,
-             ],
-             '-' => [
-                 '0-50' => 0.9,
-                 '51-100' => 0.95,
-                 '101-150' => 0.95,
-                 '151-200' => 0.95,
-             ],
-         ];
-         $mileage = explode('-', $params['mileage']);
-         $mileageFrom = $mileage[0];
-         $mileageTo = $mileage[1];
-         $pKeys = array_keys($raceC['+']);
-         $mKeys = array_keys($raceC['-']);
-         $currentPIndex = array_search($params['mileage'],$pKeys);
-         $currentMIndex = array_search($params['mileage'],$mKeys);
-         $pCofIndex = false;
-         $mCofIndex = false;
-         if($currentPIndex !== false && $currentPIndex > 0 && isset($pKeys[$currentPIndex-1])) {
-             $pCofIndex = $pKeys[$currentPIndex-1];
-         }
-         if($currentMIndex !== false && isset($mKeys[$currentMIndex+1])) {
-             $mCofIndex = $mKeys[$currentMIndex+1];
-         }
-         foreach($fullItems as $id => $item) {
-             $race = $item['raceInt'];
-             $rCof = false;
-             if($race >= $mileageFrom && $race <= $mileageTo) {
-                 $rCof = 1;
-             }
-             if($pCofIndex) {
-                 $arr = explode('-',$pCofIndex);
-                 if($race >= $arr[0] && $race <= $arr[1]) {
-                     $rCof = $raceC['+'][$pKeys[$currentPIndex]];
-                 }
-             }
-             if($mCofIndex) {
-                 $arr = explode('-',$mCofIndex);
-                 if($race >= $arr[0] && $race <= $arr[1]) {
-                     $rCof = $raceC['-'][$mKeys[$currentMIndex]];
-                 }
-             }
-             if(!$rCof) {
-                 unset($fullItems[$id]);
-                 continue;
-             }
-             $fullItems[$id]['newPrice'] *= $rCof;
-         }
-         return $fullItems;
-     }
-     public function updateByNew($params,$result)
-     {
-         $ageCar = (date('Y') - $params['year']) * 12;
-         $ageCar = $ageCar == 0 ? 6 : $ageCar;
-         if ($ageCar <= 60) {
-             $apiParams = [
-                 'markaId' => [$params['brand']['id']],
-                 'modelId' => [$params['model']['id']]
-             ];
-             if (isset($params['fuel']) && $params['fuel']) {
-                 $fuelId = $this->AutoRia->getFuelApi($params['fuel']);
-                 $apiParams = array_merge($apiParams, ['fuelId' => $fuelId]);
-             }
-             if (isset($params['transmission']) && $params['transmission']) {
-                 $gearId = $this->AutoRia->getGearApi($params['transmission']);
-                 $apiParams = array_merge($apiParams, ['gearId' => $gearId]);
-             }
-             $cars = $this->AutoRia->getCars($apiParams);
-             /** @var Markdown $markdown */
-             $markdown = $this->em->getRepository(Markdown::class)->findOneBy(['ria_model_id' => $params['model']['id']]);
-             if(!$markdown) {
-                 $markdown = $this->em->getRepository(Markdown::class)->findOneBy(['ria_brand_id' => $params['brand']['id']]);
-             }
-             if ($cars && count($cars->autos) > 1 && $markdown) {
-                 $avgPrice = 0;
-                 foreach ($cars->autos as $item) {
-                     $avgPrice += $item->price;
-                 }
-                 $avgPrice /= count($cars->autos);
-                 //$avgPrice = array_sum(array_column($cars->autos, 'price')) / count($cars->autos);
-                 $getRetail = 'getRetail' . $ageCar;
-                 $markdownValue = $markdown->$getRetail();
-                 $markdownPrice = round($avgPrice - ($avgPrice * $markdownValue / 100));
-                 if ($result['isSelect']) {
-                     $newPrices = $this->calcPricesUAH(0, $markdownPrice);
-                 } else {
-                     $newPrices = $this->calcPricesUAH($markdownPrice, 0);
-                 }
-                 $result['success'] = true;
-                 if($result['price']) {
-                     $result['price'] = ($markdownPrice + $result['price']) /2;
-                     $result['priceTI'] = ($newPrices['priceTradeIn'] + $result['priceTI']) /2;
-                     $result['priceBuy'] = ($newPrices['priceBuy'] + $result['priceBuy']) /2;
-                     $result['priceSelect'] = ($newPrices['priceSelect'] + $result['priceSelect']) /2;
-                     $result['priceSelectBuy'] = ($newPrices['priceSelectBuy'] + $result['priceSelectBuy']) /2;
-                 } else {
-                     $result['price'] = $markdownPrice;
-                     $result['priceTI'] = $newPrices['priceTradeIn'];
-                     $result['priceBuy'] = $newPrices['priceBuy'];
-                     $result['priceSelect'] = $newPrices['priceSelect'];
-                     $result['priceSelectBuy'] = $newPrices['priceSelectBuy'];
-                 }
-             }
-         }
-         return $result;
-     }
-     public function processEstimateResultNew($result, $params, $dealer = null, $isCRM = false)
-     {
-         $rate = (float) $this->rateModel->getRate();
-         $fullItems = $this->getPrices($result, $params);
-         $pricesArr = [];
-         foreach ($fullItems as $row) {
-             $pricesArr[] = ceil($row['newPrice']);
-         }
-         $price = 0;
-         $priceSelect = 0;
-         if (count($pricesArr) > 3 || ($dealer && $dealer->getId() == 16) ) {
-             $priceSelect = $this->averagePriceItems(40, $pricesArr, true);
-             $price = $this->averagePriceItems(10, $pricesArr);
-         }
-         $prices = $this->calcPricesNew($price, $priceSelect, $this->isSelect($params,$dealer,$isCRM));
-         $vehicle = ($params['brand']['title'] ?? '').' '.($params['model']['title'] ?? '');
-         $year = $params['year'];
-         $hash = md5(time().$price.'salt-retds4346FE#R42');
-         $data = [
-             'isSelect' => $this->isSelect($params,$dealer),
-             'vehicle' => $vehicle,
-             'hash' => $hash,
-             'fullItems' => $fullItems,
-             'countItems' => is_array($fullItems) ? count($fullItems) : 0,
-             'year' => $year,
-             'odometer' => $params['mileage'],
-             'success' => $price > 0,
-             'price' => $price,
-             'rate' => $rate,
-             'priceSelectBase' => $priceSelect,
-             'priceTI' => $prices['priceTradeIn'],
-             'priceBuy' => $prices['priceBuy'],
-             'priceSelect' => $prices['priceSelect'],
-             'priceSelectBuy' => $prices['priceSelectBuy'],
-         ];
-         return $this->updateByNew($params,$data);
-     }
-     /**
-      * @param $result
-      * @param $params
-      * @param null $dealer
-      * @return array
-      * @throws OptimisticLockException
-      */
-     public function processEstimateResult($result, $params, $dealer = null)
-     {
-         $rate = (float) $this->rateModel->getRate();
-         $price = 0;
-         $priceSelect = 0;
-         if (count($result->prices) > 3 || ($dealer && $dealer->getId() == 16) ) {
-             $priceSelect = $this->averagePriceItems(50, $result->prices, true);
-             $price = $this->averagePriceItems(30, $result->prices, false);
-         }
-         $odd = null;
-         $prices = $this->calcPrices($price, $priceSelect, $odd, $this->isSelect($params,$dealer));
-         $vehicle = $params['brand']['title'].' '.$params['model']['title'];
-         $year = $params['year'];
-         $hash = md5(time().$price.'salt-retds4346FE#R42');
-         $data = [
-             'isSelect' => $this->isSelect($params,$dealer),
-             'vehicle' => $vehicle,
-             'hash' => $hash,
-             'year' => $year,
-             'odometer' => $params['mileage'],
-             'success' => $price > 0,
-             'rate' => $rate,
-             'price' => $price,
-             'priceSelectBase' => $priceSelect,
-             'priceTI' => $prices['priceTradeIn'],
-             'priceBuy' => $prices['priceBuy'],
-             'priceSelect' => $prices['priceSelect'],
-             'priceSelectBuy' => $prices['priceSelectBuy'],
-         ];
-         return $data;
-     }
-     public function saveEstimateResult($params, $data, Dealer $dealer = null, User $User = null, $userCar = null, $fromCrm = false) {
-         $estimate = new VehicleEstimate();
-         $estimateResultData = [
-             'request' => $params,
-             'result' => $data,
-         ];
-         $estimate->setDateCreate(new DateTime());
-         $estimate->setDealer($dealer ?? null);
-         $estimate->setIsFinish(0);
-         $estimate->setIsSelect($data['isSelect']);
-         $estimate->setPhone($params['phone'] ?? null);
-         $estimate->setEmail($params['email'] ?? 'CRM');
-         $estimate->setUtm($params['utm']);
-         $estimate->setHref($params['href']);
-         $estimate->setReferrer($params['referrer']);
-         $estimate->setGclId($params['gcl_id']);
-         $estimate->setName($params['name'] ?? null);
-         $estimate->setUser($User ?? null);
-         $estimate->setUserCar($userCar);
-         $estimate->setCrmState(0);
-         $estimate->setHash($data['hash']);
-         $estimate->setIsSend(0);
-         $estimate->setCrmState($fromCrm ? 3 : 0);
-         $estimate->setData(json_encode($estimateResultData));
-         $this->em->persist($estimate);
-         $this->em->flush();
-         return $estimate->getId();
-     }
-     /**
-      * @param VehicleEstimate $estimate
-      * @return array
-      * @throws OptimisticLockException
-      */
-     public function processEstimateEntity(VehicleEstimate $estimate)
-     {
-         $estimateData = json_decode($estimate->getData());
-         return (array) $estimateData->result;
-     }
-     /**
-      * @param $price
-      * @param $priceSelect
-      * @param $odd
-      * @return array
-      * @throws OptimisticLockException
-      */
-     public function calcPricesNew($price, $priceSelect, $isSelect)
-     {
-         $odd = 10;
-         $priceBuyInUSD = round($price * ((100 - $odd) / 100));
-         $priceBuySelectInUSD = round($priceSelect * ((100 - $odd) / 100));
-         $priceTradeInUSD = round($priceBuyInUSD * 1.02);
-         $priceSelectUSD = round($priceBuySelectInUSD);
-         $priceBuy = (float) round($priceBuyInUSD);
-         $priceTradeIn = (float) round($priceTradeInUSD);
-         $priceSelect = (float) round($priceSelectUSD);
-         if($isSelect) {
-             $priceBuy = round($priceSelect / (1 + 0.04));
-         }
-         $prices = [
-             'priceBuyInUSD' => $priceBuyInUSD,
-             'priceBuy' => $priceBuy,
-             'priceTradeIn' => $priceTradeIn,
-             'priceTradeInUSD' => $priceTradeInUSD,
-             'priceSelectUSD' => $priceSelectUSD,
-             'priceSelect' => $priceSelect,
-             'priceSelectBuy' => $priceSelect*0.98,
-             'priceUSD' => $price,
-         ];
-         return $prices;
-     }
-     /**
-      * @param $price
-      * @param $priceSelect
-      * @param $odd
-      * @return array
-      * @throws OptimisticLockException
-      */
-     public function calcPrices($price, $priceSelect, $odd = null, $isSelect)
-     {
-         if (is_null($odd)) {
-             $odd = 10;
-         }
-         $rate = $this->rateModel->getRate();
-         $priceBuyInUSD = round($price * ((100 - $odd) / 100));
-         $priceBuySelectInUSD = round($priceSelect * ((100 - $odd) / 100));
-         $priceTradeInUSD = round($priceBuyInUSD * 1.02);
-         $priceSelectUSD = round($priceBuySelectInUSD);
-         $priceBuy = (float) round($priceBuyInUSD * $rate);
-         $priceTradeIn = (float) round($priceTradeInUSD * $rate);
-         $priceSelect = (float) round($priceSelectUSD * $rate);
-         if($isSelect) {
-             $priceBuy = round($priceSelect / (1 + 0.04));
-         }
-         $prices = [
-             'priceBuyInUSD' => $priceBuyInUSD,
-             'rate' => $rate,
-             'priceBuy' => $priceBuy,
-             'priceTradeIn' => $priceTradeIn,
-             'priceTradeInUSD' => $priceTradeInUSD,
-             'priceSelectUSD' => $priceSelectUSD,
-             'priceSelect' => $priceSelect,
-             'priceSelectBuy' => $priceSelect*0.98,
-             'priceUSD' => $price,
-         ];
-         return $prices;
-     }
-     public function calcPricesUAH($price, $priceSelect, $odd = null)
-     {
-         if (is_null($odd)) {
-             $odd = 10;
-         }
-         $priceBuy = round($price * ((100 - $odd) / 100));
-         $priceBuySelect = round($priceSelect * ((100 - $odd) / 100));
-         $priceBuyTradeIn = round(($priceSelect ? $priceBuySelect : $priceBuy) * 1.02);
-         if($priceSelect) {
-             $priceBuy = $priceBuySelect * 0.98;
-         }
-         return [
-             'priceBuy' => $priceBuy,
-             'priceTradeIn' => $priceBuyTradeIn,
-             'priceSelect' => $priceBuySelect,
-             'priceSelectBuy' => $priceBuySelect*0.98,
-         ];
-     }
-     private function averagePriceItems($percent, $priceItems , $isReverse = false)
-     {
-         if(count($priceItems) > 3) {
-             $isReverse ? rsort($priceItems) : sort($priceItems);
-             $offset = floor(count($priceItems) * 10 / 100);
-             $offset = $offset < 1 ? 1 : $offset;
-             $limit = floor(count($priceItems) * $percent / 100);
-             $limit = $limit < 1 ? 1 : $limit;
-             $length = count($priceItems) - $offset - $limit;
-             $priceItems = array_slice($priceItems, $offset, $length);
-             return round(array_sum($priceItems) / count($priceItems));
-         }
-         else
-         {
-             return null;
-         }
-     }
- }
-