Browse Source

Merge branch 'develop'

master
Guillaume 1 year ago
parent
commit
d0600d2765
30 changed files with 424 additions and 173 deletions
  1. +41
    -2
      Builder/Order/OrderShopBuilder.php
  2. +44
    -0
      Builder/Product/ProductFamilyBuilder.php
  3. +5
    -2
      Builder/User/VisitorBuilder.php
  4. +6
    -3
      Controller/AbstractAdminController.php
  5. +4
    -30
      Controller/AdminControllerTrait.php
  6. +1
    -1
      Controller/Order/CartController.php
  7. +54
    -43
      Controller/Product/FavoriteController.php
  8. +1
    -1
      Controller/Product/ProductFamilyAdminController.php
  9. +7
    -2
      Definition/Field/FieldDefinitionTrait.php
  10. +6
    -2
      Definition/Field/Product/ProductCategoryFieldDefinition.php
  11. +25
    -9
      Definition/Field/Reduction/ReductionCatalogFieldDefinition.php
  12. +6
    -2
      Definition/Field/Site/NewsFieldDefinition.php
  13. +15
    -6
      Definition/Field/User/UserFieldDefinition.php
  14. +0
    -3
      Factory/Address/AddressFactory.php
  15. +10
    -4
      Model/Product/ProductFamilyModel.php
  16. +1
    -1
      Repository/Order/OrderShopRepositoryQuery.php
  17. +7
    -0
      Repository/Product/ProductCategoryRepositoryQuery.php
  18. +7
    -0
      Repository/Product/ProductCategoryStore.php
  19. +6
    -2
      Repository/Product/ProductFamilyRepositoryQuery.php
  20. +67
    -1
      Repository/Product/ProductFamilyStore.php
  21. +56
    -35
      Resolver/ProductFamilyResolver.php
  22. +9
    -3
      Resolver/SectionResolver.php
  23. +2
    -2
      Resources/translations/admin.fr.yaml
  24. +6
    -4
      Resources/views/admin/order/field/distribution.html.twig
  25. +9
    -1
      Resources/views/admin/product/field/price_with_tax.html.twig
  26. +5
    -0
      Resources/views/admin/user/field/newsletters.html.twig
  27. +16
    -1
      Solver/Order/OrderShopSolver.php
  28. +2
    -1
      Solver/Product/ProductFamilySectionPropertySolver.php
  29. +1
    -7
      Solver/Product/ProductFamilySolver.php
  30. +5
    -5
      Transformer/Order/OrderShopTransformer.php

+ 41
- 2
Builder/Order/OrderShopBuilder.php View File

@@ -48,6 +48,7 @@ use Lc\CaracoleBundle\Solver\Product\ProductSolver;
use Lc\CaracoleBundle\Statistic\Product\ProductsSalesStatistic;
use Lc\SovBundle\Model\User\UserInterface;

use Lc\SovBundle\Translation\FlashBagTranslator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;

@@ -63,7 +64,7 @@ class OrderShopBuilder
protected OrderProductBuilder $orderProductBuilder;
protected DocumentBuilder $documentBuilder;
protected EventDispatcherInterface $eventDispatcher;
protected FlashBagInterface $flashBag;
protected FlashBagTranslator $flashBag;
protected ProductSolver $productSolver;
protected OrderShopResolver $orderShopResolver;
protected OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver;
@@ -84,7 +85,7 @@ class OrderShopBuilder
DocumentBuilder $documentBuilder,
PriceSolver $priceSolver,
EventDispatcherInterface $eventDispatcher,
FlashBagInterface $flashBag,
FlashBagTranslator $flashBag,
ProductSolver $productSolver,
OrderShopResolver $orderShopResolver,
OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver,
@@ -322,6 +323,8 @@ class OrderShopBuilder
$persist = true
): OrderShopInterface {

// @TODO : intégrer la gestion des OrderPackProduct dans cette méthode

// TODO essayer de comprendre pourquoi on doit faire un refresh ici
$this->entityManager->refresh($orderShop1);
$this->entityManager->refresh($orderShop2);
@@ -645,5 +648,41 @@ class OrderShopBuilder
return $productsSalesStatistic->getAsArray();
}

public function delete(OrderShopInterface $orderShop)
{
// delete OrderProduct
foreach($orderShop->getOrderProducts() as $orderProduct) {
$this->entityManager->delete($orderProduct);
}

// delete OrderPackProduct
foreach($orderShop->getOrderPackProducts() as $orderPackProduct) {
$this->entityManager->delete($orderPackProduct);
}

// delete OrderPayment
foreach($orderShop->getOrderPayments() as $orderPayment) {
$this->entityManager->delete($orderPayment);
}

// delete OrderReductionCarts
foreach($orderShop->getOrderReductionCarts() as $orderReductionCart) {
$this->entityManager->delete($orderReductionCart);
}

// delete OrderReductionCredits
foreach($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
$this->entityManager->delete($orderReductionCredit);
}

// delete OrderStatusHistory
foreach($orderShop->getOrderStatusHistories() as $orderStatusHistory) {
$this->entityManager->delete($orderStatusHistory);
}

// delete OrderShop
$this->entityManager->delete($orderShop);

$this->entityManager->flush();
}
}

+ 44
- 0
Builder/Product/ProductFamilyBuilder.php View File

@@ -2,7 +2,51 @@

namespace Lc\CaracoleBundle\Builder\Product;

use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Container\Section\SectionContainer;
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;

