src/CoreBundle/Model/OnlineEstimateModel.php line 475

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by PhpStorm.
  4.  * User: serhii.patsai
  5.  * Date: 11.09.2019
  6.  * Time: 12:27
  7.  */
  8. namespace CoreBundle\Model;
  9. use DateTime;
  10. use CoreBundle\Entity\User;
  11. use CoreBundle\Entity\Dealer;
  12. use CoreBundle\Entity\VehicleEstimate;
  13. use CoreBundle\Factory\Vehicle;
  14. use CoreBundle\Model\Api\AutoRia\AutoRia;
  15. use CoreBundle\Model\Vehicles\Repository;
  16. use DcSiteBundle\Entity\Markdown;
  17. use Doctrine\ORM\EntityManagerInterface;
  18. use Doctrine\ORM\OptimisticLockException;
  19. class OnlineEstimateModel
  20. {
  21.     /**
  22.      * @var Rate
  23.      */
  24.     private $rateModel;
  25.     /**
  26.      * @var EntityManagerInterface
  27.      */
  28.     private $em;
  29.     /**
  30.      * @var AutoRia
  31.      */
  32.     private $AutoRia;
  33.     /**
  34.      * OnlineEstimateModel constructor.
  35.      * @param Rate $rate
  36.      * @param EntityManagerInterface $em
  37.      * @param Vehicle $VehicleFactory
  38.      * @param Repository $repository
  39.      */
  40.     public function __construct(Rate $rateEntityManagerInterface $emAutoRia $AutoRia)
  41.     {
  42.         $this->rateModel $rate;
  43.         $this->em $em;
  44.         $this->AutoRia $AutoRia;
  45.     }
  46.     private function isSelect($params$dealer null$isCRM false) {
  47.         $old = (new DateTime())->format('Y')-$params['year'];
  48.         $mileage explode('-'$params['mileage']);
  49.         if (count($mileage) == 2) {
  50.             $mileageTo $mileage[1];
  51.         } else {
  52.             $mileage $params['mileage'] < 1000 $params['mileage'] : ceil($params['mileage']/1000);
  53.             $mileageTo $mileage + ($mileage*0.60);
  54.         }
  55.         $dealerInProgram = !$dealer || in_array($dealer->getId(), [8,27,35,34,3,29,28,32,33,37,38,15,30,9,31,39]);
  56.         $isOurBrand in_array($params['brand']['id'], [55,47,58,75,24,15,76,31,37,28,128,85,56,5456,49]);
  57.         $inOld $old <=5;
  58.         $inMileage $mileageTo <= 100;
  59.         return $dealerInProgram && $isOurBrand && $inOld && $inMileage;
  60.     }
  61.     public function getPrices($estimate$params)
  62.     {
  63.         $itemIds = [];
  64.         foreach ($estimate->result->search_result_common->data as $row) {
  65.             if($row->type == 'UsedAuto') {
  66.                 $itemIds[] = $row->id;
  67.             }
  68.         }
  69.         $fullItems = [];
  70.         $fuelId $params['fuel'];
  71.         foreach ($itemIds as $id) {
  72.             $data $this->AutoRia->getFullInfo($id);
  73.             if(!$data) {
  74.                 continue;
  75.             }
  76.             if(in_array($fuelId,[1,2,3,4]) && !in_array($data->autoData->fuelId,[1,2,3,4])) {
  77.                 continue;
  78.             }
  79.             $item['price'] = $data->UAH;
  80.             $item['year'] = $data->autoData->year;
  81.             $item['raceInt'] = $data->autoData->raceInt;
  82.             $item['fuelId'] = $data->autoData->fuelId;
  83.             $item['gearBoxId'] = $data->autoData->gearBoxId ?? null;
  84.             $fullItems[$id] = $item;
  85.         }
  86.         $yCof = [
  87.             '+' => [
  88.                 2022 => 0.85,
  89.                 2021 => 0.9,
  90.                 2020 => 0.93,
  91.                 2019 => 0.94,
  92.                 2018 => 0.94,
  93.                 2017 => 0.95,
  94.                 2016 => 0.95,
  95.                 2015 => 0.96,
  96.                 2014 => 0.96,
  97.                 2013 => 0.97,
  98.                 2012 => 0.97,
  99.                 2011 => 0.98,
  100.                 2010 => 0.98,
  101.                 2009 => 0.99,
  102.                 2008 => 0.99,
  103.             ],
  104.             '-' => [
  105.                 2021 => 1.15,
  106.                 2020 => 1.1,
  107.                 2019 => 1.07,
  108.                 2018 => 1.06,
  109.                 2017 => 1.06,
  110.                 2016 => 1.05,
  111.                 2015 => 1.05,
  112.                 2014 => 1.04,
  113.                 2013 => 1.04,
  114.                 2012 => 1.03,
  115.                 2011 => 1.03,
  116.                 2010 => 1.02,
  117.                 2009 => 1.02,
  118.                 2008 => 1.01,
  119.                 2007 => 1.01,
  120.             ]
  121.         ];
  122.         foreach($fullItems as $id => $item) {
  123.             $Cyear $params['year'];
  124.             $mYear $params['year']-1;
  125.             $pYear $params['year']+1;
  126.             $uCoh false;
  127.             if($item['year'] == $Cyear) {
  128.                 $uCoh 1;
  129.             }
  130.             if($item['year'] == $mYear) {
  131.                 if(isset($yCof['-'][$mYear])) {
  132.                     $uCoh $yCof['-'][$mYear];
  133.                 }
  134.             }
  135.             if($item['year'] == $pYear) {
  136.                 if(isset($yCof['+'][$pYear])) {
  137.                     $uCoh $yCof['+'][$pYear];
  138.                 }
  139.             }
  140.             if(!$uCoh) {
  141.                 unset($fullItems[$id]);
  142.                 continue;
  143.             }
  144.             $fullItems[$id]['newPrice'] = $fullItems[$id]['price']*$uCoh;
  145.             if($fuelId == && in_array($item['fuelId'],[1,3,4])) {
  146.                 $fullItems[$id]['newPrice'] *= 1.07;
  147.             }
  148.             if($item['fuelId'] == && in_array($fuelId,[1,3,4])) {
  149.                 $fullItems[$id]['newPrice'] /= 1.07;
  150.             }
  151.         }
  152.         $raceC = [
  153.             '+' => [
  154.                 '0-50' => false,
  155.                 '51-100' => 1.1,
  156.                 '101-150' => 1.05,
  157.                 '151-200' => 1.05,
  158.                 '201-500' => 1.1,
  159.             ],
  160.             '-' => [
  161.                 '0-50' => 0.9,
  162.                 '51-100' => 0.95,
  163.                 '101-150' => 0.95,
  164.                 '151-200' => 0.95,
  165.             ],
  166.         ];
  167.         $mileage explode('-'$params['mileage']);
  168.         $mileageFrom $mileage[0];
  169.         $mileageTo $mileage[1];
  170.         $pKeys array_keys($raceC['+']);
  171.         $mKeys array_keys($raceC['-']);
  172.         $currentPIndex array_search($params['mileage'],$pKeys);
  173.         $currentMIndex array_search($params['mileage'],$mKeys);
  174.         $pCofIndex false;
  175.         $mCofIndex false;
  176.         if($currentPIndex !== false && $currentPIndex && isset($pKeys[$currentPIndex-1])) {
  177.             $pCofIndex $pKeys[$currentPIndex-1];
  178.         }
  179.         if($currentMIndex !== false && isset($mKeys[$currentMIndex+1])) {
  180.             $mCofIndex $mKeys[$currentMIndex+1];
  181.         }
  182.         foreach($fullItems as $id => $item) {
  183.             $race $item['raceInt'];
  184.             $rCof false;
  185.             if($race >= $mileageFrom && $race <= $mileageTo) {
  186.                 $rCof 1;
  187.             }
  188.             if($pCofIndex) {
  189.                 $arr explode('-',$pCofIndex);
  190.                 if($race >= $arr[0] && $race <= $arr[1]) {
  191.                     $rCof $raceC['+'][$pKeys[$currentPIndex]];
  192.                 }
  193.             }
  194.             if($mCofIndex) {
  195.                 $arr explode('-',$mCofIndex);
  196.                 if($race >= $arr[0] && $race <= $arr[1]) {
  197.                     $rCof $raceC['-'][$mKeys[$currentMIndex]];
  198.                 }
  199.             }
  200.             if(!$rCof) {
  201.                 unset($fullItems[$id]);
  202.                 continue;
  203.             }
  204.             $fullItems[$id]['newPrice'] *= $rCof;
  205.         }
  206.         return $fullItems;
  207.     }
  208.     public function updateByNew($params,$result)
  209.     {
  210.         $ageCar = (date('Y') - $params['year']) * 12;
  211.         $ageCar $ageCar == $ageCar;
  212.         if ($ageCar <= 60) {
  213.             $apiParams = [
  214.                 'markaId' => [$params['brand']['id']],
  215.                 'modelId' => [$params['model']['id']]
  216.             ];
  217.             if (isset($params['fuel']) && $params['fuel']) {
  218.                 $fuelId $this->AutoRia->getFuelApi($params['fuel']);
  219.                 $apiParams array_merge($apiParams, ['fuelId' => $fuelId]);
  220.             }
  221.             if (isset($params['transmission']) && $params['transmission']) {
  222.                 $gearId $this->AutoRia->getGearApi($params['transmission']);
  223.                 $apiParams array_merge($apiParams, ['gearId' => $gearId]);
  224.             }
  225.             $cars $this->AutoRia->getCars($apiParams);
  226.             /** @var Markdown $markdown */
  227.             $markdown $this->em->getRepository(Markdown::class)->findOneBy(['ria_model_id' => $params['model']['id']]);
  228.             if(!$markdown) {
  229.                 $markdown $this->em->getRepository(Markdown::class)->findOneBy(['ria_brand_id' => $params['brand']['id']]);
  230.             }
  231.             if ($cars && count($cars->autos) > && $markdown) {
  232.                 $avgPrice 0;
  233.                 foreach ($cars->autos as $item) {
  234.                     $avgPrice += $item->price;
  235.                 }
  236.                 $avgPrice /= count($cars->autos);
  237.                 //$avgPrice = array_sum(array_column($cars->autos, 'price')) / count($cars->autos);
  238.                 $getRetail 'getRetail' $ageCar;
  239.                 $markdownValue $markdown->$getRetail();
  240.                 $markdownPrice round($avgPrice - ($avgPrice $markdownValue 100));
  241.                 if ($result['isSelect']) {
  242.                     $newPrices $this->calcPricesUAH(0$markdownPrice);
  243.                 } else {
  244.                     $newPrices $this->calcPricesUAH($markdownPrice0);
  245.                 }
  246.                 $result['success'] = true;
  247.                 if($result['price']) {
  248.                     $result['price'] = ($markdownPrice $result['price']) /2;
  249.                     $result['priceTI'] = ($newPrices['priceTradeIn'] + $result['priceTI']) /2;
  250.                     $result['priceBuy'] = ($newPrices['priceBuy'] + $result['priceBuy']) /2;
  251.                     $result['priceSelect'] = ($newPrices['priceSelect'] + $result['priceSelect']) /2;
  252.                     $result['priceSelectBuy'] = ($newPrices['priceSelectBuy'] + $result['priceSelectBuy']) /2;
  253.                 } else {
  254.                     $result['price'] = $markdownPrice;
  255.                     $result['priceTI'] = $newPrices['priceTradeIn'];
  256.                     $result['priceBuy'] = $newPrices['priceBuy'];
  257.                     $result['priceSelect'] = $newPrices['priceSelect'];
  258.                     $result['priceSelectBuy'] = $newPrices['priceSelectBuy'];
  259.                 }
  260.             }
  261.         }
  262.         return $result;
  263.     }
  264.     public function processEstimateResultNew($result$params$dealer null$isCRM false)
  265.     {
  266.         $rate = (float) $this->rateModel->getRate();
  267.         $fullItems $this->getPrices($result$params);
  268.         $pricesArr = [];
  269.         foreach ($fullItems as $row) {
  270.             $pricesArr[] = ceil($row['newPrice']);
  271.         }
  272.         $price 0;
  273.         $priceSelect 0;
  274.         if (count($pricesArr) > || ($dealer && $dealer->getId() == 16) ) {
  275.             $priceSelect $this->averagePriceItems(40$pricesArrtrue);
  276.             $price $this->averagePriceItems(10$pricesArr);
  277.         }
  278.         $prices $this->calcPricesNew($price$priceSelect$this->isSelect($params,$dealer,$isCRM));
  279.         $vehicle = ($params['brand']['title'] ?? '').' '.($params['model']['title'] ?? '');
  280.         $year $params['year'];
  281.         $hash md5(time().$price.'salt-retds4346FE#R42');
  282.         $data = [
  283.             'isSelect' => $this->isSelect($params,$dealer),
  284.             'vehicle' => $vehicle,
  285.             'hash' => $hash,
  286.             'fullItems' => $fullItems,
  287.             'countItems' => is_array($fullItems) ? count($fullItems) : 0,
  288.             'year' => $year,
  289.             'odometer' => $params['mileage'],
  290.             'success' => $price 0,
  291.             'price' => $price,
  292.             'rate' => $rate,
  293.             'priceSelectBase' => $priceSelect,
  294.             'priceTI' => $prices['priceTradeIn'],
  295.             'priceBuy' => $prices['priceBuy'],
  296.             'priceSelect' => $prices['priceSelect'],
  297.             'priceSelectBuy' => $prices['priceSelectBuy'],
  298.         ];
  299.         return $this->updateByNew($params,$data);
  300.     }
  301.     /**
  302.      * @param $result
  303.      * @param $params
  304.      * @param null $dealer
  305.      * @return array
  306.      * @throws OptimisticLockException
  307.      */
  308.     public function processEstimateResult($result$params$dealer null)
  309.     {
  310.         $rate = (float) $this->rateModel->getRate();
  311.         $price 0;
  312.         $priceSelect 0;
  313.         if (count($result->prices) > || ($dealer && $dealer->getId() == 16) ) {
  314.             $priceSelect $this->averagePriceItems(50$result->pricestrue);
  315.             $price $this->averagePriceItems(30$result->pricesfalse);
  316.         }
  317.         $odd null;
  318.         $prices $this->calcPrices($price$priceSelect$odd$this->isSelect($params,$dealer));
  319.         $vehicle $params['brand']['title'].' '.$params['model']['title'];
  320.         $year $params['year'];
  321.         $hash md5(time().$price.'salt-retds4346FE#R42');
  322.         $data = [
  323.             'isSelect' => $this->isSelect($params,$dealer),
  324.             'vehicle' => $vehicle,
  325.             'hash' => $hash,
  326.             'year' => $year,
  327.             'odometer' => $params['mileage'],
  328.             'success' => $price 0,
  329.             'rate' => $rate,
  330.             'price' => $price,
  331.             'priceSelectBase' => $priceSelect,
  332.             'priceTI' => $prices['priceTradeIn'],
  333.             'priceBuy' => $prices['priceBuy'],
  334.             'priceSelect' => $prices['priceSelect'],
  335.             'priceSelectBuy' => $prices['priceSelectBuy'],
  336.         ];
  337.         return $data;
  338.     }
  339.     public function saveEstimateResult($params$dataDealer $dealer nullUser $User null$userCar null$fromCrm false) {
  340.         $estimate = new VehicleEstimate();
  341.         $estimateResultData = [
  342.             'request' => $params,
  343.             'result' => $data,
  344.         ];
  345.         $estimate->setDateCreate(new DateTime());
  346.         $estimate->setDealer($dealer ?? null);
  347.         $estimate->setIsFinish(0);
  348.         $estimate->setIsSelect($data['isSelect']);
  349.         $estimate->setPhone($params['phone'] ?? null);
  350.         $estimate->setEmail($params['email'] ?? 'CRM');
  351.         $estimate->setUtm($params['utm']);
  352.         $estimate->setHref($params['href']);
  353.         $estimate->setReferrer($params['referrer']);
  354.         $estimate->setGclId($params['gcl_id']);
  355.         $estimate->setName($params['name'] ?? null);
  356.         $estimate->setUser($User ?? null);
  357.         $estimate->setUserCar($userCar);
  358.         $estimate->setCrmState(0);
  359.         $estimate->setHash($data['hash']);
  360.         $estimate->setIsSend(0);
  361.         $estimate->setCrmState($fromCrm 0);
  362.         $estimate->setData(json_encode($estimateResultData));
  363.         $this->em->persist($estimate);
  364.         $this->em->flush();
  365.         return $estimate->getId();
  366.     }
  367.     /**
  368.      * @param VehicleEstimate $estimate
  369.      * @return array
  370.      * @throws OptimisticLockException
  371.      */
  372.     public function processEstimateEntity(VehicleEstimate $estimate)
  373.     {
  374.         $estimateData json_decode($estimate->getData());
  375.         return (array) $estimateData->result;
  376.     }
  377.     /**
  378.      * @param $price
  379.      * @param $priceSelect
  380.      * @param $odd
  381.      * @return array
  382.      * @throws OptimisticLockException
  383.      */
  384.     public function calcPricesNew($price$priceSelect$isSelect)
  385.     {
  386.         $odd 10;
  387.         $priceBuyInUSD round($price * ((100 $odd) / 100));
  388.         $priceBuySelectInUSD round($priceSelect * ((100 $odd) / 100));
  389.         $priceTradeInUSD round($priceBuyInUSD 1.02);
  390.         $priceSelectUSD round($priceBuySelectInUSD);
  391.         $priceBuy = (float) round($priceBuyInUSD);
  392.         $priceTradeIn = (float) round($priceTradeInUSD);
  393.         $priceSelect = (float) round($priceSelectUSD);
  394.         if($isSelect) {
  395.             $priceBuy round($priceSelect / (0.04));
  396.         }
  397.         $prices = [
  398.             'priceBuyInUSD' => $priceBuyInUSD,
  399.             'priceBuy' => $priceBuy,
  400.             'priceTradeIn' => $priceTradeIn,
  401.             'priceTradeInUSD' => $priceTradeInUSD,
  402.             'priceSelectUSD' => $priceSelectUSD,
  403.             'priceSelect' => $priceSelect,
  404.             'priceSelectBuy' => $priceSelect*0.98,
  405.             'priceUSD' => $price,
  406.         ];
  407.         return $prices;
  408.     }
  409.     /**
  410.      * @param $price
  411.      * @param $priceSelect
  412.      * @param $odd
  413.      * @return array
  414.      * @throws OptimisticLockException
  415.      */
  416.     public function calcPrices($price$priceSelect$odd null$isSelect)
  417.     {
  418.         if (is_null($odd)) {
  419.             $odd 10;
  420.         }
  421.         $rate $this->rateModel->getRate();
  422.         $priceBuyInUSD round($price * ((100 $odd) / 100));
  423.         $priceBuySelectInUSD round($priceSelect * ((100 $odd) / 100));
  424.         $priceTradeInUSD round($priceBuyInUSD 1.02);
  425.         $priceSelectUSD round($priceBuySelectInUSD);
  426.         $priceBuy = (float) round($priceBuyInUSD $rate);
  427.         $priceTradeIn = (float) round($priceTradeInUSD $rate);
  428.         $priceSelect = (float) round($priceSelectUSD $rate);
  429.         if($isSelect) {
  430.             $priceBuy round($priceSelect / (0.04));
  431.         }
  432.         $prices = [
  433.             'priceBuyInUSD' => $priceBuyInUSD,
  434.             'rate' => $rate,
  435.             'priceBuy' => $priceBuy,
  436.             'priceTradeIn' => $priceTradeIn,
  437.             'priceTradeInUSD' => $priceTradeInUSD,
  438.             'priceSelectUSD' => $priceSelectUSD,
  439.             'priceSelect' => $priceSelect,
  440.             'priceSelectBuy' => $priceSelect*0.98,
  441.             'priceUSD' => $price,
  442.         ];
  443.         return $prices;
  444.     }
  445.     public function calcPricesUAH($price$priceSelect$odd null)
  446.     {
  447.         if (is_null($odd)) {
  448.             $odd 10;
  449.         }
  450.         $priceBuy round($price * ((100 $odd) / 100));
  451.         $priceBuySelect round($priceSelect * ((100 $odd) / 100));
  452.         $priceBuyTradeIn round(($priceSelect $priceBuySelect $priceBuy) * 1.02);
  453.         if($priceSelect) {
  454.             $priceBuy $priceBuySelect 0.98;
  455.         }
  456.         return [
  457.             'priceBuy' => $priceBuy,
  458.             'priceTradeIn' => $priceBuyTradeIn,
  459.             'priceSelect' => $priceBuySelect,
  460.             'priceSelectBuy' => $priceBuySelect*0.98,
  461.         ];
  462.     }
  463.     private function averagePriceItems($percent$priceItems $isReverse false)
  464.     {
  465.         if(count($priceItems) > 3) {
  466.             $isReverse rsort($priceItems) : sort($priceItems);
  467.             $offset floor(count($priceItems) * 10 100);
  468.             $offset $offset $offset;
  469.             $limit floor(count($priceItems) * $percent 100);
  470.             $limit $limit $limit;
  471.             $length count($priceItems) - $offset $limit;
  472.             $priceItems array_slice($priceItems$offset$length);
  473.             return round(array_sum($priceItems) / count($priceItems));
  474.         }
  475.         else
  476.         {
  477.             return null;
  478.         }
  479.     }
  480. }