Parcourir la source

Refactoring frontend

packProduct
Guillaume il y a 3 ans
Parent
révision
565388d484
12 fichiers modifiés avec 336 ajouts et 80 suppressions
  1. +3
    -0
      Builder/User/UserMerchantBuilder.php
  2. +5
    -0
      Container/Merchant/MerchantContainer.php
  3. +9
    -3
      Controller/ControllerTrait.php
  4. +101
    -0
      Controller/Product/FavoriteController.php
  5. +1
    -1
      Repository/Order/OrderShopStore.php
  6. +12
    -4
      Repository/Product/ProductFamilyRepositoryQuery.php
  7. +116
    -9
      Repository/Product/ProductFamilyStore.php
  8. +62
    -1
      Solver/Order/OrderShopSolver.php
  9. +3
    -3
      Solver/Price/PriceSolver.php
  10. +9
    -0
      Solver/Product/ProductFamilySolver.php
  11. +2
    -58
      Solver/Product/ProductSolver.php
  12. +13
    -1
      Twig/StoreTwigExtension.php

+ 3
- 0
Builder/User/UserMerchantBuilder.php Voir le fichier

@@ -32,6 +32,9 @@ class UserMerchantBuilder
if (!$userMerchant) {
$userMerchantFactory = new UserMerchantFactory();
$userMerchant = $userMerchantFactory->create($user, $merchant);

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

return $userMerchant;

+ 5
- 0
Container/Merchant/MerchantContainer.php Voir le fichier

@@ -50,4 +50,9 @@ class MerchantContainer
{
return $this->store;
}

public function getBuilder(): MerchantBuilder
{
return $this->builder;
}
}

+ 9
- 3
Controller/ControllerTrait.php Voir le fichier

@@ -39,6 +39,7 @@ use Lc\CaracoleBundle\Model\User\UserMerchantInterface;
use Lc\CaracoleBundle\Model\User\VisitorInterface;
use Lc\CaracoleBundle\Resolver\MerchantResolver;
use Lc\CaracoleBundle\Resolver\SectionResolver;
use Lc\CaracoleBundle\Resolver\VisitorResolver;
use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\SovBundle\Model\User\UserInterface;
use Symfony\Component\Security\Core\Security;
@@ -89,7 +90,7 @@ trait ControllerTrait

public function getMerchantSettingCurrent($settingName)
{
return $this->getSettingValue($this->getCurrentMerchant(), $settingName);
return $this->getSettingValue($this->getMerchantCurrent(), $settingName);
}

public function getSectionSettingCurrent($settingName)
@@ -104,7 +105,7 @@ trait ControllerTrait

public function getVisitorCurrent(): VisitorInterface
{
return $this->get(VisitorResolver::class)->getCurrent();
}

public function getMerchantCurrent(): MerchantInterface
@@ -114,7 +115,12 @@ trait ControllerTrait

public function getUserMerchantCurrent(): UserMerchantInterface
{
return $this->getUserMerchantContainer()->getBuilder()->createIfNotExist($this->getCurrentUser(), $this->getCurrentMerchant());
return $this->getUserMerchantContainer()->getBuilder()->createIfNotExist($this->getUserCurrent(), $this->getMerchantCurrent());
}

public function getMerchantUserCurrent(): MerchantInterface
{
return $this->get(MerchantResolver::class)->getMerchantUser($this->getUserCurrent());
}

public function getSectionCurrent(): SectionInterface

+ 101
- 0
Controller/Product/FavoriteController.php Voir le fichier

@@ -0,0 +1,101 @@
<?php

namespace Lc\CaracoleBundle\Controller\Product;

use Lc\CaracoleBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class FavoriteController extends AbstractController
{
/**
* @Route("/favorite/toggle", name="lc_frontend_favorite_toggle")
*/
public function toggle(Request $request)
{
$user = $this->_getUser();
$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';
}

$this->_saveUser($user);

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

/**
* @Route("/favorite/add", name="lc_frontend_favorite_add")
*/
public function add(Request $request)
{
$user = $this->_getUser();
$productFamily = $this->_getProductFamily($request);

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

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

/**
* @Route("/favorite/delete", name="lc_frontend_favorite_delete")
*/
public function delete(Request $request)
{
$user = $this->_getUser();
$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'
]);
}