class ProductFamilyBuilder
{
protected EntityManagerInterface $entityManager;
protected SectionContainer $sectionContainer;

public function __construct(
EntityManagerInterface $entityManager,
SectionContainer $sectionContainer
)
{
$this->entityManager = $entityManager;
$this->sectionContainer = $sectionContainer;
}

public function setMerchant(ProductFamilyInterface $productFamily, MerchantInterface $merchant): void
{
$sectionStore = $this->sectionContainer->getStore()->setMerchant($merchant);

// Les ProductFamilySectionProperty sont créées en double, on rectifie ici
$productFamilySectionPropertyArray = [];
foreach($productFamily->getProductFamilySectionProperties() as $productFamilySectionProperty) {
$productFamilySectionPropertyArray[$productFamilySectionProperty->getId()] = $productFamilySectionProperty;
$productFamily->removeProductFamilySectionProperty($productFamilySectionProperty);
}

foreach($productFamilySectionPropertyArray as $productFamilySectionProperty) {
$oldSection = $productFamilySectionProperty->getSection();
$newSection = $sectionStore->getOneByDevAlias($oldSection->getDevAlias());

if($newSection) {
$productFamilySectionProperty->setProductFamily($productFamily);
$productFamilySectionProperty->setSection($newSection);
$productFamily->addProductFamilySectionProperty($productFamilySectionProperty);
}
else {
$this->entityManager->remove($productFamilySectionProperty);
$productFamily->removeProductFamilySectionProperty($productFamilySectionProperty);
}
}

$productFamily->initProductCategories();
}
}

+ 5
- 2
Builder/User/VisitorBuilder.php View File

@@ -45,8 +45,11 @@ class VisitorBuilder

$visitor->setLastAccess(new \DateTime());

$this->entityManager->update($visitor);
$this->entityManager->flush();
// Erreur : The EntityManager is closed. #713
if($this->entityManager->isOpen()) {
$this->entityManager->update($visitor);
$this->entityManager->flush();
}
}

// setCookieVisitor

+ 6
- 3
Controller/AbstractAdminController.php View File

@@ -64,9 +64,12 @@ abstract class AbstractAdminController extends SovAbstractAdminController
$controller->configureFields($autocompleteContext['originatingPage'])
)->getByProperty($autocompleteContext['propertyName']);

$filterManager = $this->get(FilterManager::class);
$filteredValue = ['value' => $context->getRequest()->query->get('q')];
$filterManager->applyFilter($repositoryQuery, $field, $filteredValue);
if($field) {
$filterManager = $this->get(FilterManager::class);
$filteredValue = ['value' => $context->getRequest()->query->get('q')];
$filterManager->applyFilter($repositoryQuery, $field, $filteredValue);
}

$repositoryQuery->select('.' . $autocompleteContext['propertyName']);

$responses = array();

+ 4
- 30
Controller/AdminControllerTrait.php View File

@@ -130,40 +130,14 @@ trait AdminControllerTrait
$newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance());

$merchant = $duplicateOtherMerchantForm->get('merchants')->getData();
//
if($this->isInstanceOf(ProductFamilyInterface::class)) {
$sectionStore = $this->getSectionContainer()->getStore()->setMerchant($merchant);

// Les ProductFamilySectionproperty sont créées en double, on rectifie ici
// @TODO : j'imagine qu'on peut faire mieux que ça. Résoudre le problème à la base par exemple.
$productFamilySectionPropertyArray = [];
foreach($newEntity->getProductFamilySectionProperties() as $productFamilySectionProperty) {
$productFamilySectionPropertyArray[$productFamilySectionProperty->getId()] = $productFamilySectionProperty;
$newEntity->removeProductFamilySectionProperty($productFamilySectionProperty);
}

foreach($productFamilySectionPropertyArray as $productFamilySectionProperty) {
$oldSection = $productFamilySectionProperty->getSection();
$newSection = $sectionStore->getOneByDevAlias($oldSection->getDevAlias());

if($newSection) {
$productFamilySectionProperty->setProductFamily($newEntity);
$productFamilySectionProperty->setSection($newSection);
$newEntity->addProductFamilySectionProperty($productFamilySectionProperty);
}
else {
$entityManager->remove($productFamilySectionProperty);
$newEntity->removeProductFamilySectionProperty($productFamilySectionProperty);
}
}

$newEntity->initProductCategories();
}
$this->getProductFamilyContainer()->getBuilder()->setMerchant($newEntity, $merchant);
}
else {
$newEntity->setMerchant($merchant);
}
//
//

$entityManager->create($newEntity, false);
$entityManager->flush();


+ 1
- 1
Controller/Order/CartController.php View File

@@ -30,7 +30,7 @@ class CartController extends AbstractController
$data = $request->request->all();

