Untitled
unknown
plain_text
7 months ago
12 kB
4
Indexable
<?php
declare(strict_types=1);
namespace App\Import\Traits;
use App\Import\ArticleIterator;
use App\Import\ReducCe\ArticleDto;
use Doctrine\Common\Persistence\ManagerRegistry;
use JMS\Serializer\Naming\IdenticalPropertyNamingStrategy;
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
use JMS\Serializer\SerializerBuilder;
use Puwnz\GoogleMapsLib\Geocode\DTO\GeocodeResult;
trait ArticleTrait
{
use GeocodeTrait;
private ?\Generator $articles = null;
public function next(): void
{
$this->articles->next();
}
public function valid(): bool
{
return $this->articles->valid();
}
public function rewind(): void
{
if ($this->key() === 0) {
$this->articles->rewind();
}
}
public function key()
{
return $this->articles->key();
}
public function init(string $path): void
{
if ($this->articles !== null) {
return;
}
$fileContents = str_replace('#cdata-section', 'cdata_section', $this->filesystem->read($path));
$fileContents = json_decode($fileContents, true, 512, \JSON_THROW_ON_ERROR);
$this->articles = $this->crawlArticles($fileContents);
}
private function crawlArticles(array $fileContents): \Generator
{
foreach ($fileContents['catalogues'] as $catalogue) {
$currentCatalogue = $this->translateCode($catalogue['catalogues_id']);
if (!$this->isCollection($catalogue['genres']['genre'])) {
$catalogue['genres']['genre'] = [$catalogue['genres']['genre']];
}
foreach ($catalogue['genres']['genre'] as $genre) {
if (isset($genre['sousgenres']['sousgenre'])) {
if (!$this->isCollection($genre['sousgenres']['sousgenre'])) {
$genre['sousgenres']['sousgenre'] = [$genre['sousgenres']['sousgenre']];
}
$currentGenre = $this->translateCode($genre['genres_id']);
foreach ($genre['sousgenres']['sousgenre'] as $sousgenre) {
if (isset($sousgenre['sousgenres_prix_dynamiques']) && $sousgenre['sousgenres_prix_dynamiques'] === true) {
continue;
}
$currentSousgenre = $this->translateCode($sousgenre['sousgenres_id']);
if (isset($sousgenre['articles'])) {
$articles = $sousgenre['articles'];
if (!$this->isCollection($articles)) {
$articles = [$articles];
}
foreach ($articles as $article) {
foreach ($article['article'] as $article1) {
try {
if (!is_array($article1['articles_tarifs'])) {
$article1['articles_tarifs'] = [];
}
if (!is_array($article1['articles_lieux'])) {
$article1['articles_lieux'] = [];
}
$article1['articles_puttc'] = number_format((float)strtr((string)$article1['articles_puttc'], ',', '.'), 2, '.', '');
$article1['articles_puht'] = number_format((float)strtr((string)$article1['articles_puht'], ',', '.'), 2, '.', '');
$article1['articles_prix_public'] = number_format((float)strtr((string)$article1['articles_prix_public'], ',', '.'), 2, '.', '');
$article1['articles_tva'] = number_format((float)strtr((string)$article1['articles_tva'], ',', '.'), 2, '.', '');
$article1['articles_descriptif'] = $article1['articles_descriptif']['cdata_section'];
$article1['currentCatalogue'] = $currentCatalogue;
$article1['currentGenre'] = $currentGenre;
$article1['currentSousgenre'] = $currentSousgenre;
$article1['articles_actif'] = $this->isActive($sousgenre, $article1);
$article1['lieux_latitude'] = $sousgenre['lieux_latitude'];
$article1['lieux_longitude'] = $sousgenre['lieux_longitude'];
$article1['articles_date_fin'] = $article1['articles_date_fin'] ?: null;
$article1['articles_date_debut'] = $article1['articles_date_debut'] ?: null;
yield self::serialize($article1, ArticleDto::class);
} catch (\Throwable $e) {
$this->logger->emergency('Article error', [
'article' => $article1,
'error' => $e->getMessage(),
]);
throw $e;
}
}
}
}
}
}
}
}
}
private function isActive(array $sousGenre, array $article): bool
{
if ($sousGenre['sousgenres_actif'] !== 'True') {
return false;
}
if ($article['articles_actif'] !== 'True') {
return false;
}
if ((int)($article['articles_multiple_cmd'] ?? 1) !== 1) {
return false;
}
if ($article['articles_type'] === 'ETICKET' && $this->availableToSale($article) === false) {
return false;
}
return true;
}
private function translateCode(string $code): string
{
return str_replace('-', '_', $code);
}
private function isCollection($array): bool
{
return is_array($array) && array_key_exists(0, $array);
}
private function availableToSale(array $article): bool
{
if ($article['articles_type'] === 'RETRAIT_MAGASIN') {
return false;
}
if ($article['articles_invisibleweb'] === 'True') {
return false;
}
if (in_array($article['articles_statut_manif'], [ArticleIterator::STATUS_ON_SALE, ArticleIterator::STATUS_REPORTED], true) === false) {
return false;
}
if (in_array($article['articles_sousgenre'], ArticleIterator::CATEGORIES_VALABLES, true) === false) {
return false;
}
return true;
}
private function formatGeo($number)
{
if (is_numeric($number)) {
return $number * 10000000;
}
}
public static function serialize(array $body, string $class)
{
$serializer = SerializerBuilder::create()
->setPropertyNamingStrategy(
new SerializedNameAnnotationStrategy(
new IdenticalPropertyNamingStrategy()
)
)
->setCacheDir('./var/cache/jms')
->setDebug(true)
->build();
//todo mettre le cache sur redis
return $serializer->deserialize(json_encode($body), $class, 'json');
}
protected function getAddress(array $product, ArticleDto $article, ?ManagerRegistry $managerRegistry = null): array
{
$article = $this->mapAddress($article);
$geo = null;
if (null !== $article->getArticlesLieux()) {
$address = [
'address_name' => $article->getArticlesLieuNom(),
'address_1' => $article->getArticlesLieuAdresse1(),
'address_2' => $article->getArticlesLieuAdresse2(),
'address_zip_code' => $article->getArticlesLieuCodePostal(),
'address_city' => $article->getArticlesLieuVille(),
'address_district' => $article->getArticlesLieuRegion(),
'address_country' => $article->getArticlesLieuPays(),
];
$geo = $this->getGeocodeResult($address);
}
if ($geo === null && $article->getLieuxLatitude() && $article->getLieuxLongitude()) {
$geo = $this->reverseGeocode($article->getLieuxLatitude(), $article->getLieuxLongitude());
if ($geo) {
$product['latitude'] = $geo->getGeometry()->getLocation()->getLatitude();
$product['longitude'] = $geo->getGeometry()->getLocation()->getLongitude();
$product['address_name'] = $geo->getFormattedAddress();
$product['address_1'] = sprintf('%s %s', $this->getAddressComponent('street_number', $geo), $this->getAddressComponent('route', $geo));
$product['address_zip_code'] = $this->getAddressComponent('postal_code', $geo);
$product['address_city'] = $this->getAddressComponent('locality', $geo);
$product['address_country'] = trim($this->getAddressComponent('country', $geo) ?? 'France');
$product['address_district'] = trim($this->getAddressComponent('administrative_area_level_1', $geo) ?? 'France');
$geo = null;
}
}
if ($geo !== null) {
$product['latitude'] = $geo->getGeometry()->getLocation()->getLatitude();
$product['longitude'] = $geo->getGeometry()->getLocation()->getLongitude();
$product['address_name'] = $address['address_name'];
if ($managerRegistry !== null) {
$product['address'] = $this->getOrCreateAddress($geo, $managerRegistry);
}
}
return $product;
}
private function mapAddress(ArticleDto $article): ArticleDto
{
if (null !== $article->getArticlesLieux()) {
$localisations = $article->getArticlesLieux()['articles_lieu'];
if (null !== $localisations['articles_lieu_adresse1']) {
$article->setArticlesLieuNom($localisations['articles_lieu_nom']);
$article->setArticlesLieuAdresse1($localisations['articles_lieu_adresse1']);
$article->setArticlesLieuAdresse2($localisations['articles_lieu_adresse2']);
$article->setArticlesLieuCodePostal($localisations['articles_lieu_code_postal']);
$article->setArticlesLieuVille($localisations['articles_lieu_ville']);
$article->setArticlesLieuRegion($localisations['articles_lieu_region']);
$article->setArticlesLieuPays($localisations['articles_lieu_pays']);
$article->setLieuxLatitude((float)$localisations['articles_lieu_latitude'] ?: null);
$article->setLieuxLongitude((float)$localisations['articles_lieu_longitude'] ?: null);
}
}
return $article;
}
private function getGeocodeResult(array $addressArticle): ?GeocodeResult
{
if (null === $addressArticle['address_1']) {
return null;
}
$address = sprintf('%s %s %s %s %s', $addressArticle['address_1'], $addressArticle['address_2'], $addressArticle['address_zip_code'], $addressArticle['address_city'], $addressArticle['address_country']);
/** @var GeocodeResult[] $geocode */
$geocode = $this->googleService->geocode($address);
if ($geocode === []) {
return null;
}
$geo = current($geocode);
return $geo ?? null;
}
private function reverseGeocode(float $lat, float $lng): ?GeocodeResult
{
$geocode = $this->googleService->reverseGeocode($lat, $lng);
if ($geocode === []) {
return null;
}
$geo = current($geocode);
return $geo ?? null;
}
private function getPriceCent($price): float
{
return (float)$price;
}
private function getRemisePart($public, $ttc): float
{
if (0 == $public || 0 == $ttc || 0 == ($public - $ttc)) {
return 0;
}
return (($public - $ttc) / $public) * 100;
}
private function getPrice($price): float
{
return (float)str_replace(',', '.', (string)$price);
}
}
Editor is loading...
Leave a Comment