private function _getUser()
{
$user = $this->getUserCurrent();
if (!$user) {
throw new \ErrorException('Vous devez être connecté pour gérer vos favoris');
}

return $user;
}

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

private function _getProductFamily($request)
{
$idProductFamily = $request->request->get('idProductFamily');
$productFamily = $this->getProductFamilyContainer()->getStore()->getOneById($idProductFamily);

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

+ 1
- 1
Repository/Order/OrderShopStore.php Voir le fichier

@@ -261,7 +261,7 @@ class OrderShopStore extends AbstractStore
}

// findCartCurrent
public function getOneCartCurrent(array $params, $query = null): ?OrderShopInterface
public function getOneCartCurrent(array $params = [], $query = null): ?OrderShopInterface
{
$query = $this->createDefaultQuery($query);


+ 12
- 4
Repository/Product/ProductFamilyRepositoryQuery.php Voir le fichier

@@ -4,12 +4,15 @@ namespace Lc\CaracoleBundle\Repository\Product;

use Knp\Component\Pager\PaginatorInterface;
use Lc\CaracoleBundle\Model\Product\ProductCategoryInterface;
use Lc\CaracoleBundle\Repository\SectionRepositoryQueryTrait;
use Lc\SovBundle\Repository\AbstractRepositoryQuery;

class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery
{
protected bool $isJoinProductCategories;
protected bool $isJoinProducts;
use SectionRepositoryQueryTrait;

protected bool $isJoinProductCategories = false;
protected bool $isJoinProducts = false;

public function __construct(ProductFamilyRepository $repository, PaginatorInterface $paginator)
{
@@ -50,7 +53,7 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery
$dateTime = new \DateTime();
}

return $this->andWhere(':now <= e.propertyNoveltyExpirationDate')
return $this->andWhere(':now <= .propertyNoveltyExpirationDate')
->setParameter('now', $dateTime);
}

@@ -61,7 +64,7 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery

public function filterIsNovelty()
{
return $this->andWhere(':now <= e.propertyNoveltyExpirationDate')
return $this->andWhere(':now <= .propertyNoveltyExpirationDate')
->setParameter('now', new \DateTime()) ;
}

@@ -72,6 +75,11 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery
return $this;
}

public function filterBySupplier($supplier): self
{
return $this->andWhereEqual('supplier', $supplier);
}

public function joinProductCategories(): self
{
if (!$this->isJoinProductCategories) {

+ 116
- 9
Repository/Product/ProductFamilyStore.php Voir le fichier

@@ -7,6 +7,7 @@ use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCatalogInterface;
use Lc\CaracoleBundle\Repository\SectionStoreTrait;
use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Repository\AbstractStore;
use Lc\SovBundle\Repository\RepositoryQueryInterface;

@@ -26,6 +27,7 @@ class ProductFamilyStore extends AbstractStore
public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{
$query->orderBy('position');
return $query;
}

public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
@@ -55,7 +57,7 @@ class ProductFamilyStore extends AbstractStore
}

// getProductFamiliesNovelties
public function getNovelty($query = null)
public function getNovelty($user = null, $organizeByParentCategory = true, $query = null)
{
$query = $this->createDefaultQuery($query);

@@ -63,11 +65,13 @@ class ProductFamilyStore extends AbstractStore
->filterByPropertyNoveltyExpirationDate()
->filterIsOnline();

return $query->find();
$results = $query->find();

return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
}

// getProductFamiliesOrganics
public function getOrganic($query = null)
public function getOrganic($user = null, $organizeByParentCategory = true, $query = null)
{
$query = $this->createDefaultQuery($query);

@@ -75,26 +79,28 @@ class ProductFamilyStore extends AbstractStore
->filterPropertyOrganicLabel()
->filterIsOnline();

return $query->find();
$results = $query->find();

return $this->getWithReductions($results, $user, false, $organizeByParentCategory);
}

// getProductFamiliesOnDiscount
public function getDiscount($organizeByParentCategory = false, $user = null, $query = null)
public function getDiscount($user = null, $organizeByParentCategory = true, $query = null)
{
return $this->getWithReductions($this->getOnline($query), $user, $organizeByParentCategory, true);
return $this->getWithReductions($this->getOnline($query), $user, false, $organizeByParentCategory);
}

// getProductFamiliesFavorites
public function getFavorite($user = null)
public function getFavorite($user = null, $organizeByParentCategory = true, $query = null)
{
if ($user) {
return $this->getWithReductions($user->getProductFamiliesFavorites(), $user, false, true);
return $this->getWithReductions($user->getProductFamiliesFavorites(), $user, false, $organizeByParentCategory);
}

return [];
}

//findByTerms
// findByTerms
public function getByTerms($terms, $maxResults = false, $query = null)
{
$query = $this->createDefaultQuery($query);
@@ -137,5 +143,106 @@ class ProductFamilyStore extends AbstractStore
}
}