if (isset($data['order_products']['id_product_family'])) {
$idProductFamily = $data['order_products']['id_product_family'];
$idProductFamily = (int) $data['order_products']['id_product_family'];
$this->productFamily = $this->getProductFamilyContainer()->getStore()->getOneById($idProductFamily);

if(!$this->productFamily) {

+ 54
- 43
Controller/Product/FavoriteController.php View File

@@ -14,26 +14,31 @@ class FavoriteController extends AbstractController
*/
public function toggle(Request $request)
{
$user = $this->_getUser();
$user = $this->getUserCurrent();
$productFamily = $this->_getProductFamily($request);

if ($user->getFavoriteProductFamilies()->contains($productFamily)) {
$user->removeFavoriteProductFamily($productFamily);
$isFavorite = false;
$message = 'Le produit a bien été supprimé de vos favoris';
} else {
$user->addFavoriteProductFamily($productFamily);
$isFavorite = true;
$message = 'Le produit a bien été ajouté à vos favoris';
if($user && $productFamily) {
if ($user->getFavoriteProductFamilies()->contains($productFamily)) {
$user->removeFavoriteProductFamily($productFamily);
$isFavorite = false;
$message = 'Le produit a bien été supprimé de vos favoris';
} else {
$user->addFavoriteProductFamily($productFamily);
$isFavorite = true;
$message = 'Le produit a bien été ajouté à vos favoris';
}

$this->_saveUser($user);

return new JsonResponse([
'return' => 'success',
'is_favorite' => $isFavorite,
'message' => $message
]);
}
else {
return $this->_errorResponse();
}

$this->_saveUser($user);

return new JsonResponse([
'return' => 'success',
'is_favorite' => $isFavorite,
'message' => $message
]);
}

/**
@@ -41,16 +46,21 @@ class FavoriteController extends AbstractController
*/
public function add(Request $request)
{
$user = $this->_getUser();
$user = $this->getUserCurrent();
$productFamily = $this->_getProductFamily($request);

$user->addFavoriteProductFamily($productFamily);
$this->_saveUser($user);
if($user && $productFamily) {
$user->addFavoriteProductFamily($productFamily);
$this->_saveUser($user);

return new JsonResponse([
'return' => 'success',
'message' => 'Le produit a bien été ajouté à vos favoris'
]);
return new JsonResponse([
'return' => 'success',
'message' => 'Le produit a bien été ajouté à vos favoris'
]);
}
else {
return $this->_errorResponse();
}
}

/**
@@ -58,32 +68,27 @@ class FavoriteController extends AbstractController
*/
public function delete(Request $request)
{
$user = $this->_getUser();
$user = $this->getUserCurrent();
$productFamily = $this->_getProductFamily($request);

$user->removeFavoriteProductFamily($productFamily);
$this->_saveUser($user);

return new JsonResponse([
'return' => 'success',
'message' => 'Le produit a bien été supprimé de vos favoris'
]);
}
if($user && $productFamily) {
$user->removeFavoriteProductFamily($productFamily);
$this->_saveUser($user);

private function _getUser()
{
$user = $this->getUserCurrent();
if (!$user) {
throw new \ErrorException('Vous devez être connecté pour gérer vos favoris');
return new JsonResponse([
'return' => 'success',
'message' => 'Le produit a bien été supprimé de vos favoris'
]);
}
else {
return $this->_errorResponse();
}

return $user;
}

private function _saveUser($user)
{
$entityManager = $this->getEntityManager();
$entityManager->persist($user);
$entityManager->update($user);
$entityManager->flush();
}

@@ -97,8 +102,14 @@ class FavoriteController extends AbstractController

if (isset($productFamily) && $productFamily) {
return $productFamily;
} else {
throw new \ErrorException('Ce produit est introuvable');
}
}

private function _errorResponse()
{
return new JsonResponse([
'return' => 'error',
'message' => 'Une erreur est survenue.'
]);
}
}

+ 1
- 1
Controller/Product/ProductFamilyAdminController.php View File

@@ -18,7 +18,7 @@ abstract class ProductFamilyAdminController extends AbstractAdminController
public function configureCrud(Crud $crud): Crud
{
$crud = parent::configureCrud($crud);
$crud->setPaginatorPageSize(100);
if ($this->getRequestCrudAction() === ActionDefinition::SORT) {
$crud->setDefaultSort(['position' => 'ASC']);
} else {

+ 7
- 2
Definition/Field/FieldDefinitionTrait.php View File

@@ -12,14 +12,19 @@ trait FieldDefinitionTrait
use MerchantContextTrait;
use SectionContextTrait;

protected ?array $sectionArray = null;

public function configureFieldsBase(): array
{
$sectionArray = $this->sectionStore->setMerchant($this->merchant)->get();
if(is_null($this->sectionArray)){
$this->sectionArray = $this->sectionStore->setMerchant($this->merchant)->get();
}


return array_merge(parent::configureFieldsBase(), [
'section' => AssociationField::new('section')
->setTemplatePath('@LcCaracole/admin/section/field/section.html.twig')
->setFormTypeOption('choices', $sectionArray)
->setFormTypeOption('choices', $this->sectionArray)
]);
}


+ 6
- 2
Definition/Field/Product/ProductCategoryFieldDefinition.php View File

@@ -18,6 +18,8 @@ class ProductCategoryFieldDefinition extends AbstractFieldDefinition
protected SectionStore $sectionStore;
protected ProductCategoryStore $productCategoryStore;

protected ?array $productCategoryArray = null;

public function __construct(
TranslatorAdmin $translatorAdmin,
SectionStore $sectionStore,
@@ -70,15 +72,17 @@ class ProductCategoryFieldDefinition extends AbstractFieldDefinition

public function configureFields(): array
{
$productCategoryArray = $this->productCategoryStore
if(is_null($this->productCategoryArray)) {
$this->productCategoryArray = $this->productCategoryStore
->setSection($this->section)
->getParents();
}

return [
'title' => TextField::new('title')->setSortable(true),
'position' => NumberField::new('position')->setSortable(true),
'parent' => AssociationField::new('parent')
->setFormTypeOption('choices', $productCategoryArray)
->setFormTypeOption('choices', $this->productCategoryArray)
->setFormTypeOption(
'choice_label',
function ($productCategory) {

+ 25
- 9
Definition/Field/Reduction/ReductionCatalogFieldDefinition.php View File

@@ -27,6 +27,11 @@ class ReductionCatalogFieldDefinition extends AbstractFieldDefinition
protected ProductFamilyStore $productFamilyStore;
protected ProductCategoryStore $productCategoryStore;

protected ?array $groupUserArray = null;
protected ?array $usersArray= null;
protected ?array $productFamilyArray= null;
protected ?array $productCategoryArray= null;

public function __construct(
TranslatorAdmin $translatorAdmin,
GroupUserStore $groupUserStore,
@@ -81,10 +86,21 @@ class ReductionCatalogFieldDefinition extends AbstractFieldDefinition

public function configureFields(): array
{
$groupUserArray = $this->groupUserStore->setMerchant($this->merchant)->get();
$usersArray = $this->userStore->setMerchant($this->merchant)->getJoinGroupUsers();
$productFamilyArray = $this->productFamilyStore->setMerchant($this->merchant)->get();
$productCategoryArray = $this->productCategoryStore->setMerchant($this->merchant)->get();
if(is_null($this->groupUserArray)) {
$this->groupUserArray = $this->groupUserStore->setMerchant($this->merchant)->get();
}

if(is_null($this->usersArray)) {
$this->usersArray = $this->userStore->setMerchant($this->merchant)->getJoinGroupUsers();
}

if(is_null($this->productFamilyArray)) {
$this->productFamilyArray = $this->productFamilyStore->setMerchant($this->merchant)->get();
}

if(is_null($this->productCategoryArray)) {
$this->productCategoryArray = $this->productCategoryStore->setMerchant($this->merchant)->get();
}

return [
'title' => TextField::new('title')->setSortable(true),
@@ -116,13 +132,13 @@ class ReductionCatalogFieldDefinition extends AbstractFieldDefinition
'groupUsersActive' => BooleanField::new('groupUsersActive')->setFormTypeOption('mapped', false),
'groupUsers' => AssociationField::new('groupUsers')
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig')
->setFormTypeOption('choices', $groupUserArray),
->setFormTypeOption('choices', $this->groupUserArray),

'usersActive' => BooleanField::new('usersActive')->setFormTypeOption('mapped', false),

'users' => AssociationField::new('users')
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig')
->setFormTypeOption('choices', $usersArray)
->setFormTypeOption('choices', $this->usersArray)
->setFormTypeOption(
'choice_attr',
function ($choice, $key, $value) {
@@ -149,13 +165,13 @@ class ReductionCatalogFieldDefinition extends AbstractFieldDefinition
$section = ' [' . $category->getSection()->getTitle() . ']';;
return $category . $section . $isOffline;
})
->setFormTypeOption('choices', $productCategoryArray),
->setFormTypeOption('choices', $this->productCategoryArray),


'productFamiliesActive' => BooleanField::new('productFamiliesActive')->setFormTypeOption('mapped', false),
'productFamilies' => AssociationField::new('productFamilies')
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig')
->setFormTypeOption('choices', $productFamilyArray)
->setFormTypeOption('choices', $this->productFamilyArray)
->setFormTypeOption(
'choice_attr',
function ($choice, $key, $value) {
@@ -170,7 +186,7 @@ class ReductionCatalogFieldDefinition extends AbstractFieldDefinition
}
),
'productFamily' => AssociationField::new('productFamily')
->setFormTypeOption('choices', $productFamilyArray)
->setFormTypeOption('choices', $this->productFamilyArray)
];
}
}

+ 6
- 2
Definition/Field/Site/NewsFieldDefinition.php View File

@@ -12,6 +12,8 @@ class NewsFieldDefinition extends SovNewsFieldDefinition
{
use FieldDefinitionTrait;

protected ?array $newsletterArray = null;

protected SectionStore $sectionStore;
protected NewsletterStore $newsletterStore;

@@ -36,12 +38,14 @@ class NewsFieldDefinition extends SovNewsFieldDefinition
{
$fieldArray = parent::configureFields();

$newsletterArray = $this->newsletterStore
if(is_null($this->newsletterArray)){
$this->newsletterArray = $this->newsletterStore
->setSection($this->section)
->setMerchant($this->merchant)
->get();
}

$fieldArray['newsletter']->setFormTypeOption('choices', $newsletterArray);
$fieldArray['newsletter']->setFormTypeOption('choices', $this->newsletterArray);

return $fieldArray;
}

+ 15
- 6
Definition/Field/User/UserFieldDefinition.php View File

@@ -21,15 +21,19 @@ class UserFieldDefinition extends SovUserFieldDefinition
{
use MerchantContextTrait;

protected ?array $newsletterArray = null;
protected ?array $groupUserArray = null;

protected GroupUserStore $groupUserStore;
protected NewsletterStore $newsletterStore;

public function __construct(
TranslatorAdmin $translatorAdmin,
RolesDefinition $rolesDefinition,
GroupUserStore $groupUserStore,
GroupUserStore $groupUserStore,
NewsletterStore $newsletterStore
) {
)
{
parent::__construct($translatorAdmin, $rolesDefinition);

$this->groupUserStore = $groupUserStore;
@@ -70,19 +74,24 @@ class UserFieldDefinition extends SovUserFieldDefinition

public function configureFields(): array
{
$groupUsers = $this->groupUserStore->setMerchant($this->merchant)->getAll();
$newsletters = $this->newsletterStore->getAll();
if (is_null($this->newsletterArray)) {
$this->newsletterArray = $this->newsletterStore->getAll();
}

if (is_null($this->groupUserArray)) {
$this->groupUserArray = $this->groupUserStore->setMerchant($this->merchant)->getAll();
}

return array_merge(parent::configureFields(), [
'isSaleAlwaysOpen' => BooleanField::new('isSaleAlwaysOpen'),
'newsletters' => AssociationField::new('newsletters')
->setFormTypeOption('choices', $newsletters)
->setFormTypeOption('choices', $this->newsletterArray)
->setFormTypeOption('choice_label', function ($choice) {
return $choice->getTitle() . '[' . $choice->getSection()->getMerchant() . ']';
})
->setSortable(true),
'groupUsers' => AssociationField::new('groupUsers')
->setFormTypeOption('choices', $groupUsers)
->setFormTypeOption('choices', $this->groupUserArray)
->setCustomOption('class', GroupUser::class)
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig')
->setFormTypeOption('choice_label', function ($choice) {

+ 0
- 3
Factory/Address/AddressFactory.php View File

@@ -15,9 +15,6 @@ class AddressFactory extends AbstractFactory
$class = AddressContainer::getEntityFqcn();
$address = new $class;

$address->setMerchant($merchant);

return $address;
}

}

+ 10
- 4
Model/Product/ProductFamilyModel.php View File

@@ -49,11 +49,17 @@ abstract class ProductFamilyModel extends AbstractFullEntity implements ProductP
const QUALITY_LABEL_RECUP = 'recup';

static $organicLabels = [
self::QUALITY_LABEL_AB,
self::QUALITY_LABEL_NP,
self::QUALITY_LABEL_HVE,
self::QUALITY_LABEL_TVVR
self::QUALITY_LABEL_AB,
self::QUALITY_LABEL_NP,
self::QUALITY_LABEL_HVE,
self::QUALITY_LABEL_TVVR
];

static $organicStrictLabels = [
self::QUALITY_LABEL_AB,
self::QUALITY_LABEL_NP
];

static $geographicLabels = [
self::QUALITY_LABEL_AOC,
self::QUALITY_LABEL_AOP,

+ 1
- 1
Repository/Order/OrderShopRepositoryQuery.php View File

@@ -61,7 +61,6 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery
public function selectSum(): self
{
$this->joinProduct();
$this->joinDistribution();
return $this
->select(
'SUM(orderProducts.quantityOrder) as quantity, distribution.cycleNumber as cycleNumber, distribution.year as year , product.id as productId'
@@ -161,6 +160,7 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery

public function filterByDistributions(array $distributionArray): self
{
$this->joinDistribution();
return $this
->andWhere('.distribution IN (:distributions)')
->setParameter('distributions', $distributionArray);

+ 7
- 0
Repository/Product/ProductCategoryRepositoryQuery.php View File

@@ -26,6 +26,8 @@ class ProductCategoryRepositoryQuery extends AbstractRepositoryQuery

return $this
->innerJoin('.productFamilies', 'productFamilies');
//@GONE AWAY avec un addSelect('productFamilies') on gagne 10 requetes

}

return $this;
@@ -37,4 +39,9 @@ class ProductCategoryRepositoryQuery extends AbstractRepositoryQuery

return $this->andWhere('productFamilies.status = 1');
}

public function filterByTitle(string $title): self
{
return $this->andWhere('.title LIKE :title')->setParameter('title', $title);
}
}

+ 7
- 0
Repository/Product/ProductCategoryStore.php View File

@@ -53,4 +53,11 @@ class ProductCategoryStore extends AbstractStore
$query->filterByDevAlias($devAlias);
return $query->find();
}

public function getOneByTitle(string $title): ?ProductCategoryInterface
{
$query = $this->createDefaultQuery();
$query->filterByTitle($title);
return $query->findOne();
}
}

+ 6
- 2
Repository/Product/ProductFamilyRepositoryQuery.php View File

@@ -140,7 +140,7 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery
{
return $this->innerJoin('.qualityLabels', 'qualityLabel')
->andWhere('qualityLabel.devAlias IN (:organicLabels)')
->setParameter(':organicLabels', ProductFamilyModel::$organicLabels);
->setParameter(':organicLabels', ProductFamilyModel::$organicStrictLabels);
}

public function filterIsNovelty()
@@ -189,7 +189,7 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery
$this->innerJoin('.products', 'products');
if ($addSelect) {
// Décommenté sinon doctrine n'hydrate pas correctement les produits liés au ProductFamily (exemple : un seul sur deux)
// $this->addSelect('products');
//$this->addSelect('products');
}
}
return $this;
@@ -201,4 +201,8 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery
return $this;
}

public function filterByTitle(string $title): self
{
return $this->andWhere('.title LIKE :title')->setParameter('title', $title);
}
}

+ 67
- 1
Repository/Product/ProductFamilyStore.php View File

@@ -11,6 +11,8 @@ use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\CaracoleBundle\Repository\AbstractStore;
use Lc\SovBundle\Repository\RepositoryQueryInterface;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;

class ProductFamilyStore extends AbstractStore
{
@@ -19,13 +21,16 @@ class ProductFamilyStore extends AbstractStore

protected ProductFamilyRepositoryQuery $query;
protected PriceSolver $priceSolver;
protected CacheInterface $cache;

public function __construct(
ProductFamilyRepositoryQuery $query,
PriceSolver $priceSolver
PriceSolver $priceSolver,
CacheInterface $cache
) {
$this->query = $query;
$this->priceSolver = $priceSolver;
$this->cache = $cache;
}

public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
@@ -60,6 +65,13 @@ class ProductFamilyStore extends AbstractStore
$productFamiliesArray = [];

foreach ($parentCategory->getChildrens() as $i => $category) {
//Essai d'alternative
// foreach ($category->getProductFamilies() as $productFamily) {
// if($productFamily->getStatus()==1) {
// $productFamiliesArray[$productFamily->getId()] = $productFamily;
// }
// }

$productFamiliesCategory = $this->getByCategory($category);
foreach ($productFamiliesCategory as $productFamily) {
$productFamiliesArray[$productFamily->getId()] = $productFamily;
@@ -116,6 +128,25 @@ class ProductFamilyStore extends AbstractStore
return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
}

public function getCachedNovelty($user = null, $organizeByParentCategory = true, $query = null): array
{
$productFamilyStore = $this;
return $this->cache->get($this->getCacheKeyNovelty(), function (ItemInterface $item) use ($productFamilyStore, $user, $organizeByParentCategory, $query) {
$item->expiresAfter(3600);
return $productFamilyStore->getNovelty($user, $organizeByParentCategory, $query);
});
}

public function deleteCacheNovelty(): void
{
$this->cache->delete($this->getCacheKeyNovelty());
}

public function getCacheKeyNovelty()
{
return 'products_novelty_'.$this->section->getId();
}

// getProductFamiliesOrganics
public function getOrganic($user = null, $organizeByParentCategory = true, $query = null)
{
@@ -134,6 +165,31 @@ class ProductFamilyStore extends AbstractStore
return $this->getWithReductions($this->getOnline($query), $user, false, $organizeByParentCategory, true);
}

public function getCachedDiscount($user = null, $organizeByParentCategory = true, $query = null): array
{
$productFamilyStore = $this;

return $this->cache->get($this->getCacheKeyDiscount(), function (ItemInterface $item) use ($productFamilyStore, $user, $organizeByParentCategory, $query) {
$item->expiresAfter(3600);
return $productFamilyStore->getDiscount($user, $organizeByParentCategory, $query);
});
}

public function deleteCacheDiscount(): void
{
$this->cache->delete($this->getCacheKeyDiscount());
}

public function getCacheKeyDiscount()
{
return 'products_discount_'.$this->section->getId();
}

public function loadAllDatas(ProductFamilyInterface $productFamily)
{
$productFamily->getProductFamilySectionProperties()->toArray();
}

// getProductFamiliesFavorites
public function getFavorite($user = null, $organizeByParentCategory = true, $query = null)
{
@@ -227,6 +283,10 @@ class ProductFamilyStore extends AbstractStore

$productFamiliesToReturn = array();
foreach ($productFamilies as $productFamily) {

// Cache : chargement de toutes les données manquantes (fetch eager ne fonctionne pas)
$this->loadAllDatas($productFamily);

foreach ($reductionCatalogs as $reductionCatalog) {
$conditionProductFamilies = $conditionProductFamily = $conditionProductCategory = false;

@@ -301,4 +361,10 @@ class ProductFamilyStore extends AbstractStore
return $productFamiliesToReturn;
}

public function getOneByTitle(string $title): ?ProductFamilyInterface
{
$query = $this->createDefaultQuery();
$query->filterByTitle($title);
return $query->findOne();
}
}

+ 56
- 35
Resolver/ProductFamilyResolver.php View File

@@ -2,8 +2,10 @@

namespace Lc\CaracoleBundle\Resolver;

use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
use Lc\CaracoleBundle\Solver\Order\OrderShopSolver;
use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;

@@ -11,11 +13,13 @@ class ProductFamilyResolver
{
protected PriceSolver $priceSolver;
protected ProductFamilySolver $productFamilySolver;
protected OrderShopSolver $orderShopSolver;

public function __construct(PriceSolver $priceSolver, ProductFamilySolver $productFamilySolver)
public function __construct(PriceSolver $priceSolver, ProductFamilySolver $productFamilySolver, OrderShopSolver $orderShopSolver)
{
$this->priceSolver = $priceSolver;
$this->productFamilySolver = $productFamilySolver;
$this->orderShopSolver = $orderShopSolver;
}

public function getMultiplyingFactor(ProductFamilyInterface $productFamily)
@@ -23,76 +27,93 @@ class ProductFamilyResolver
if ($productFamily->getBehaviorPrice() == ProductFamilyModel::BEHAVIOR_PRICE_BY_PIECE) {
if ($productFamily->getBuyingPrice() > 0) {
return number_format(
$this->priceSolver->getPriceWithTax($productFamily) / $productFamily->getBuyingPrice(),
3
$this->priceSolver->getPriceWithTax($productFamily) / $productFamily->getBuyingPrice(),
3
);
}
} elseif ($productFamily->getBehaviorPrice() == ProductFamilyModel::BEHAVIOR_PRICE_BY_REFERENCE_UNIT) {
if ($productFamily->getBuyingPriceByRefUnit() > 0) {
return number_format(
$this->priceSolver->getPriceByRefUnitWithTax(
$productFamily
) / $productFamily->getBuyingPriceByRefUnit(),
3
$this->priceSolver->getPriceByRefUnitWithTax(
$productFamily
) / $productFamily->getBuyingPriceByRefUnit(),
3
);
}
}
}

public function getCheapestProduct(ProductFamilyInterface $productFamily)
public function getCheapestProduct(ProductFamilyInterface $productFamily, OrderShopInterface $orderShop = null)
{
$priceSolver = $this->priceSolver;

return $this->getCheapestOrMostExpensiveProduct(
$productFamily,
function ($a, $b) use ($priceSolver) {
return $priceSolver->getPriceWithTaxAndReduction(
$a
) > $priceSolver->getPriceWithTaxAndReduction($b);
},
true
$productFamily,
function ($a, $b) use ($priceSolver) {
return $priceSolver->getPriceWithTaxAndReduction(
$a
) > $priceSolver->getPriceWithTaxAndReduction($b);
},
true,
$orderShop
);
}

public function getCheapestProductByRefUnit(ProductFamilyInterface $productFamily)
public function getCheapestProductByRefUnit(ProductFamilyInterface $productFamily, OrderShopInterface $orderShop = null)
{
$priceSolver = $this->priceSolver;

return $this->getCheapestOrMostExpensiveProduct(
$productFamily,
function ($a, $b) use ($priceSolver) {
return $priceSolver->getPriceByRefUnitWithTaxAndReduction(
$a
) > $priceSolver->getPriceByRefUnitWithTaxAndReduction($b);
},
false
$productFamily,
function ($a, $b) use ($priceSolver) {
return $priceSolver->getPriceByRefUnitWithTaxAndReduction(
$a
) > $priceSolver->getPriceByRefUnitWithTaxAndReduction($b);
},
false,
$orderShop
);
}

public function getMostExpensiveProductByRefUnit(ProductFamilyInterface $productFamily)
public function getMostExpensiveProductByRefUnit(ProductFamilyInterface $productFamily, OrderShopInterface $orderShop = null)
{
$priceSolver = $this->priceSolver;

return $this->getCheapestOrMostExpensiveProduct(
$productFamily,
function ($a, $b) use ($priceSolver) {
return $priceSolver->getPriceByRefUnitWithTaxAndReduction(
$a
) < $priceSolver->getPriceByRefUnitWithTaxAndReduction($b);
},
false
$productFamily,
function ($a, $b) use ($priceSolver) {
return $priceSolver->getPriceByRefUnitWithTaxAndReduction(
$a
) < $priceSolver->getPriceByRefUnitWithTaxAndReduction($b);
},
false,
$orderShop
);
}

private function getCheapestOrMostExpensiveProduct(
ProductFamilyInterface $productFamily,
$comparisonFunction,
$returnSelfIfNotActiveProducts
) {
ProductFamilyInterface $productFamily,
$comparisonFunction,
$returnSelfIfNotActiveProducts,
OrderShopInterface $orderShop = null
)
{
if ($productFamily->getActiveProducts()) {
$products = $this->productFamilySolver->getProductsOnline($productFamily)->getValues();

if (count($products) > 0) {
usort($products, $comparisonFunction);

if($orderShop) {
foreach ($products as $product) {

return $product;

// Retourner le produit en fonction de sa disponibilité
// if ($this->orderShopSolver->isProductAvailable($orderShop->getSection(), $orderShop, $product, 1, true))
}
}

return $products[0];
}
} else {

+ 9
- 3
Resolver/SectionResolver.php View File

@@ -111,14 +111,20 @@ class SectionResolver
}
}

/*
* /!\ Cache désactivé car génération d'une erreur du type :
* "A new entity was found through the relationship 'App\Entity\Order\OrderShop#section' that was not configured to cascade persist operations for entity: Marché"
*
* Arrive sur les pages générées via le cache HTTP (CacheController.php)
*/
if ($sectionCurrent) {
$this->cacheSectionCurrent = $sectionCurrent;
//$this->cacheSectionCurrent = $sectionCurrent;
return $sectionCurrent;
} elseif ($returnVisitedIfOutOfSection && $currentVisitedSection) {
$this->cacheSectionVisited = $currentVisitedSection;
//$this->cacheSectionVisited = $currentVisitedSection;
return $currentVisitedSection;
} elseif ($returnDefaultIfOutOfSections && $sectionDefault) {
$this->cacheSectionDefault = $sectionDefault;
//$this->cacheSectionDefault = $sectionDefault;
return $sectionDefault;
}


+ 2
- 2
Resources/translations/admin.fr.yaml View File

@@ -44,8 +44,8 @@ setting_definition:
settings:
orderReferencePrefix: Préfixe référence commandes
orderState: Statut d'ouverture des commandes
orderClosedStart: Période commandes fermées (début)
orderClosedEnd: Période commandes fermées (fin)
orderClosedStart: "Période commandes fermées (début : définir comme date le lendemain du jour de fermeture de la section)"
orderClosedEnd: "Période commandes fermées (fin : définir comme date la veille du jour de ré-ouverture de la section)"
orderMaximumPerCycle: Nombre maximum de commande par cycle de vente
colorPrimary: Couleur primaire
colorSecondary: Couleur secondaire

+ 6
- 4
Resources/views/admin/order/field/distribution.html.twig View File

@@ -10,8 +10,10 @@
{% endif %}
{% endif %}

{% if cycleType == "year" %}
A{{ distribution.cycleNumber }}
{% else %}
{{ labelCycleType ~ distribution.cycleNumber }}A{{ distribution.year|slice(2,2) }}
{% if cycleType is defined %}
{% if cycleType == "year" %}
A{{ distribution.cycleNumber }}
{% else %}
{{ labelCycleType ~ distribution.cycleNumber }}A{{ distribution.year|slice(2,2) }}
{% endif %}
{% endif %}

+ 9
- 1
Resources/views/admin/product/field/price_with_tax.html.twig View File

@@ -1 +1,9 @@
{{ price_solver.getPriceWithTax(entity.instance)|format_price|raw }}
{% set priceWithTax = price_solver.getPriceWithTax(entity.instance)|format_price %}
{% set priceWithTaxAndReduction = price_solver.getPriceWithTaxAndReduction(entity.instance)|format_price %}

{% if priceWithTax != priceWithTaxAndReduction %}
<s>{{ priceWithTax|raw }}</s><br />
{{ priceWithTaxAndReduction|raw }}
{% else %}
{{ priceWithTaxAndReduction|raw }}
{% endif %}

+ 5
- 0
Resources/views/admin/user/field/newsletters.html.twig View File

@@ -0,0 +1,5 @@
{% if entity.instance.getNewsletters()|length %}
<span class="badge badge-success">Oui</span>
{% else %}
<span class="badge badge-secondary">Non</span>
{% endif %}

+ 16
- 1
Solver/Order/OrderShopSolver.php View File

@@ -126,7 +126,7 @@ class OrderShopSolver
// isProductAvailable
public function isProductAvailable(
SectionInterface $section,
OrderShopInterface $orderShop,
?OrderShopInterface $orderShop,
ProductInterface $product,
int $quantityOrder = 0,
bool $checkCart = false
@@ -171,6 +171,16 @@ class OrderShopSolver
}
}

public function isOneProductAvailable(SectionInterface $section, $productArray): bool
{
foreach($productArray as $product) {
if($this->isProductAvailable($section, null, $product, 1, false)) {
return true;
}
}
return false;
}

public function isOneProductAvailableAddCart(OrderShopInterface $orderShop, $products): bool
{
foreach ($products as $product) {
@@ -221,6 +231,11 @@ class OrderShopSolver
}
return $arrayComplementaryOrderShops;
}
public function countValidComplementaryOrderShops(OrderShopInterface $orderShop): int
{
return count($this->getValidComplementaryOrderShops($orderShop));
}

public function getOrderStatusHistory(OrderShopInterface $orderShop, OrderStatusInterface $status)
{

+ 2
- 1
Solver/Product/ProductFamilySectionPropertySolver.php View File

@@ -12,10 +12,11 @@ class ProductFamilySectionPropertySolver
public function getProductFamilySectionProperty(ProductFamilyInterface $productFamily, SectionInterface $section):? ProductFamilySectionPropertyInterface
{
foreach ($productFamily->getProductFamilySectionProperties() as $productFamilySectionProperty) {
if ($productFamilySectionProperty->getSection() == $section) {
if ($productFamilySectionProperty->getSection()->getId() == $section->getId()) {
return $productFamilySectionProperty;
}
}

return null;
}


+ 1
- 7
Solver/Product/ProductFamilySolver.php View File

@@ -152,7 +152,7 @@ class ProductFamilySolver
if ($productFamily->getTaxRate()) {
return $productFamily->getTaxRate();
} else {
return $productFamily->getProductFamilySectionProperties()[0]->getSection()->getMerchant()->getTaxRate();
return $this->getMerchant($productFamily)->getTaxRate();
}
}

@@ -191,7 +191,6 @@ class ProductFamilySolver
return false;
}


public function getProductCategoryChild(ProductFamilyInterface $productFamily, SectionInterface $section)
{
$productCategories = $productFamily->getProductCategories();
@@ -205,7 +204,6 @@ class ProductFamilySolver
return false;
}


public function isPropertyNoveltyOnline(ProductFamilyInterface $productFamily): ?bool
{
if ($productFamily->getPropertyNoveltyExpirationDate()) {
@@ -218,7 +216,6 @@ class ProductFamilySolver
return false;
}


public function countProperties(ProductFamilyInterface $productFamily): bool
{
$count = 0;
@@ -239,7 +236,6 @@ class ProductFamilySolver
return $count;
}


public function hasProductsWithVariousWeight(ProductFamilyInterface $productFamily)
{
if ($productFamily->getActiveProducts()) {
@@ -268,7 +264,6 @@ class ProductFamilySolver
return false;
}


public function getProductsGroupByTitle(ProductFamilyInterface $productFamily): array
{
$arrayProductsGroupByTitle = [];
@@ -489,7 +484,6 @@ class ProductFamilySolver
return false;
}


public function isCategoriesOnlineInSection(ProductFamilyInterface $productFamily, SectionInterface $section): bool
{
$isCategoriesOnlineInSection = false;

+ 5
- 5
Transformer/Order/OrderShopTransformer.php View File

@@ -59,13 +59,13 @@ class OrderShopTransformer

$i = 0;

$orderProductsByParentCategory = $this->orderShopSolver->getOrderProductsByParentCategory($orderShop);
foreach ($orderProductsByParentCategory as $labelCategory => $orderProducts) {
foreach ($orderProducts as $orderProduct) {
// $orderProductsByParentCategory = $this->orderShopSolver->getOrderProductsByParentCategory($orderShop);
// foreach ($orderProductsByParentCategory as $labelCategory => $orderProducts) {
foreach ($orderShop->getOrderProducts() as $orderProduct) {
$data['orderProducts'][$i]['id'] = $orderProduct->getId();
$data['orderProducts'][$i]['product'] = $orderProduct->getProduct()->getId();
$data['orderProducts'][$i]['quantityOrder'] = $orderProduct->getQuantityOrder();
$data['orderProducts'][$i]['labelCategory'] = $labelCategory;
// $data['orderProducts'][$i]['labelCategory'] = $labelCategory;
$data['orderProducts'][$i]['title'] = $orderProduct->getTitle();
$data['orderProducts'][$i]['price'] = $this->priceSolver->getPrice($orderProduct);
$data['orderProducts'][$i]['priceWithTax'] = $this->priceSolver->getPriceWithTax($orderProduct);
@@ -78,7 +78,7 @@ class OrderShopTransformer
);
$i++;
}
}
// }

return $data;
}

Loading…
Cancel
Save