<?php
namespace App\Controller\Api;
use App\Env;
use stdClass;
use App\Entity\City;
use App\Entity\Page;
use App\Entity\Region;
use App\Entity\PostOffice;
use App\Entity\Translation\CityTranslation;
use App\Service\Dadata\Address;
use App\Repository\CityRepository;
use App\Repository\RegionRepository;
use App\Service\Delivery\Provider\NP;
use App\Repository\PostofficeRepository;
use Doctrine\ORM\EntityManagerInterface;
use App\Service\Delivery\ProviderFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class DeliveryController extends AbstractController
{
protected EntityManagerInterface $em;
protected $default_region_id = '0c5b2444-70a0-4932-980c-b4dc0d3f02b5';
protected $default_city_id = '0c5b2444-70a0-4932-980c-b4dc0d3f02b5';
//Repositories
protected RegionRepository $Regions;
protected CityRepository $Cities;
protected PostofficeRepository $Postoffices;
public function __construct(EntityManagerInterface $em, private CityRepository $cityRepository)
{
if(Env::site() == Env::DOM || Env::site() == Env::OPT) {
$default_region_id = 'dcaadb64-4b33-11e4-ab6d-005056801329';
$default_city_id = 'e718a680-4b33-11e4-ab6d-005056801329';
}
$this->em = $em;
$this->Regions = $this->em->getRepository(Region::class);
$this->Cities = $this->em->getRepository(City::class);
$this->Postoffices = $this->em->getRepository(PostOffice::class);
}
// Показать все почтовые отделения в городе
#[Route('/api/delivery/getoffices', name: 'api_delivery_getoffices_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/delivery/getoffices', name: 'api_delivery_getoffices', requirements: ['_locale' => '%app.langs%'])]
public function getoffices(Request $request): Response
{
$city = (string) $request->query->get('city');
$fias = (string) $request->query->get('fias');
$lon = (string) $request->query->get('lon');
$lat = (string) $request->query->get('lat');
$delivery_intname = (string) $request->query->get('delivery_id');
$Delivery = ProviderFactory::factory($delivery_intname, $this->em, $request);
$offices = $Delivery->getOffices($this->Postoffices, $city, $lat, $lon);
return $this->json($offices);
}
// Показать адрес
#[Route('/api/delivery/getaddress', name: 'api_delivery_getaddress_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/delivery/getaddress', name: 'api_delivery_getaddress', requirements: ['_locale' => '%app.langs%'])]
public function getaddress(Request $request): Response
{
$city = (string) $request->query->get('city');
$address = (string) $request->query->get('address');
$addr = Address::getAddress($address);
return $this->json($addr);
}
// Расчет стоимости доставки
#[Route('/api/delivery/getprice', name: 'api_delivery_getprice_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/delivery/getprice', name: 'api_delivery_getprice', requirements: ['_locale' => '%app.langs%'])]
public function getprice(Request $request): Response
{
$city = (string) $request->query->get('city');
$sub = (string) $request->query->get('subdelivery_id');
$fias = (string) $request->query->get('fias');
$weight = (float) $request->query->get('weight');
$amount = (float) $request->query->get('amount');
$delivery_intname = (string) $request->query->get('delivery_id');
$Delivery = ProviderFactory::factory($delivery_intname, $this->em, $request);
$res = $Delivery->calculate($city, $sub, $weight);
// if (($amount >= (int) $sett['free_delivery_amount'])&&(!Auth::isOpt())) {
// $res->sum = 0;
// }
return $this->json($res);
}
// Список регионов
#[Route('/api/delivery/getregions', name: 'api_delivery_getregions_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/delivery/getregions', name: 'api_delivery_getregions', requirements: ['_locale' => '%app.langs%'])]
public function getregions(Request $request): Response
{
$response = [];
$response['regions'] = [];
// $response['regions'] = $this->em->createQuery("SELECT r.id, r.fias_id, r.name, r.prior, r.visible FROM App\Entity\Region r WHERE r.visible = 1 ORDER BY r.name ASC")->getResult();
$regions = $this->Regions->findBy(
['visible' => 1],
['name' => 'ASC']
);
if(Env::site() == Env::MIR || Env::site() == Env::OPT_MIR) {
} else {
$i = 299;
$cc = count($regions) / 3 - 1;
$c = 0;
foreach ($regions as $k => $region) {
$response['regions'][$k]['id'] = $region->getId();
$response['regions'][$k]['fias_id'] = $region->getFiasId();
$response['regions'][$k]['name'] = $region->getName();
$response['regions'][$k]['visible'] = $region->isVisible();
$response['regions'][$k]['prior'] = $i;
// $region->setPrior($i);
if ($c > $cc * 2) {
$i = 99;
} elseif ($c > $cc - 1) {
$i = 199;
}
$c++;
}
}
/** @var \App\Entity\City[] $cities */
$cities = $this->em->createQuery("SELECT c FROM App\Entity\City c WHERE c.visible = 1 and c.top > 0 ORDER BY c.top DESC")->getResult();
$response['cities'] = [];
foreach ($cities as $k => $city) {
$response['cities'][$k]['id'] = $city->getId();
$response['cities'][$k]['fias_id'] = $city->getFiasId();
$response['cities'][$k]['name'] = $city->getName();
$response['cities'][$k]['postal_code'] = $city->getPostalCode();
$response['cities'][$k]['type'] = $city->getType();
$response['cities'][$k]['prior'] = $city->getPrior();
$response['cities'][$k]['visible'] = $city->isVisible();
$response['cities'][$k]['top'] = $city->isTop();
}
return $this->json($response);
}
// Список городов
#[Route('/api/delivery/getcities', name: 'api_delivery_getcities_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/delivery/getcities', name: 'api_delivery_getcities', requirements: ['_locale' => '%app.langs%'])]
public function getcities(Request $request): Response
{
$region = (int) $request->query->get('region');
$cities_array = [];
if(Env::site() == Env::MIR || Env::site() == Env::OPT_MIR) {
//$cities = $City->getall(['where' => 'visible=1 and region=' . (int)$_GET['region'], 'order' => 'prior desc']);
$cities_array = $this->em->createQuery("SELECT c.id, c.region, c.fias_id, c.name, c.postal_code, c.type, c.prior, c.visible, c.top, c.top2 FROM App\Entity\City c WHERE c.visible = 1 and c.region = ".$region." ORDER BY c.prior DESC")->getResult();
} else {
//$cities = $City->getall(['where' => 'visible=1 and top2=1 and region=' . (int)$_GET['region'], 'order' => '`type` desc, name asc']);
// $cities = $this->em->createQuery("SELECT c.id, c.region, c.fias_id, c.name, c.postal_code, c.type, c.prior, c.visible, c.top, c.top2 FROM App\Entity\City c WHERE c.visible = 1 and c.top2 = 1 and c.region = ".$region." ORDER BY c.prior DESC")->getResult();
$cities = $this->cityRepository->getTop2ByRegion($region);
$i = 299;
$cc = count($cities)/3-1;
$c = 0;
foreach ($cities as $k => $city) {
$city->setPrior($i);
if ($c > $cc * 2) {
$i = 99;
} elseif ($c > $cc) {
$i = 199;
}
$c++;
$cities_array[] = [
"id" => $city->getId(),
"region" => $city->getRegion(),
"fias_id" => $city->getFiasId(),
"name" => $city->getName(),
"postal_code" => $city->getPostalCode(),
"type" => $city->getType(),
"prior" => $city->getPrior(),
"visible" => (int) $city->isVisible(),
"top" => (int) $city->isTop(),
"top2" => (int) $city->isTop2(),
];
}
}
return $this->json($cities_array);
}
// Список регионов НП
#[Route('/api/delivery/setregions', name: 'api_delivery_setregions_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/delivery/setregions', name: 'api_delivery_setregions', requirements: ['_locale' => '%app.langs%'])]
public function setregions(Request $request): Response
{
$NP = new NP($this->em, $request);
$cities = $NP->getCities();
$regions = [];
foreach ($cities as $city) {
$regions[$city['Area']] = ['fias_id' => $city['Area'], 'name' => $city['AreaDescriptionRu']];
}
foreach ($regions as $k => $v) {
$regions_num = $this->em->createQuery("SELECT r.id FROM App\Entity\Region r WHERE r.fias_id = '".$v['fias_id']."'")->getResult();
if (count($regions_num) == 0) {
$Region = new Region();
$Region->setFiasId($v['fias_id']);
$Region->setName($v['name']);
$this->em->persist($Region);
}
}
$this->em->flush();
$response = [];
return $this->json($response);
}
// Список городов НП
#[Route('/api/delivery/setcities', name: 'api_delivery_setcities_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/delivery/setcities', name: 'api_delivery_setcities', requirements: ['_locale' => '%app.langs%'])]
public function setcities(Request $request): Response
{
set_time_limit(0);
$region_fias = [];
$NP = new NP($this->em, $request);
$regions = $this->Regions->findAll();
$added = 0;
foreach ($regions as $r) {
$region_fias[$r->getFiasId()] = $r->getId();
}
$cities = $NP->getCities();
$i = 0;
foreach ($cities as $city) {
$type = str_replace("поселок городского типа", "пгт.", $city['SettlementTypeDescriptionRu']);
$type = str_replace(["город", "село"], ["г.", "с."], $type);
$city_num = $this->em->createQuery("SELECT c.id FROM App\Entity\City c WHERE c.fias_id = '".$city['Ref']."'")->getResult();
if (count($city_num) == 0) {
$added++;
$top = ($city['SettlementTypeDescriptionRu'] == 'город') ? 1 : 0;
$City = new City();
$City->setRegion((int) $region_fias[$city['Area']]);
$City->setName($city['DescriptionRu']);
$City->setFiasId($city['Ref']);
$City->setType($type);
$City->setPostalCode($city['Index1']);
$City->setTop2($top);
$City->setPrior(0);
$City->setVisible(true);
$this->em->persist($City);
$this->em->flush();
$ukName = new CityTranslation('uk', 'name', $city['Description']);
$City->addTranslation($ukName);
$this->em->persist($City);
if ($i++ > 100) {
$this->em->flush();
$i = 0;
}
}
$this->em->flush();
}
return $this->json($cities);
}
// Список отделений НП
#[Route('/api/delivery/setoffices', name: 'api_delivery_setoffices_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/delivery/setoffices', name: 'api_delivery_setoffices', requirements: ['_locale' => '%app.langs%'])]
public function setoffices(Request $request): Response
{
set_time_limit(0);
$NP = new NP($this->em, $request);
$cities = $this->Cities->findAll();
foreach ($cities as $city) {
$offices = $NP->getOfficesFromApi($city->getFiasId());
echo $city->getName().": ".count($offices)."<br>";
foreach ($offices as $office) {
$office_num = $this->em->createQuery("SELECT p.id FROM App\Entity\PostOffice p WHERE p.code = '".$office['Ref']."'")->getResult();
if (count($office_num) == 0) {
$PO = new PostOffice();
$PO->setDelivery('np');
$PO->setName($office['DescriptionRu']);
$PO->setAddress($office['ShortAddressRu']);
$PO->setLat($office['Latitude']);
$PO->setLon($office['Longitude']);
$PO->setWorktime($office["worktime"]);
$PO->setPostcode($city->getPostalCode());
$PO->setCode($office['Ref']);
$PO->setComment($office['Number']);
$PO->setPhone($office['Phone']);
$PO->setUpdated(time());
$this->em->persist($PO);
}
}
}
$this->em->flush();
$response = ["status" => "ok"];
return $this->json($response);
}
}