<?php
namespace App\Controller\Api;
use App\Env;
use App\Func;
use stdClass;
use App\Entity\City;
use App\Entity\Page;
use App\Entity\User;
use App\Entity\Region;
use App\Entity\Esystem;
use App\Entity\Delivery;
use App\Service\Auth\Auth;
use App\Service\Cart\Cart;
use App\Repository\CityRepository;
use App\Repository\UserRepository;
use App\Service\Checkout\Checkout;
use App\Repository\RegionRepository;
use App\Repository\EsystemRepository;
use App\Repository\DeliveryRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class CheckoutController extends AbstractController
{
protected EntityManagerInterface $em;
protected $default_region_id = '0c5b2444-70a0-4932-980c-b4dc0d3f02b5';
protected $default_city_id = '0c5b2444-70a0-4932-980c-b4dc0d3f02b5';
protected Checkout $Checkout;
protected Cart $Cart;
protected User $User;
protected Auth $Auth;
//Repositories
protected RegionRepository $Regions;
protected CityRepository $Cities;
protected DeliveryRepository $Deliveries;
protected EsystemRepository $Esystems;
protected UserRepository $Users;
public function __construct(EntityManagerInterface $em, Checkout $Checkout, Cart $Cart, Auth $Auth, Security $security)
{
if (Env::site() == Env::DOM || Env::site() == Env::OPT) {
$this->default_region_id = 'dcaadb64-4b33-11e4-ab6d-005056801329';
$this->default_city_id = 'e718a680-4b33-11e4-ab6d-005056801329';
}
$this->em = $em;
$this->Checkout = $Checkout;
$this->Cart = $Cart;
$this->Auth = $Auth;
$this->Auth->setUser($security->getUser());
$this->Regions = $this->em->getRepository(Region::class);
$this->Cities = $this->em->getRepository(City::class);
$this->Deliveries = $this->em->getRepository(Delivery::class);
$this->Esystems = $this->em->getRepository(Esystem::class);
$this->Users = $this->em->getRepository(User::class);
}
// Разделение строки на фамилию, имя, определение пола
#[Route(path: '/api/checkout/cleanname', name: 'api_checkout_cleanname_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/cleanname', name: 'api_checkout_cleanname', requirements: ['_locale' => '%app.langs%'])]
public function cleanname(Request $request): Response
{
$fullname = (string) $request->query->get('fullname');
$curl = curl_init();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Token ' . Env::code_dadata();
$headers[] = 'X-Secret: ' . Env::code_dadata_2();
$request = [$fullname];
curl_setopt($curl, CURLOPT_URL, "https://cleaner.dadata.ru/api/v1/clean/name");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($request, JSON_UNESCAPED_UNICODE));
$response = curl_exec($curl);
$data = json_decode($response, true)[0];
$response = [];
if (($data['name']) && ($data['surname'])) {
$usersurname = $data['surname'];
$username = $data['name'];
switch ($data['gender']) {
case 'Ж':
$usergender = 'F';
break;
case 'М':
$usergender = 'M';
break;
default:
$usergender = null;
}
}
$response['username'] = $username;
$response['usersurname'] = $usersurname;
$response['usergender'] = $usergender;
return $this->json($response);
}
// Подсказки при вводе ФИО
#[Route(path: '/api/checkout/fiohint', name: 'api_checkout_fiohint_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/fiohint', name: 'api_checkout_fiohint', requirements: ['_locale' => '%app.langs%'])]
public function fiohint(Request $request): Response
{
$fullname = (string) $request->query->get('fullname');
$curl = curl_init();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: Token ' . Env::code_dadata();
$request = ['query' => $fullname, 'parts' => ['surname', 'name'], 'count' => 10];
curl_setopt($curl, CURLOPT_URL, "https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/fio");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($request));
$response = curl_exec($curl);
$suggestions = json_decode($response);
//var_dump($suggestions);
$apiResponce = [];
foreach ($suggestions->suggestions as $suggestion) {
$obj = new stdClass();
$obj->value = $suggestion->value;
$obj->name = $suggestion->data->name;
$obj->surname = $suggestion->data->surname;
$obj->gender = $suggestion->data->gender;
$apiResponce[] = $obj;
}
return $this->json($apiResponce);
}
#[Route(path: '/api/checkout/citydetect', name: 'api_checkout_citydetect_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/citydetect', name: 'api_checkout_citydetect', requirements: ['_locale' => '%app.langs%'])]
public function citydetect(Request $request): Response
{
$city_fias_id = $this->Checkout->getCity_fias_id();
if ($city_fias_id) {
} else {
if (Env::site() == env::DOM || Env::site() == env::OPT) {
$ip = $_SERVER["REMOTE_ADDR"];
$request = @file_get_contents("https://api.sypexgeo.net/json/" . $ip);
$array = json_decode($request, true);
$city_name = isset($array['city']['name_ru']) ? $array['city']['name_ru'] : "";
$city = $this->Cities->findOneBy(["name" => $city_name]);
if (!$city) {
$region = $this->Regions->findOneBy(['fias_id' => $this->default_region_id]);
$city = $this->Cities->findOneBy(['fias_id' => $this->default_city_id]);
$this->Checkout->setRegion_fias_id($region->getFiasId());
$this->Checkout->setRegion_name($region->getName());
$this->Checkout->setCity_fias_id($city->getFiasId());
$this->Checkout->setCity_name($city->getName());
$this->Checkout->setCity_post_code($city->getPostalCode());
} else {
$region = $this->Regions->find($city->getRegion());
$this->Checkout->setRegion_fias_id($region->getFiasId());
$this->Checkout->setRegion_name($region->getName());
$this->Checkout->setCity_fias_id($city->getFiasId());
$this->Checkout->setCity_name($city->getName());
$this->Checkout->setCity_post_code($city->getPostalCode());
}
} elseif (Env::site() == env::MIR || Env::site() == env::OPT_MIR) {
$curl = curl_init();
$headers[] = 'Accept: application/json';
$headers[] = 'Authorization: Token ' . Env::code_dadata();
curl_setopt($curl, CURLOPT_URL, "https://suggestions.dadata.ru/suggestions/api/4_1/rs/iplocate/address?ip=" . $_SERVER['REMOTE_ADDR']);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = json_decode(curl_exec($curl));
if ($response->location == null) {
$region = $this->Regions->findOneBy(['fias_id' => $this->default_region_id]);
$city = $this->Cities->findOneBy(['fias_id' => $this->default_city_id]);
$this->Checkout->setRegion_fias_id($region->getFiasId());
$this->Checkout->setRegion_name($region->getName());
$this->Checkout->setCity_fias_id($city->getFiasId());
$this->Checkout->setCity_name($city->getName());
$this->Checkout->setCity_post_code($city->getPostalCode());
} else {
$this->Checkout->setRegion_fias_id($response->location->data->region_fias_id);
$this->Checkout->setRegion_name($response->location->data->region_with_type);
$this->Checkout->setCity_fias_id(($response->location->data->settlement_fias_id ? $response->location->data->settlement_fias_id : $response->location->data->city_fias_id));
$this->Checkout->setCity_name(($response->location->data->settlement_with_type ? $response->location->data->settlement_with_type : $response->location->data->city_with_type));
$this->Checkout->setCity_post_code($response->location->data->postal_code);
}
} else {
$this->Checkout->setRegion_fias_id('default');
}
}
return $this->json($this->Checkout->getCheckout());
}
// Подсказки при вводе города
#[Route(path: '/api/checkout/citylist', name: 'api_checkout_citylist_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/citylist', name: 'api_checkout_citylist', requirements: ['_locale' => '%app.langs%'])]
public function citylist(Request $request): Response
{
$q = (string) $request->query->get('string');
if (Env::site() == env::DOM || Env::site() == env::OPT) {
/** @var \App\Entity\City[] $cities */
$cities = $this->em->createQuery("SELECT c FROM App\Entity\City c WHERE c.name LIKE '" . $q . "%' ORDER BY c.type ASC")->setMaxResults(10)->getResult(); // Check
if (count($cities)) {
$response = new \stdClass();
$response->suggestions = [];
foreach ($cities as $city) {
$region = $this->Regions->find($city->getRegion());
if ($region) {
$suggestion = new \stdClass();
$suggestion->value = $city->getType() . ' ' . $city->getName() . ", " . $region->getName();
$suggestion->data = new \stdClass();
$suggestion->data->city_fias_id = $city->getFiasId();
array_push($response->suggestions, $suggestion);
}
}
}
} else {
$curl = curl_init();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Accept: application/json';
$headers[] = 'Authorization: Token ' . Env::code_dadata();
$request = ['query' => $q, 'from_bound' => ['value' => 'city'], 'to_bound' => ['value' => 'settlement'], 'count' => 10];
curl_setopt($curl, CURLOPT_URL, "https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($request));
$response = curl_exec($curl);
}
return $this->json($response);
}
// Выбор города
#[Route(path: '/api/checkout/selectcity', name: 'api_checkout_selectcity_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/selectcity', name: 'api_checkout_selectcity', requirements: ['_locale' => '%app.langs%'])]
public function selectcity(Request $request, Checkout $Checkout): Response
{
$fias_id = (string) $request->query->get('fias_id');
if ($fias_id) {
if (Env::site() == env::DOM || Env::site() == env::OPT) {
$city = $this->Cities->findOneBy(['fias_id' => $fias_id]); // Check
if ($city->getId()) {
$region = $this->Regions->find($city->getRegion());
if ($region) {
$Checkout->setRegion_fias_id($region->getFiasId());
$Checkout->setRegion_name($region->getName());
$Checkout->setCity_fias_id($city->getFiasId());
$Checkout->setCity_name($city->getName());
$Checkout->setCity_post_code($city->getPostalCode());
$Checkout->setUseraddr('');
$Checkout->setUserlat('');
$Checkout->setUserlon('');
$Checkout->setDelivery_post_code('');
$Checkout->setDelivery_post_name('');
$Checkout->setDelivery_post_worktime('');
$Checkout->setDelivery_post_phone('');
$Checkout->setDelivery_post_email('');
$Checkout->setDelivery_sub_id(0);
$Checkout->setDelivery_sub_name('');
$Checkout->setDelivery_cost(0);
}
}
} else {
$curl = curl_init();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Accept: application/json';
$headers[] = 'Authorization: Token ' . Env::code_dadata();
$request = ['query' => $fias_id];
curl_setopt($curl, CURLOPT_URL, "https://suggestions.dadata.ru/suggestions/api/4_1/rs/findById/address");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($request));
$response = json_decode(curl_exec($curl));
if (!count($response->suggestions)) {
$region = $this->Regions->findOneBy(['fias_id' => $this->default_region_id]);
$city = $this->Cities->findOneBy(['fias_id' => $this->default_city_id]);
$Checkout->setRegion_fias_id($region->getFiasId());
$Checkout->setRegion_name($region->getName());
$Checkout->setCity_fias_id($city->getFiasId());
$Checkout->setCity_name($city->getName());
$Checkout->setCity_post_code($city->getPostalCode());
$Checkout->setUseraddr('');
$Checkout->setUserlat('');
$Checkout->setUserlon('');
$Checkout->setDelivery_post_code('');
$Checkout->setDelivery_post_name('');
$Checkout->setDelivery_post_worktime('');
$Checkout->setDelivery_post_phone('');
$Checkout->setDelivery_post_email('');
$Checkout->setDelivery_sub_id(0);
$Checkout->setDelivery_sub_name('');
$Checkout->setDelivery_cost(0);
} else {
$Checkout->setRegion_fias_id($response->suggestions[0]->data->region_fias_id);
$Checkout->setRegion_name($response->suggestions[0]->data->region_with_type);
$Checkout->setCity_fias_id(($response->suggestions[0]->data->settlement_fias_id ? $response->suggestions[0]->data->settlement_fias_id : $response->suggestions[0]->data->city_fias_id));
$Checkout->setCity_name(($response->suggestions[0]->data->settlement_with_type ? $response->suggestions[0]->data->settlement_with_type : $response->suggestions[0]->data->city_with_type));
$Checkout->setCity_post_code($response->suggestions[0]->data->postal_code);
$city = $this->Cities->findOneBy(['fias_id' => $Checkout->getCity_fias_id()]);
if ($city->getPostalCode()) {
$Checkout->setCity_post_code($city->getPostalCode());
}
$Checkout->setUseraddr('');
$Checkout->setUserlat('');
$Checkout->setUserlon('');
$Checkout->setDelivery_post_code('');
$Checkout->setDelivery_post_name('');
$Checkout->setDelivery_post_worktime('');
$Checkout->setDelivery_post_phone('');
$Checkout->setDelivery_post_email('');
$Checkout->setDelivery_sub_id(0);
$Checkout->setDelivery_sub_name('');
$Checkout->setDelivery_cost(0);
}
}
}
return $this->json($Checkout->getCheckout());
}
// Подсказки при вводе адреса
#[Route(path: '/api/checkout/addresslist', name: 'api_checkout_addresslist_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/addresslist', name: 'api_checkout_addresslist', requirements: ['_locale' => '%app.langs%'])]
public function addressList(Request $request, Checkout $Checkout): Response
{
$q = (string) $request->query->get('string');
$curl = curl_init();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Accept: application/json';
$headers[] = 'Authorization: Token ' . Env::code_dadata();
$request = ['query' => $q, 'locations' => ['city_fias_id' => $Checkout->getCity_fias_id(), ['settlement_fias_id' => $Checkout->getCity_fias_id()]], 'from_bound' => ['value' => 'street'], 'to_bound' => ['value' => 'flat'], 'count' => 10];
curl_setopt($curl, CURLOPT_URL, "https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($request));
$response = json_decode(curl_exec($curl), true);
return $this->json($response);
}
// Get Session Vars
#[Route(path: '/api/checkout/get-session-vars', name: 'api_checkout_get_session_vars_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/get-session-vars', name: 'api_checkout_get_session_vars', requirements: ['_locale' => '%app.langs%'])]
public function getSessionVars(): Response
{
$result = [
'amount_delivery' => Func::fmtmoney($this->Cart->getAmountDelivery()),
'amount_with_delivery' => Func::fmtmoney($this->Cart->getAmountWithDelivery()),
'userlat' => $this->Checkout->getUserlat(),
'userlon' => $this->Checkout->getUserlon(),
'delivery_id' => (int) $this->Checkout->getDelivery_id(),
'delivery_intname' => $this->Checkout->getDelivery_intname(),
'delivery_name' => $this->Checkout->getDelivery_name(),
'delivery_post_code' => $this->Checkout->getDelivery_post_code(),
];
return $this->json($result);
}
// Выбор сервиса доставки
#[Route(path: '/api/checkout/select-type/{delivery_id}', name: 'api_checkout_select_type_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/select-type/{delivery_id}', name: 'api_checkout_select_type', requirements: ['_locale' => '%app.langs%'])]
public function selectType(int $delivery_id = 0): Response
{
$delivery = $this->Deliveries->find($delivery_id);
if ($delivery) {
$this->Checkout->setDelivery_id($delivery->getId());
$this->Checkout->setDelivery_intname($delivery->getIntname());
$this->Checkout->setDelivery_name($delivery->getName());
$result = [
'error' => null,
'delivery_id' => $delivery->getId(),
'delivery_intname' => $delivery->getIntname(),
'delivery_name' => $delivery->getName(),
];
} else {
$result = [
"error" => "wrong delivery id",
];
}
return $this->json($result);
}
// Выбор варианта доставки
#[Route(path: '/api/checkout/select-price/{sub_id}/{sub_code}/{sub_name}/{cost}', name: 'api_checkout_select_price_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/select-price/{sub_id}/{sub_code}/{sub_name}/{cost}', name: 'api_checkout_select_price', requirements: ['_locale' => '%app.langs%'])]
public function selectPrice(int $sub_id = 0, string $sub_code = '', string $sub_name = '', string $cost = ''): Response
{
$this->Checkout->setDelivery_sub_id($sub_id);
$this->Checkout->setDelivery_sub_code($sub_code);
$this->Checkout->setDelivery_sub_name($sub_name);
$this->Checkout->setDelivery_cost($cost);
$result = [
'error' => null,
'delivery_sub_id' => $sub_id,
'delivery_sub_code' => $sub_code,
'delivery_sub_name' => $sub_name,
'delivery_cost' => $cost,
];
return $this->json($result);
}
// Изменение цены доставки
#[Route(path: '/api/checkout/set-price/{cost}', name: 'api_checkout_set_price_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/set-price/{cost}', name: 'api_checkout_set_price', requirements: ['_locale' => '%app.langs%'])]
public function setPrice($cost = ''): Response
{
$this->Checkout->setDelivery_cost($cost);
$result = [
'delivery_cost' => $cost,
];
return $this->json($result);
}
// Выбор отделения доставки
#[Route(path: '/api/checkout/select-code/{code}/{name}/{worktime}/{phone}/{email}', name: 'api_checkout_select_code_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/select-code/{code}/{name}/{worktime}/{phone}/{email}', name: 'api_checkout_select_code', requirements: ['_locale' => '%app.langs%'])]
public function selectCode(string $code = '', string $name = '', string $worktime = '', string $phone = '', string $email = ''): Response
{
$this->Checkout->setUserlat('');
$this->Checkout->setDelivery_post_code($code);
$this->Checkout->setDelivery_post_name($name);
$this->Checkout->setDelivery_post_worktime($worktime);
$this->Checkout->setDelivery_post_phone($phone);
$this->Checkout->setDelivery_post_email($email);
$result = [
'error' => null,
'delivery_post_code' => $code,
'delivery_post_name' => $name,
'delivery_post_worktime' => $worktime,
'delivery_post_phone' => $phone,
'delivery_post_email' => $email,
];
return $this->json($result);
}
// Выбор отделения доставки
#[Route(path: '/api/checkout/select-address/{addr}/{lat}/{lon}', name: 'api_checkout_select-address_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/select-address/{addr}/{lat}/{lon}', name: 'api_checkout_select-address', requirements: ['_locale' => '%app.langs%'])]
public function selectAddress(string $addr = '', string $lat = '', string $lon = ''): Response
{
$this->Checkout->setUseraddr($addr);
$this->Checkout->setUserlat($lat);
$this->Checkout->setUserlon($lon);
$result = [
'useraddr' => $addr,
'userlat' => $lat,
'userlon' => $lon,
];
return $this->json($result);
}
// Выбор способа оплаты
#[Route(path: '/api/checkout/payment/select-type/{id}', name: 'checkout_payment_select_type_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/payment/select-type/{id}', name: 'checkout_payment_select_type', requirements: ['_locale' => '%app.langs%'])]
public function payment(int $id): Response
{
$esystem = $this->Esystems->find($id);
if ($esystem) {
$this->Checkout->setPayment_id($id);
$this->Checkout->setPayment_name($esystem->getName());
$result = [
'payment_id' => $id,
'payment_name' => $esystem->getName(),
];
} else {
$result = [
'error' => "wrong id",
];
}
return $this->json($result);
}
// Данные компании
#[Route(path: '/api/checkout/payment/company-data', name: 'checkout_payment_company_data_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/payment/company-data', name: 'checkout_payment_company_data', requirements: ['_locale' => '%app.langs%'])]
public function companyData(Request $request): Response
{
$company_nip = $request->get('company_nip');
$company_name = $request->get('company_name');
$company_index = $request->get('company_index');
$company_city = $request->get('company_city');
$company_street = $request->get('company_street');
$company_house = $request->get('company_house');
$company_flat = $request->get('company_flat');
$this->Checkout->setCompanyNip($company_nip);
$this->Checkout->setCompanyName($company_name);
$this->Checkout->setCompanyIndex($company_index);
$this->Checkout->setCompanyCity($company_city);
$this->Checkout->setCompanyStreet($company_street);
$this->Checkout->setCompanyHouse($company_house);
$this->Checkout->setCompanyFlat($company_flat);
$user = $this->Users->find($this->Auth->getUserId());
$user->setCompanyNip($company_nip);
$user->setCompanyName($company_name);
$user->setCompanyIndex($company_index);
$user->setCompanyCity($company_city);
$user->setCompanyStreet($company_street);
$user->setCompanyHouse($company_house);
$user->setCompanyFlat($company_flat);
$this->em->persist($user);
$this->em->flush();
return $this->json(true);
}
// Очистка данных компании
#[Route(path: '/api/checkout/payment/clear-company-data', name: 'checkout_payment_clear_company_data_no_locale', defaults: ['_locale' => '%app.default_lang%'])]
#[Route(path: '/{_locale}/api/checkout/payment/clear-company-data', name: 'checkout_payment_clear_company_data', requirements: ['_locale' => '%app.langs%'])]
public function clearCompanyData(): Response
{
$this->Checkout->setCompanyNip('');
$this->Checkout->setCompanyName('');
$this->Checkout->setCompanyIndex('');
$this->Checkout->setCompanyCity('');
$this->Checkout->setCompanyStreet('');
$this->Checkout->setCompanyHouse('');
$this->Checkout->setCompanyFlat('');
return $this->json(true);
}
}