// setReductionForProductFamilies
public function getWithReductions(
array $productFamilies,
UserInterface $user = null,
$organizeByCategory = false,
$organizeByParentCategory = false,
$onlyOnDiscount = false
) {
$conditions = [
'ids' => [],
'categories' => [],
];
foreach ($productFamilies as $productFamily) {
$conditions['ids'][] = $productFamily->getId();
$conditions['categories'] = array_merge(
$conditions['categories'],
$productFamily->getProductCategories()->toArray()
);
}

if ($productFamilies) {
$reductionCatalogs = $this->reductionCatalogStore->getByProductFamilies(
$conditions,
$user
);
}

$productFamiliesToReturn = array();
foreach ($productFamilies as $productFamily) {
foreach ($reductionCatalogs as $reductionCatalog) {
$conditionProductFamilies = $conditionProductFamily = $conditionProductCategory = false;

if ($reductionCatalog->getProductFamilies()->contains(
$productFamily
) || $reductionCatalog->getProductFamilies()->isEmpty()) {
$conditionProductFamilies = true;
}

if ($reductionCatalog->getProductFamily() == $productFamily || $reductionCatalog->getProductFamily(
) === null) {
$conditionProductFamily = true;
}

foreach ($productFamily->getProductCategories() as $productCategory) {
if ($reductionCatalog->getProductCategories()->contains(
$productCategory
) || $reductionCatalog->getProductCategories()->isEmpty()) {
$conditionProductCategory = true;
}
}

if ($conditionProductFamilies && $conditionProductFamily && $conditionProductCategory) {
if ($productFamily->getReductionCatalog()) {
$productFamily->setReductionCatalog(
$this->getBestReductionCatalog(
$productFamily,
$reductionCatalog,
$productFamily->getReductionCatalog()
)
);
} else {
$productFamily->setReductionCatalog($reductionCatalog);
}
}
}

if (($onlyOnDiscount && $productFamily->getReductionCatalog()) || !$onlyOnDiscount) {
if ($organizeByParentCategory) {
$productCategories = $productFamily->getProductCategories();
if ($productCategories && count($productCategories) > 0) {
$parentCategory = $productCategories[0]->getParentCategory();
if ($this->productCategorySolver->isDisplay($parentCategory, $user)) {
if (!isset($productFamiliesToReturn[$parentCategory->getId()])) {
$productFamiliesToReturn[$parentCategory->getId()] = [
'category' => $parentCategory,
'products' => []
];
}
$productFamiliesToReturn[$parentCategory->getId()]['products'][] = $productFamily;
}
}
} elseif ($organizeByCategory) {
foreach ($productFamily->getProductCategories() as $productCategory) {
if ($this->isDisplay($productFamily)) {
$productFamiliesToReturn[$productCategory->getId()][] = $productFamily;
}
}
} else {
if ($this->isDisplay($productFamily)) {
$productFamiliesToReturn[] = $productFamily;
}
}
}
}

if ($organizeByParentCategory) {
uasort($productFamiliesToReturn, array($this, 'compMethodSortProductFamiliesByParentCategory'));
}

return $productFamiliesToReturn;
}

}

+ 62
- 1
Solver/Order/OrderShopSolver.php Voir le fichier

