@@ -0,0 +1,8 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Context; | |||
interface UserUtilsInterface | |||
{ | |||
} |
@@ -3,12 +3,14 @@ | |||
namespace Lc\ShopBundle\Model; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\ShopBundle\Context\StatusInterface; | |||
/** | |||
* @ORM\MappedSuperclass() | |||
*/ | |||
abstract class Address extends AbstractEntity | |||
abstract class Address extends AbstractEntity implements StatusInterface | |||
{ | |||
use StatusTrait; | |||
const TYPE_INDIVIDUAL = 'individual'; | |||
const TYPE_LEGAL_PERSON = 'legal-person'; |
@@ -17,7 +17,7 @@ trait SluggableTrait | |||
return $this->slug; | |||
} | |||
public function setSlug(string $slug): self | |||
public function setSlug(?string $slug): self | |||
{ | |||
$this->slug = $slug; | |||
@@ -181,9 +181,20 @@ abstract class User extends UserModelFOS | |||
/** | |||
* @return Collection|Address[] | |||
*/ | |||
public function getAddresses(): Collection | |||
{ | |||
return $this->addresses; | |||
public function getAddresses($status = null): Collection | |||
{ | |||
if($status){ | |||
$addressToReturn = new ArrayCollection(); | |||
foreach ($this->addresses as $address){ | |||
if($address->getStatus() == $status) { | |||
$addressToReturn[] = $address; | |||
} | |||
} | |||
return $addressToReturn; | |||
}else{ | |||
return $this->addresses; | |||
} | |||
} | |||
public function addAddress(Address $address): self |
@@ -99,4 +99,17 @@ class BaseRepository extends EntityRepository implements ServiceEntityRepository | |||
return parent::findOneBy($criteria, $orderBy); | |||
} | |||
public function findSimilarSlug($merchant){ | |||
$qb = $this->createQueryBuilder('entity') | |||
->select('entity.id, COUNT(entity.slug) as niche') | |||
->andWhere('entity.status>=0') | |||
->andWhere('entity.merchant= :merchant') | |||
->setParameter('merchant', $merchant) | |||
->groupBy('entity.slug') | |||
->having('COUNT(entity.slug) >1'); | |||
return $qb->getQuery()->getResult(); | |||
} | |||
} |
@@ -29,11 +29,11 @@ class ReductionCartRepository extends BaseRepository implements DefaultRepositor | |||
return ReductionCartInterface::class; | |||
} | |||
public function findOneByCode($code) | |||
public function findByCode($code) | |||
{ | |||
$query = $this->findByMerchantQuery() ; | |||
$query->andWhere('e.codes LIKE :code')->setParameter('code', '%'.$code.'%') ; | |||
return $query->getQuery()->getOneOrNullResult() ; | |||
return $query->getQuery()->getResult() ; | |||
} | |||
public function getValuesOfFieldType(){ |
@@ -80,6 +80,8 @@ group: | |||
email: Email | |||
delivery: Livraison | |||
maintenance: Maintenance | |||
Address: | |||
listLoopBesancon: Adresses de Besançon à spécifier (lat / long) | |||
None: Aucune valeur | |||
@@ -388,6 +390,9 @@ field: | |||
unit: Unité | |||
Address: | |||
city: Commune | |||
statusOptions: | |||
offline: Désactiver | |||
online: Activer | |||
typeOptions: | |||
individual: Particulier | |||
legal-person: Professionnel | |||
@@ -396,6 +401,7 @@ field: | |||
quantityProduct: Quantité (en rapport à l'unité) | |||
unit: Unité | |||
OrderShop: | |||
hasReach: Étape atteinte | |||
deliveryTrucks: Véhicules de livraison | |||
createdAt: Date de création | |||
updatedAt: Date de modification |
@@ -51,6 +51,11 @@ | |||
<div class="col-12"> | |||
{{ form_row(form.deliveryInfos) }} | |||
</div> | |||
<div class="col-12 {{ merchantUtils.getMerchantCurrent().isHubBesancon() ? '': 'hidden'}}"> | |||
{{ form_row(form.inBesanconLoop) }} | |||
</div> | |||
<div class="col-6"> | |||
{{ form_row(form.latitude) }} | |||
</div> | |||
@@ -63,6 +68,12 @@ | |||
<div class="col-6"> | |||
{{ form_row(form.longitudeOverride) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.status) }} | |||
<p class="callout callout-info"> | |||
Sauf si vous savez ce que ce vous faites ce champ doit toujours être "Activer" | |||
</p> | |||
</div> | |||
{{ form_row(form.country) }} | |||
@@ -17,6 +17,16 @@ | |||
<div class="col-6"> | |||
{{ form_row(form.merchantConfigs['order-open-time']) }} | |||
</div> | |||
{% if form.merchantConfigs['order-open-day-vip'] is defined %} | |||
<div class="col-6"> | |||
{{ form_row(form.merchantConfigs['order-open-day-vip']) }} | |||
</div> | |||
{% endif %} | |||
{% if form.merchantConfigs['order-open-time-vip'] is defined %} | |||
<div class="col-6"> | |||
{{ form_row(form.merchantConfigs['order-open-time-vip']) }} | |||
</div> | |||
{% endif %} | |||
<div class="col-6"> | |||
{{ form_row(form.merchantConfigs['order-close-day']) }} | |||
</div> |
@@ -0,0 +1,18 @@ | |||
{% if value == 1 %} | |||
<span class="badge badge-info"> | |||
Adresse de livraison | |||
</span> | |||
{% elseif value == 2 %} | |||
<span class="badge badge-warning"> | |||
Adresse de facturation | |||
</span> | |||
{% elseif value == 3 %} | |||
<span class="badge badge-danger"> | |||
Page de confirmation | |||
</span> | |||
{% else %} | |||
<span class="badge badge-secondary"> | |||
Aucune | |||
</span> | |||
{% endif %} | |||
@@ -396,6 +396,29 @@ | |||
{% endembed %} | |||
{% endmacro %} | |||
{% macro box_step_reach() %} | |||
{% embed '@LcShop/backend/default/block/embed_box.twig' %} | |||
{% import '@LcShop/backend/order/macros.html.twig' as order_macros %} | |||
{% trans_default_domain 'lcshop' %} | |||
{% block class %}bg-info{% endblock %} | |||
{% block icon %}list-ol{% endblock %} | |||
{% block label %}Étape atteinte{% endblock %} | |||
{% block value %} | |||
<div v-if="order.hasReach == 1"> | |||
Adresse de livraison | |||
</div> | |||
<div v-if="order.hasReach == 2"> | |||
Adresse de facturation | |||
</div> | |||
<div v-if="order.hasReach == 3"> | |||
Page de paiement | |||
</div> | |||
<div v-if="order.hasReach ==null"> | |||
Aucune | |||
</div> | |||
{% endblock %} | |||
{% endembed %} | |||
{% endmacro %} | |||
{% macro box_payments() %} |
@@ -32,7 +32,9 @@ | |||
{{ order_macros.box_delivery_slot() }} | |||
</div> | |||
</template> | |||
<div class="col-3"> | |||
{{ order_macros.box_step_reach() }} | |||
</div> | |||
<div class="col-12"> | |||
{{ macros.card_start('OrderShop.resume') }} |
@@ -2,5 +2,5 @@ | |||
{% trans_default_domain 'lcshop' %} | |||
<div class="col-6 user-address-item"> | |||
{% set button = '<button type="button" data-url="'~ path('easyadmin', {"action": 'editAddressUser', 'entity': 'User', 'id': entity.id, 'addressId': address.id})~'" class="btn btn-default btn-edit-user-address" >'~ 'action.edit'|trans ~'</button>' %} | |||
{{ macros.box_info('bg-info', 'address-card', address.summary, '', button) }} | |||
{{ macros.box_info('bg-info', 'address-card', address.summary(true, true), '', button) }} | |||
</div> |
@@ -19,7 +19,9 @@ | |||
<div class="col-5"> | |||
<div class="row" id="user-addresses"> | |||
{% for address in entity.addresses %} | |||
{% if address.status >=0 %} | |||
{% include '@LcShop/backend/user/block_useraddress.html.twig' %} | |||
{% endif %} | |||
{% endfor %} | |||
</div> | |||
<button type="button" data-url="{{ path('easyadmin', {"action": 'editAddressUser', 'entity': 'User', 'id': entity.id, 'addressId': 'new'}) }}" |
@@ -13,6 +13,8 @@ class MailUtils | |||
const SUBJECT = 'subject'; | |||
const SUBJECT_PREFIX = 'subject-prefix'; | |||
const TO_EMAIL = 'to-email'; | |||
const COPY_TO = 'copy-to'; | |||
const COPY_HIDDEN_TO = 'copy-hidden-to'; | |||
const TO_NAME = 'to-name'; | |||
const FROM_EMAIL = 'from-email'; | |||
const FROM_NAME = 'from-name'; | |||
@@ -73,6 +75,15 @@ class MailUtils | |||
->setBody($this->templating->render($params[self::CONTENT_TEMPLATE] . '-html.html.twig', $contentData), 'text/html') | |||
->addPart($this->templating->render($params[self::CONTENT_TEMPLATE] . '-text.html.twig', $contentData)); | |||
if (isset($params[self::COPY_TO]) && strlen($params[self::COPY_TO])) { | |||
$message->addCc($params[self::COPY_TO]); | |||
} | |||
if (isset($params[self::COPY_HIDDEN_TO]) && strlen($params[self::COPY_HIDDEN_TO])) { | |||
$message->addBcc($params[self::COPY_HIDDEN_TO]); | |||
} | |||
if (isset($params[self::REPLY_TO]) && strlen($params[self::REPLY_TO])) { | |||
$message->addReplyTo($params[self::REPLY_TO]); | |||
} |
@@ -13,6 +13,7 @@ use Lc\ShopBundle\Context\OrderStatusHistoryInterface; | |||
use Lc\ShopBundle\Context\PriceUtilsInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface; | |||
use Lc\ShopBundle\Context\ReductionCreditInterface; | |||
use Lc\ShopBundle\Context\UserUtilsInterface; | |||
use Lc\ShopBundle\Model\ProductFamily; | |||
use Lc\ShopBundle\Services\CreditUtils; | |||
use Lc\ShopBundle\Services\DocumentUtils; | |||
@@ -45,7 +46,7 @@ class OrderUtils | |||
protected $creditUtils; | |||
protected $router; | |||
public function __construct(EntityManagerInterface $em, Security $security, RouterInterface $router, UserUtils $userUtils, | |||
public function __construct(EntityManagerInterface $em, Security $security, RouterInterface $router, UserUtilsInterface $userUtils, | |||
MerchantUtilsInterface $merchantUtils, PriceUtilsInterface $priceUtils, ProductFamilyUtilsInterface $productFamilyUtils, | |||
DocumentUtils $documentUtils, Utils $utils, CreditUtils $creditUtils) | |||
{ |
@@ -9,6 +9,7 @@ use Symfony\Component\HttpFoundation\Cookie ; | |||
use Lc\ShopBundle\Context\VisitorInterface; | |||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||
use Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\Security\Core\Security; | |||
class UserUtils | |||
{ | |||
@@ -21,7 +22,8 @@ class UserUtils | |||
protected $cookieChecker ; | |||
public function __construct(ParameterBagInterface $parameterBag, EntityManagerInterface $em, Utils $utils, | |||
RequestStack $requestStack, MerchantUtilsInterface $merchantUtils, CookieChecker $cookieChecker) | |||
RequestStack $requestStack, MerchantUtilsInterface $merchantUtils, CookieChecker $cookieChecker, | |||
Security $security) | |||
{ | |||
$this->em = $em ; | |||
$this->parameterBag = $parameterBag ; | |||
@@ -30,6 +32,7 @@ class UserUtils | |||
$this->visitorRepository = $this->em->getRepository($this->em->getClassMetadata(VisitorInterface::class)->getName()) ; | |||
$this->merchantUtils = $merchantUtils ; | |||
$this->cookieChecker = $cookieChecker ; | |||
$this->security = $security ; | |||
} | |||
public function getCookieNameVisitor() |
@@ -7,6 +7,8 @@ use Doctrine\ORM\EntityManagerInterface; | |||
use EasyCorp\Bundle\EasyAdminBundle\Configuration\ConfigManager; | |||
use Geocoder\Model\Coordinates; | |||
use Geocoder\Provider\Addok\Addok; | |||
use Geocoder\Provider\GoogleMaps\GoogleMaps; | |||
use Geocoder\Provider\Nominatim\Nominatim; | |||
use Geocoder\Query\GeocodeQuery; | |||
use Geocoder\Query\ReverseQuery; | |||
use Lc\ShopBundle\Context\ImageInterface; | |||
@@ -172,6 +174,15 @@ class Utils | |||
return $truncate; | |||
} | |||
function stripAccents($stripAccents) | |||
{ | |||
return strtr($stripAccents,'àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ','aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY'); | |||
} | |||
function cleanStringToCompare($string) | |||
{ | |||
return $this->stripAccents(trim(strtolower($string))) ; | |||
} | |||
public function isBot() | |||
{ | |||
@@ -265,8 +276,27 @@ class Utils | |||
public function getGeocoderProvider() | |||
{ | |||
$provider = false ; | |||
$symfonyClient = new HttplugClient(); | |||
$provider = new Addok($symfonyClient, 'https://api-adresse.data.gouv.fr') ; | |||
$configGeocoderProvider = $this->parameterBag->get('geocoder.provider') ; | |||
/* API du gouvernement */ | |||
if($configGeocoderProvider == 'addok') { | |||
$provider = new Addok($symfonyClient, 'https://api-adresse.data.gouv.fr') ; | |||
} | |||
/* Google Maps */ | |||
elseif($configGeocoderProvider == 'googlemaps') { | |||
$provider = new GoogleMaps($symfonyClient, null, $this->parameterBag->get('geocoder.api_key')) ; | |||
} | |||
/* Nominatim : OpenStreetMap */ | |||
elseif($configGeocoderProvider == 'nominatim') { | |||
$provider = Nominatim::withOpenStreetMapServer($symfonyClient, 'Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion'); | |||
} | |||
if(!$provider) { | |||
throw new \ErrorException('Aucun provider (geocoding) défini') ; | |||
} | |||
return $provider ; | |||
} | |||
@@ -275,7 +305,13 @@ class Utils | |||
$provider = $this->getGeocoderProvider() ;; | |||
$query = GeocodeQuery::create($query)->withData('type', 'housenumber'); | |||
$results = $provider->geocodeQuery($query); | |||
return $results->all() ; | |||
$resultsToReturn = array(); | |||
foreach($results as $result) { | |||
if ($result->getStreetNumber() && strlen($result->getStreetNumber()) > 0) { | |||
$resultsToReturn[] = $result; | |||
} | |||
} | |||
return $resultsToReturn; | |||
} | |||
public function callReverseAddressApi($latitude, $longitude) | |||
@@ -506,46 +542,6 @@ class Utils | |||
} | |||
public function duplicateEntity($entity){ | |||
$newEntity = clone $entity ; | |||
if($newEntity instanceof ImageInterface){ | |||
$this->duplicateImage($entity); | |||
$newEntity->setImage(null); | |||
} | |||
if($newEntity instanceof ProductFamilyInterface){ | |||
$this->productFamilyUtils->processBeforePersistProductFamily($newEntity); | |||
} | |||
$this->em->persist($newEntity) ; | |||
$this->em->flush(); | |||
return $newEntity; | |||
} | |||
public function duplicateImage($entity, $folder = false){ | |||
$basePath = $this->parameterBag->get('kernel.project_dir').'/public/uploads/images/' ; | |||
if($entity->getImage() && file_exists($basePath.$entity->getImage())) { | |||
dump(pathinfo($basePath.$entity->getImage())); | |||
} | |||
die(); | |||
$newImage = md5(uniqid()).'.jpg'; | |||
if($folder) $newImage = $folder.'/'.$newImage; | |||
if($entity->getImage() && file_exists($basePath.$entity->getImage())) { | |||
copy($basePath.$entity->getImage(), $basePath . $newImage); | |||
$entity->setImage($newImage); | |||
}else{ | |||
$entity->setImage(null); | |||
} | |||
return $entity; | |||
} | |||
} |
@@ -9,6 +9,7 @@ use Lc\ShopBundle\Context\OrderUtilsInterface; | |||
use Lc\ShopBundle\Context\PriceUtilsInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface; | |||
use Lc\ShopBundle\Context\Services\StatisticsUtilsInterface; | |||
use Lc\ShopBundle\Context\UserUtilsInterface; | |||
use League\Flysystem\Util; | |||
class UtilsManager | |||
@@ -29,7 +30,7 @@ class UtilsManager | |||
public function __construct( | |||
Utils $utils, | |||
UserUtils $userUtils, | |||
UserUtilsInterface $userUtils, | |||
MerchantUtilsInterface $merchantUtils, | |||
ProductFamilyUtilsInterface $productFamilyUtils, | |||
OrderUtilsInterface $orderUtils, | |||
@@ -63,7 +64,7 @@ class UtilsManager | |||
return $this->utils ; | |||
} | |||
public function getUserUtils(): UserUtils | |||
public function getUserUtils(): UserUtilsInterface | |||
{ | |||
return $this->userUtils ; | |||
} |
@@ -16,6 +16,7 @@ use Lc\ShopBundle\Context\PointSaleInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface; | |||
use Lc\ShopBundle\Context\ReminderInterface; | |||
use Lc\ShopBundle\Context\SluggableInterface; | |||
use Lc\ShopBundle\Context\TaxRateInterface; | |||
use Lc\ShopBundle\Context\UnitInterface; | |||
use Lc\ShopBundle\Context\UserInterface; | |||
@@ -62,10 +63,13 @@ class UtilsProcess | |||
$this->em->persist($newAddress); | |||
} | |||
$this->em->persist($newEntity); | |||
if($flush){ | |||
$this->em->flush(); | |||
if($newEntity instanceof SluggableInterface){ | |||
$this->em->persist($newEntity); | |||
if($flush)$this->em->flush(); | |||
$newEntity->setSlug(null); | |||
} | |||
$this->em->persist($newEntity); | |||
if($flush)$this->em->flush(); | |||
return $newEntity; |