@@ -25,6 +25,7 @@ class ProductFamilySectionPropertyBuilder | |||
$this->productFamilySectionPropertySolver = $productFamilySectionPropertySolver; | |||
} | |||
public function enable(ProductFamilyInterface $productFamily, SectionInterface $section, bool $flush = true): void | |||
{ | |||
$productFamilySectionProperty = $this->productFamilySectionPropertySolver->getProductFamilySectionProperty($productFamily, $section); | |||
@@ -47,4 +48,18 @@ class ProductFamilySectionPropertyBuilder | |||
} | |||
} | |||
public function disable(ProductFamilyInterface $productFamily, SectionInterface $section, bool $flush = true): void | |||
{ | |||
$productFamilySectionProperty = $this->productFamilySectionPropertySolver->getProductFamilySectionProperty($productFamily, $section); | |||
if ($productFamilySectionProperty) { | |||
$productFamilySectionProperty->setStatus(0); | |||
$this->entityManager->update($productFamilySectionProperty); | |||
} | |||
if($flush) { | |||
$this->entityManager->flush(); | |||
} | |||
} | |||
} |
@@ -61,6 +61,7 @@ class ProductCategoryFieldDefinition extends AbstractFieldDefinition | |||
'title', | |||
'description', | |||
'image', | |||
'status', | |||
'saleStatus', | |||
'isEligibleTicketRestaurant', | |||
]; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\CaracoleBundle\Definition\Field\User; | |||
use App\Entity\User\GroupUser; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField; | |||
use Lc\CaracoleBundle\Context\MerchantContextTrait; | |||
@@ -82,6 +83,7 @@ class UserFieldDefinition extends SovUserFieldDefinition | |||
->setSortable(true), | |||
'groupUsers' => AssociationField::new('groupUsers') | |||
->setFormTypeOption('choices', $groupUsers) | |||
->setCustomOption('class', GroupUser::class) | |||
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig') | |||
->setFormTypeOption('choice_label', function ($choice) { | |||
return $choice->getTitle() . '[' . $choice->getMerchant() . ']'; |
@@ -39,7 +39,7 @@ class ProductCategoriesFilter extends AssociationFilter | |||
$isOffline = " [Hors ligne]"; | |||
} | |||
$section = ' ['.$category->getSection()->getTitle().']' ;; | |||
return $category->getTitle() . $section. $isOffline; | |||
return $category . $section. $isOffline; | |||
} | |||
) |
@@ -0,0 +1,38 @@ | |||
<?php | |||
namespace Lc\CaracoleBundle\Field\Filter\User; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||
use Lc\SovBundle\Field\Filter\AssociationFilter; | |||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
/** | |||
* @author La clic ! <contact@laclic.fr> | |||
*/ | |||
class UserExtraInfoCityFilter extends AssociationFilter | |||
{ | |||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||
{ | |||
$builder->add( | |||
$this->getFieldPropertySnake($fieldDto->getProperty()), | |||
TextType::class, | |||
array( | |||
'required' => false, | |||
'attr' => array( | |||
'class' => ' input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
} | |||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, $filteredValue = null) | |||
{ | |||
if ($filteredValue !== null) { | |||
$repositoryQuery->filterByExtraInfoCity('%' . $filteredValue . '%'); | |||
} | |||
} | |||
} |
@@ -0,0 +1,38 @@ | |||
<?php | |||
namespace Lc\CaracoleBundle\Field\Filter\User; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||
use Lc\SovBundle\Field\Filter\AssociationFilter; | |||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
/** | |||
* @author La clic ! <contact@laclic.fr> | |||
*/ | |||
class UserExtraInfoZipFilter extends AssociationFilter | |||
{ | |||
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array()) | |||
{ | |||
$builder->add( | |||
$this->getFieldPropertySnake($fieldDto->getProperty()), | |||
TextType::class, | |||
array( | |||
'required' => false, | |||
'attr' => array( | |||
'class' => ' input-sm', | |||
'form' => 'filters-form', | |||
), | |||
) | |||
); | |||
} | |||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, $filteredValue = null) | |||
{ | |||
if ($filteredValue !== null) { | |||
$repositoryQuery->filterByExtraInfoZip('%' . $filteredValue . '%'); | |||
} | |||
} | |||
} |
@@ -25,6 +25,15 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery | |||
parent::__construct($repository, 'productFamily', $paginator); | |||
} | |||
public function resetRelationsJoin(): void | |||
{ | |||
$this->isJoinSections = false; | |||
$this->isJoinProductCategories = false; | |||
$this->isJoinProductFamilySectionProperties = false; | |||
$this->isJoinProducts = false; | |||
$this->isJoinQualityLabels = false; | |||
} | |||
public function joinProductFamilySectionProperties(bool $addSelect = true): self | |||
{ | |||
if (!$this->isJoinProductFamilySectionProperties) { | |||
@@ -178,7 +187,8 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery | |||
$this->innerJoin('.products', 'products'); | |||
if ($addSelect) { | |||
$this->addSelect('products'); | |||
// Décommenté sinon doctrine n'hydrate pas correctement les produits liés au ProductFamily (exemple : un seul sur deux) | |||
// $this->addSelect('products'); | |||
} | |||
} | |||
return $this; |
@@ -11,6 +11,7 @@ class UserRepositoryQuery extends SovUserRepositoryQuery | |||
use MerchantRepositoryQueryTrait; | |||
protected $isJoinUserMerchants = false; | |||
protected $isJoinAddresses = false; | |||
public function joinUserMerchants(): self | |||
@@ -24,6 +25,17 @@ class UserRepositoryQuery extends SovUserRepositoryQuery | |||
return $this; | |||
} | |||
public function joinAddresses(): self | |||
{ | |||
if (!$this->isJoinAddresses) { | |||
$this->isJoinAddresses = true; | |||
return $this | |||
->innerJoin('.addresses', 'addresses'); | |||
} | |||
return $this; | |||
} | |||
public function filterMerchantIsActive(): self | |||
{ | |||
$this->joinUserMerchants(); | |||
@@ -38,4 +50,22 @@ class UserRepositoryQuery extends SovUserRepositoryQuery | |||
->andWhere('userMerchants.merchant = :merchant') | |||
->setParameter('merchant', $merchant); | |||
} | |||
public function filterByExtraInfoZip(string $zip) | |||
{ | |||
$this->joinAddresses(); | |||
return $this | |||
->andWhere('.extraInfoZip LIKE :extraInfoZip OR addresses.zip LIKE :extraInfoZip') | |||
->setParameter('extraInfoZip', $zip); | |||
} | |||
public function filterByExtraInfoCity(string $city) | |||
{ | |||
$this->joinAddresses(); | |||
return $this | |||
->andWhere('.extraInfoCity LIKE :extraInfoCity OR addresses.city LIKE :extraInfoCity') | |||
->setParameter('extraInfoCity', $city); | |||
} | |||
} |
@@ -29,6 +29,7 @@ action: | |||
history: Historique | |||
credit: Voir l'historique de crédit | |||
switchUser: Prendre la main | |||
exportOrderPurchasesAsArchive: Récapitulatif des commandes | |||
setting_definition: | |||
merchant: |
@@ -1,7 +0,0 @@ | |||
{% import '@LcCaracole/admin/section/macros.html.twig' as macros_section %} | |||
{% set item = entity.instance %} | |||
{% for section_property in item.productFamilySectionProperties %} | |||
{{ macros_section.section_badge(section_property.section) }} | |||
{% else %} | |||
<span class="badge badge-secondary">Aucune</span> | |||
{% endfor %} |
@@ -1,4 +1,9 @@ | |||
{% macro section_badge(section) %} | |||
<span class="badge badge-secondary {{ section_container.solver.getHtmlClass(section) }}">{{ section.title }}</span> | |||
{% endmacro %} | |||
{% macro section_badge_light_custom(section,title, status= 1) %} | |||
<span class="badge badge-secondary {{ status !=1 ? 'stripped'}} {{ section_container.solver.getHtmlClass(section) }}-light">{{ title }}</span> | |||
{% endmacro %} |
@@ -0,0 +1,11 @@ | |||
{% set user = entity.instance %} | |||
{% set city = user.extraInfoCity %} | |||
{% if city is not empty %} | |||
<span class="badge badge-secondary">{{ city }}</span> | |||
{% elseif user.addresses is not empty %} | |||
{% for addresse in user.addresses %} | |||
<span class="badge badge-secondary">{{ addresse.city }}</span> | |||
{% endfor %} | |||
{% else %} | |||
<span class="badge badge-secondary">Aucun(e)</span> | |||
{% endif %} |
@@ -0,0 +1,11 @@ | |||
{% set user = entity.instance %} | |||
{% set zip = user.extraInfoZip %} | |||
{% if zip is not empty %} | |||
<span class="badge badge-secondary">{{ zip }}</span> | |||
{% elseif user.addresses is not empty %} | |||
{% for addresse in user.addresses %} | |||
<span class="badge badge-secondary">{{ addresse.zip }}</span> | |||
{% endfor %} | |||
{% else %} | |||
<span class="badge badge-secondary">Aucun(e)</span> | |||
{% endif %} |
@@ -2,9 +2,23 @@ | |||
namespace Lc\CaracoleBundle\Solver\Product; | |||
use Lc\CaracoleBundle\Model\Product\ProductCategoryInterface; | |||
class ProductCategorySolver | |||
{ | |||
public function isOnline(ProductCategoryInterface $productCategory) | |||
{ | |||
if ($productCategory->getParent()) { | |||
if ($productCategory->getStatus() && $productCategory->getParent()->getStatus()) { | |||
return true; | |||
} | |||
} elseif ($productCategory->getStatus()) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
} | |||
@@ -18,6 +18,7 @@ class ProductFamilySectionPropertySolver | |||
} | |||
return null; | |||
} | |||
} | |||
@@ -7,6 +7,7 @@ use Doctrine\Common\Collections\Collection; | |||
use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductFamilyModel; | |||
use Lc\CaracoleBundle\Model\Product\ProductFamilySectionPropertyInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductInterface; | |||
use Lc\CaracoleBundle\Model\Reduction\ReductionCatalogInterface; | |||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||
@@ -15,10 +16,14 @@ class ProductFamilySolver | |||
{ | |||
protected ProductSolver $productSolver; | |||
protected ProductFamilySectionPropertySolver $productFamilySectionPropertySolver; | |||
protected ProductCategorySolver $productCategorySolver; | |||
public function __construct(ProductSolver $productSolver) | |||
public function __construct(ProductSolver $productSolver, ProductFamilySectionPropertySolver $productFamilySectionPropertySolver, ProductCategorySolver $productCategorySolver) | |||
{ | |||
$this->productSolver = $productSolver; | |||
$this->productFamilySectionPropertySolver = $productFamilySectionPropertySolver; | |||
$this->productCategorySolver = $productCategorySolver; | |||
} | |||
@@ -467,5 +472,17 @@ class ProductFamilySolver | |||
return false; | |||
} | |||
public function isCategoriesOnlineInSection(ProductFamilyInterface $productFamily, SectionInterface $section):bool | |||
{ | |||
$isCategoriesOnlineInSection =false; | |||
foreach ($productFamily->getProductCategories() as $productCatgory){ | |||
if($productCatgory->getSection() === $section && $this->productCategorySolver->isOnline($productCatgory)){ | |||
$isCategoriesOnlineInSection = true; | |||
} | |||
} | |||
return $isCategoriesOnlineInSection; | |||
} | |||
} | |||
@@ -113,11 +113,15 @@ class StoreTwigExtension extends AbstractExtension | |||
return $this->sectionResolver->isOutOfSection(); | |||
} | |||
private $sections = null; | |||
public function getSections() | |||
{ | |||
return $this->sectionStore | |||
if(!$this->sections){ | |||
$this->sections = $this->sectionStore | |||
->setMerchant($this->merchantResolver->getCurrent()) | |||
->getOnline(); | |||
} | |||
return $this->sections; | |||
} | |||
public function getMerchants() |