@@ -15,16 +15,19 @@ use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
use Lc\CaracoleBundle\Model\Product\ProductInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver;

class OrderShopSolver
{
protected PriceSolver $priceSolver;
protected EntityManagerInterface $entityManager;
protected ProductSolver $productSolver;

public function __construct(PriceSolver $priceSolver, EntityManagerInterface $entityManager)
public function __construct(PriceSolver $priceSolver, EntityManagerInterface $entityManager, ProductSolver $productSolver)
{
$this->priceSolver = $priceSolver;
$this->entityManager = $entityManager;
$this->productSolver = $productSolver;
}

public function countQuantities(OrderShopInterface $orderShop): int
@@ -101,6 +104,64 @@ class OrderShopSolver
return $quantity;
}

// isProductAvailable
public function isAvailable(ProductInterface $product, $quantityOrder = 0, $checkCart = false, $orderShop = null)
{
if ($product->getStatus() != 1 || $product->getProductFamily()->getStatus() != 1 || !$this->productSolver->isProductSaleStatusOn($product)) {
return false;
}

// @TODO : orderShop à définir où est appelé isAvailable
if ($checkCart && !$orderShop) {
throw new \Exception("Attention : définir le orderShop à l'endroit où est appelé isAvailable");
}

$productFamily = $product->getProductFamily();
$quantityAsked = $quantityOrder;

if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
if (!$quantityOrder) {
$quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product, true);
} else {
$quantityAsked = ($product->getQuantityInherited() / $product->getUnitInherited()->getCoefficient()) * $quantityOrder;
}

if ($checkCart) {
$quantityAsked += $this->getQuantityOrderByProduct($orderShop, $product, true);
}
}

if (($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY
|| $productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT)) {

if (!$quantityOrder) {
$quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product);
}

if ($checkCart) {
$quantityAsked += $this->getQuantityOrderByProduct($orderShop, $product);
}
}

if ($product->getAvailableQuantityInherited() >= $quantityAsked
|| $productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_UNLIMITED) {
return true;
} else {
return false;
}
}

public function isOneProductAvailableAddCart(OrderShopInterface $orderShop, $products): bool
{
foreach ($products as $product) {
if ($this->isAvailable($product, 1, true, $orderShop)) {
return true;
}
}

return false;
}

public function getTotalOrderPayments(OrderShopInterface $orderShop, $mergeComplementaryOrderShop = false): float
{
$totalAmount = floatval(0);

+ 3
- 3
Solver/Price/PriceSolver.php Voir le fichier

@@ -29,15 +29,15 @@ class PriceSolver
$service = '';

if ($entity instanceof ProductPropertyInterface) {
$service = 'productPriceResolver';
$service = 'productPriceSolver';
}

if ($entity instanceof OrderProductInterface) {
$service = 'orderProductPriceResolver';
$service = 'orderProductPriceSolver';
}

if ($entity instanceof OrderShopInterface || is_iterable($entity) || is_array($entity)) {
$service = 'orderShopPriceResolver';
$service = 'orderShopPriceSolver';
}

if (strlen($service) && $entity && method_exists($this->$service, $name)) {

+ 9
- 0
Solver/Product/ProductFamilySolver.php Voir le fichier

@@ -98,6 +98,15 @@ class ProductFamilySolver
return false;
}
}

public function countProductFamiliesOrganizedByParentCategory(array $categories): int
{
$count = 0;
foreach ($categories as $category) {
$count += count($category['products']);
}
return $count;
}
}



+ 2
- 58
Solver/Product/ProductSolver.php Voir le fichier

@@ -2,70 +2,14 @@

namespace Lc\CaracoleBundle\Solver\Product;

use Doctrine\Common\Collections\ArrayCollection;
use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
use Lc\CaracoleBundle\Model\Product\ProductInterface;

class ProductSolver
{

// isProductAvailable
public function isAvailable(ProductInterface $product, $quantityOrder = 0, $checkCart = false, $orderShop = null)
{
if ($product->getStatus() != 1 || $product->getProductFamily()->getStatus() != 1 || !$this->isProductSaleStatusOn($product)) {
return false;
}

// @TODO : orderShop à définir où est appelé isProductAvailable
if ($checkCart && !$orderShop) {
throw new \Exception("Attention jeune padawan : définir le orderShop à l'endroit où est appelé isProductAvailable");
}

$productFamily = $product->getProductFamily();
$quantityAsked = $quantityOrder;

if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
if (!$quantityOrder) {
$quantityAsked = $orderShop->getQuantityOrderByProduct($product, true);
} else {
$quantityAsked = ($product->getQuantityInherited() / $product->getUnitInherited()->getCoefficient()) * $quantityOrder;
}

if ($checkCart) {
$quantityAsked += $orderShop->getQuantityOrderByProduct($product, true);
}
}

if (($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY
|| $productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT)) {

if (!$quantityOrder) {
$quantityAsked = $orderShop->getQuantityOrderByProduct($product);
}

if ($checkCart) {
$quantityAsked += $orderShop->getQuantityOrderByProduct($product);
}
}

if ($product->getAvailableQuantityInherited() >= $quantityAsked
|| $productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_UNLIMITED) {
return true;
} else {
return false;
}
}

public function isOneProductAvailableAddCart(array $products): bool
{
foreach ($products as $product) {
if ($product->isAvailable(1, true)) {
return true;
}
}

return false;
}

public function isProductSaleStatusOn(ProductInterface $product)
{
if ($product->getProductFamily()->getSaleStatus() != 1) {

+ 13
- 1
Twig/StoreTwigExtension.php Voir le fichier

@@ -6,6 +6,7 @@ use Lc\CaracoleBundle\Repository\Config\TaxRateStore;
use Lc\CaracoleBundle\Repository\Config\UnitStore;
use Lc\CaracoleBundle\Repository\Merchant\MerchantRepositoryQuery;
use Lc\CaracoleBundle\Repository\Merchant\MerchantStore;
use Lc\CaracoleBundle\Repository\Order\OrderShopStore;
use Lc\CaracoleBundle\Repository\Product\ProductCategoryStore;
use Lc\CaracoleBundle\Repository\Reminder\ReminderStore;
use Lc\CaracoleBundle\Repository\Section\SectionRepository;
@@ -28,6 +29,7 @@ class StoreTwigExtension extends AbstractExtension
protected UnitStore $unitStore;
protected TaxRateStore $taxRateStore;
protected ProductCategoryStore $productCategoryStore;
protected OrderShopStore $orderShopStore;

public function __construct(
MerchantResolver $merchantResolver,
@@ -37,7 +39,8 @@ class StoreTwigExtension extends AbstractExtension
ReminderStore $reminderStore,
UnitStore $unitStore,
TaxRateStore $taxRateStore,
ProductCategoryStore $productCategoryStore
ProductCategoryStore $productCategoryStore,
OrderShopStore $orderShopStore
) {
$this->merchantResolver = $merchantResolver;
$this->sectionResolver = $sectionResolver;
@@ -47,6 +50,7 @@ class StoreTwigExtension extends AbstractExtension
$this->unitStore = $unitStore;
$this->taxRateStore = $taxRateStore;
$this->productCategoryStore = $productCategoryStore;
$this->orderShopStore = $orderShopStore;
}

public function getFunctions()
@@ -54,6 +58,7 @@ class StoreTwigExtension extends AbstractExtension
return array(
new TwigFunction('carac_sections', [$this, 'getSections']),
new TwigFunction('carac_section_current', [$this, 'getSectionCurrent']),
new TwigFunction('carac_cart_current', [$this, 'getCartCurrent']),
new TwigFunction('carac_merchants', [$this, 'getMerchants']),
new TwigFunction('carac_reminders', [$this, 'getReminders']),
new TwigFunction('carac_units', [$this, 'getUnits']),
@@ -82,6 +87,13 @@ class StoreTwigExtension extends AbstractExtension
return $this->sectionResolver->getCurrent();
}

public function getCartCurrent()
{
return $this->orderShopStore
->setSection($this->sectionResolver->getCurrent())
->getOneCartCurrent();
}

public function getMerchants()
{
return $this->merchantStore->getOnline();

Chargement…
Annuler
Enregistrer