Sfoglia il codice sorgente

Merge branch 'develop'

master
Fabien Normand 2 anni fa
parent
commit
0a04332412
54 ha cambiato i file con 1015 aggiunte e 493 eliminazioni
  1. +121
    -121
      Builder/Order/OrderShopBuilder.php
  2. +7
    -0
      Builder/PointSale/PointSaleSectionBuilder.php
  3. +50
    -0
      Container/PointSale/PointSaleSectionContainer.php
  4. +51
    -16
      Controller/AdminControllerTrait.php
  5. +7
    -0
      Controller/ControllerTrait.php
  6. +1
    -0
      Controller/Section/SectionAdminController.php
  7. +1
    -1
      Controller/Section/SwitchSectionAdminController.php
  8. +1
    -6
      Controller/Ticket/TicketAdminController.php
  9. +2
    -2
      Controller/User/GroupUserAdminController.php
  10. +5
    -0
      Definition/Field/PointSale/PointSaleFieldDefinition.php
  11. +8
    -2
      Definition/SectionSettingDefinition.php
  12. +21
    -17
      EventSubscriber/Product/OnlineOrOfflineProductCategoryAfterProductFamilyEventSubscriber.php
  13. +2
    -2
      EventSubscriber/User/InitUserMerchantEventSubscriber.php
  14. +24
    -0
      Factory/PointSale/PointSaleSectionFactory.php
  15. +2
    -0
      Factory/Product/ProductFamilyFactory.php
  16. +2
    -2
      Factory/Reduction/ReductionCatalogFactory.php
  17. +2
    -1
      Factory/User/UserPointSaleFactory.php
  18. +8
    -40
      Model/PointSale/PointSaleInterface.php
  19. +36
    -2
      Model/PointSale/PointSaleModel.php
  20. +15
    -0
      Model/PointSale/PointSaleSectionInterface.php
  21. +68
    -0
      Model/PointSale/PointSaleSectionModel.php
  22. +1
    -0
      Model/Product/ProductCategoryModel.php
  23. +4
    -1
      Model/Product/ProductFamilyModel.php
  24. +8
    -0
      Model/Section/SectionInterface.php
  25. +53
    -0
      Model/Section/SectionModel.php
  26. +2
    -1
      Model/User/UserPointSaleModel.php
  27. +8
    -6
      Notification/MailMailjetNotification.php
  28. +2
    -3
      Repository/Order/OrderProductStore.php
  29. +28
    -6
      Repository/Order/OrderShopRepositoryQuery.php
  30. +173
    -157
      Repository/Order/OrderShopStore.php
  31. +5
    -0
      Repository/PointSale/PointSaleRepositoryQuery.php
  32. +15
    -0
      Repository/PointSale/PointSaleSectionRepository.php
  33. +23
    -0
      Repository/PointSale/PointSaleSectionRepositoryQuery.php
  34. +43
    -0
      Repository/PointSale/PointSaleSectionStore.php
  35. +1
    -1
      Repository/PointSale/PointSaleStore.php
  36. +0
    -2
      Repository/Product/ProductCategoryRepositoryQuery.php
  37. +1
    -1
      Repository/Product/ProductCategoryStore.php
  38. +1
    -1
      Repository/Product/ProductFamilyRepositoryQuery.php
  39. +1
    -0
      Repository/Product/ProductFamilyStore.php
  40. +2
    -2
      Repository/Reduction/ReductionCreditRepositoryQuery.php
  41. +5
    -1
      Repository/Section/SectionRepositoryQuery.php
  42. +6
    -0
      Repository/Section/SectionStore.php
  43. +18
    -2
      Resolver/MerchantResolver.php
  44. +31
    -5
      Resolver/OpeningResolver.php
  45. +14
    -1
      Resources/translations/admin.fr.yaml
  46. +20
    -1
      Resources/views/admin/order/field/complementary.html.twig
  47. +5
    -1
      Resources/views/admin/order/field/distribution.html.twig
  48. +5
    -8
      Solver/Config/UnitSolver.php
  49. +76
    -67
      Solver/Order/OrderShopSolver.php
  50. +16
    -2
      Solver/PointSale/PointSaleSolver.php
  51. +4
    -6
      Solver/Product/ProductFamilySolver.php
  52. +8
    -4
      Statistic/Product/ProductsSalesStatistic.php
  53. +1
    -1
      Twig/FormTwigExtension.php
  54. +1
    -1
      Twig/StoreTwigExtension.php

+ 121
- 121
Builder/Order/OrderShopBuilder.php Vedi File

@@ -6,6 +6,7 @@ use App\Builder\Distribution\DistributionBuilder;
use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Builder\Credit\CreditHistoryBuilder;
use Lc\CaracoleBundle\Builder\File\DocumentBuilder;
use Lc\CaracoleBundle\Event\Order\CartChangeEvent;
use Lc\CaracoleBundle\Event\Order\OrderShopChangeStatusEvent;
use Lc\CaracoleBundle\Factory\Credit\CreditHistoryFactory;
use Lc\CaracoleBundle\Factory\File\DocumentFactory;
@@ -77,27 +78,26 @@ class OrderShopBuilder
protected FlashBagTranslator $flashBagTranslator;

public function __construct(
EntityManagerInterface $entityManager,
OrderShopStore $orderShopStore,
OrderShopSolver $orderShopSolver,
OrderStatusStore $orderStatusStore,
OrderProductStore $orderProductStore,
ProductFamilyStore $productFamilyStore,
OrderProductBuilder $orderProductBuilder,
DocumentBuilder $documentBuilder,
PriceSolver $priceSolver,
EventDispatcherInterface $eventDispatcher,
FlashBagInterface $flashBag,
OpeningResolver $openingResolver,
ProductSolver $productSolver,
OrderShopResolver $orderShopResolver,
OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver,
DistributionBuilder $distributionBuilder,
MerchantResolver $merchantResolver,
CreditHistoryBuilder $creditHistoryBuilder,
FlashBagTranslator $flashBagTranslator
)
{
EntityManagerInterface $entityManager,
OrderShopStore $orderShopStore,
OrderShopSolver $orderShopSolver,
OrderStatusStore $orderStatusStore,
OrderProductStore $orderProductStore,
ProductFamilyStore $productFamilyStore,
OrderProductBuilder $orderProductBuilder,
DocumentBuilder $documentBuilder,
PriceSolver $priceSolver,
EventDispatcherInterface $eventDispatcher,
FlashBagInterface $flashBag,
OpeningResolver $openingResolver,
ProductSolver $productSolver,
OrderShopResolver $orderShopResolver,
OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver,
DistributionBuilder $distributionBuilder,
MerchantResolver $merchantResolver,
CreditHistoryBuilder $creditHistoryBuilder,
FlashBagTranslator $flashBagTranslator
) {
$this->entityManager = $entityManager;
$this->orderShopStore = $orderShopStore;
$this->orderShopSolver = $orderShopSolver;
@@ -120,11 +120,10 @@ class OrderShopBuilder
}

public function create(
SectionInterface $section,
UserInterface $user = null,
VisitorInterface $visitor = null
): OrderShopInterface
{
SectionInterface $section,
UserInterface $user = null,
VisitorInterface $visitor = null
): OrderShopInterface {
$orderShopFactory = new OrderShopFactory();
$orderShop = $orderShopFactory->create($section, $user, $visitor);

@@ -140,21 +139,18 @@ class OrderShopBuilder
protected array $cacheCartCurrentBySection = [];

public function createIfNotExist(
SectionInterface $section,
UserInterface $user = null,
VisitorInterface $visitor = null,
bool $cache = false
): OrderShopInterface
{

SectionInterface $section,
UserInterface $user = null,
VisitorInterface $visitor = null,
bool $cache = false
): OrderShopInterface {
$cart = null;

// cache
$cacheIdCartCurrent = 'cart_current_' . $section->getId();
if ($cache
&& isset($this->cacheCartCurrentBySection[$cacheIdCartCurrent])
&& $this->cacheCartCurrentBySection[$cacheIdCartCurrent]) {

&& isset($this->cacheCartCurrentBySection[$cacheIdCartCurrent])
&& $this->cacheCartCurrentBySection[$cacheIdCartCurrent]) {
return $this->cacheCartCurrentBySection[$cacheIdCartCurrent];
}

@@ -169,7 +165,6 @@ class OrderShopBuilder
if ($cartUser) {
$cart = $cartUser;
} elseif ($cartVisitor) {

if ($user && $cartVisitor && !$cartVisitor->getUser()) {
$cartVisitor->setUser($user);
$this->entityManager->update($cartVisitor);
@@ -194,16 +189,15 @@ class OrderShopBuilder
}

public function setOrderStatus(
OrderShopInterface $orderShop,
string $alias,
bool $forceByAdmin = false
): OrderShopInterface
{
OrderShopInterface $orderShop,
string $alias,
bool $forceByAdmin = false
): OrderShopInterface {
$orderStatus = $this->orderStatusStore->getOneByAlias($alias);

if ($orderStatus) {
if ($orderShop->getOrderStatus() === null
|| $orderShop->getOrderStatus()->getNextStatusAllowed()->contains($orderStatus)) {
|| $orderShop->getOrderStatus()->getNextStatusAllowed()->contains($orderStatus)) {
$this->applyChangeOrderStatus($orderShop, $orderStatus, $forceByAdmin);
}
} else {
@@ -214,14 +208,13 @@ class OrderShopBuilder
}

public function applyChangeOrderStatus(
OrderShopInterface $orderShop,
OrderStatusInterface $orderStatus,
bool $forceByAdmin = false
): void
{
OrderShopInterface $orderShop,
OrderStatusInterface $orderStatus,
bool $forceByAdmin = false
): void {
$this->eventDispatcher->dispatch(
new OrderShopChangeStatusEvent($orderShop, $orderStatus, $forceByAdmin),
OrderShopChangeStatusEvent::PRE_CHANGE_STATUS
new OrderShopChangeStatusEvent($orderShop, $orderStatus, $forceByAdmin),
OrderShopChangeStatusEvent::PRE_CHANGE_STATUS
);

$orderShop->setOrderStatusProtected($orderStatus);
@@ -232,17 +225,16 @@ class OrderShopBuilder
$orderShop->addOrderStatusHistory($orderStatusHistory);

$this->eventDispatcher->dispatch(
new OrderShopChangeStatusEvent($orderShop, $orderStatus, $forceByAdmin),
OrderShopChangeStatusEvent::POST_CHANGE_STATUS
new OrderShopChangeStatusEvent($orderShop, $orderStatus, $forceByAdmin),
OrderShopChangeStatusEvent::POST_CHANGE_STATUS
);
}

public function addOrderProduct(
OrderShopInterface $orderShop,
OrderProductInterface $orderProductAdd,
bool $persist = true
): bool
{
OrderShopInterface $orderShop,
OrderProductInterface $orderProductAdd,
bool $persist = true
): bool {
$return = false;

if ($this->orderShopSolver->isOrderProductAvailableAddCart($orderProductAdd, $orderShop)) {
@@ -250,7 +242,7 @@ class OrderShopBuilder
$updated = false;
$this->orderProductBuilder->init($orderProductAdd);
$productFamily = $this->productFamilyStore->setSection($orderShop->getSection())->getOneBySlug(
$orderProductAdd->getProduct()->getProductFamily()->getSlug()
$orderProductAdd->getProduct()->getProductFamily()->getSlug()
);

if ($productFamily) {
@@ -259,10 +251,10 @@ class OrderShopBuilder
if ($reductionCatalog && $reductionCatalog->getStatus()) {
$orderProductReductionCatalogFactory = new OrderProductReductionCatalogFactory();
$orderProductReductionCatalog = $orderProductReductionCatalogFactory->create(
$reductionCatalog->getTitle(),
$reductionCatalog->getValue(),
$reductionCatalog->getUnit(),
$reductionCatalog->getBehaviorTaxRate()
$reductionCatalog->getTitle(),
$reductionCatalog->getValue(),
$reductionCatalog->getUnit(),
$reductionCatalog->getBehaviorTaxRate()
);

$orderProductAdd->setOrderProductReductionCatalog($orderProductReductionCatalog);
@@ -271,15 +263,15 @@ class OrderShopBuilder

foreach ($orderShop->getOrderProducts() as $orderProduct) {
if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()
&& $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery()
&& (string)$this->priceSolver->getPrice($orderProduct)
== (string)$this->priceSolver->getPrice($orderProductAdd)
&& $this->orderProductReductionCatalogSolver->compare(
$orderProduct->getOrderProductReductionCatalog(),
$orderProductAdd->getOrderProductReductionCatalog()
)) {
&& $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery()
&& (string)$this->priceSolver->getPrice($orderProduct)
== (string)$this->priceSolver->getPrice($orderProductAdd)
&& $this->orderProductReductionCatalogSolver->compare(
$orderProduct->getOrderProductReductionCatalog(),
$orderProductAdd->getOrderProductReductionCatalog()
)) {
$orderProduct->setQuantityOrder(
$orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
$orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
);

if ($persist) {
@@ -300,7 +292,7 @@ class OrderShopBuilder
if (isset($orderProductReductionCatalog)) {
$this->entityManager->create($orderProductReductionCatalog);
}
//TODO est-ce un update ou un create ???
// @TODO : update ou create ?
$this->entityManager->persist($orderProductAdd);
$this->entityManager->update($orderShop);
}
@@ -310,10 +302,8 @@ class OrderShopBuilder

if ($persist) {
$this->entityManager->flush();
$this->eventDispatcher->dispatch(new CartChangeEvent($orderShop), CartChangeEvent::POST_UPDATE);
}

// @TODO : dispatch event cart change
//$this->eventCartChange($orderShop);
}
} else {
// @TODO : retourner le message d'erreur et faire le addFlash dans le contrôleur
@@ -337,23 +327,27 @@ class OrderShopBuilder
}
}
$this->utils->addFlash('error', $textError);*/

$return = false;
}

return $return;
}

public function merge(
OrderShopInterface $orderShop1,
OrderShopInterface $orderShop2,
$persist = true
): OrderShopInterface
{
OrderShopInterface $orderShop1,
OrderShopInterface $orderShop2,
$persist = true
): OrderShopInterface {
//TODO essayer de comprendre prk on doit faire un refresh ici ???
$this->entityManager->refresh($orderShop1);
$this->entityManager->refresh($orderShop2);
if ($orderShop1 && $orderShop2) {
foreach ($orderShop2->getOrderProducts() as $orderProduct) {
$orderProductAlreadyInCart = $this->orderShopSolver->hasOrderProductAlreadyInCart($orderShop1, $orderProduct);
$orderProductAlreadyInCart = $this->orderShopSolver->hasOrderProductAlreadyInCart(
$orderShop1,
$orderProduct
);

if ($orderProductAlreadyInCart) {
if ($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) {
@@ -387,9 +381,13 @@ class OrderShopBuilder
$orderShop->addOrderPayment($orderPayment);

if ($meanPayment == OrderPaymentModel::MEAN_PAYMENT_CREDIT) {
$this->creditHistoryBuilder->create(CreditHistoryModel::TYPE_DEBIT, $this->merchantResolver->getUserMerchant(), [
'orderPayment' => $orderPayment
]);
$this->creditHistoryBuilder->create(
CreditHistoryModel::TYPE_DEBIT,
$this->merchantResolver->getUserMerchant(),
[
'orderPayment' => $orderPayment
]
);
}

if ($this->orderShopResolver->isPaid($orderShop)) {
@@ -415,17 +413,17 @@ class OrderShopBuilder
$orderShop->setStatTotal($this->priceSolver->getTotal($orderShop));
$orderShop->setStatTotalWithTax($this->priceSolver->getTotalWithTax($orderShop));
$orderShop->setStatTotalOrderProductsWithReductions(
$this->priceSolver->getTotalOrderProductsWithReductions($orderShop)
$this->priceSolver->getTotalOrderProductsWithReductions($orderShop)
);
$orderShop->setStatTotalOrderProductsWithTaxAndReductions(
$this->priceSolver->getTotalOrderProductsWithTaxAndReductions($orderShop)
$this->priceSolver->getTotalOrderProductsWithTaxAndReductions($orderShop)
);
$orderShop->setStatMarginOrderProductsWithReductions(
$this->priceSolver->getMarginOrderProductsWithReductions($orderShop)
$this->priceSolver->getMarginOrderProductsWithReductions($orderShop)
);
$orderShop->setStatDeliveryPriceWithReduction($this->priceSolver->getDeliveryPriceWithReduction($orderShop));
$orderShop->setStatDeliveryPriceWithTaxAndReduction(
$this->priceSolver->getDeliveryPriceWithTaxAndReduction($orderShop)
$this->priceSolver->getDeliveryPriceWithTaxAndReduction($orderShop)
);

$this->entityManager->persist($orderShop);
@@ -438,8 +436,8 @@ class OrderShopBuilder
public function initDistribution(OrderShopInterface $orderShop): void
{
$distribution = $this->distributionBuilder->guessDistributionByDeliveryDate(
$orderShop->getDeliveryDate(),
$orderShop->getSection()
$orderShop->getDeliveryDate(),
$orderShop->getSection()
);
$orderShop->setDistribution($distribution);
}
@@ -456,17 +454,16 @@ class OrderShopBuilder
}

public function addReductionCart(
OrderShopInterface $orderShop,
ReductionCartInterface $reductionCart
): ?OrderReductionCartInterface
{
OrderShopInterface $orderShop,
ReductionCartInterface $reductionCart
): ?OrderReductionCartInterface {
$orderReductionCartFactory = new OrderReductionCartFactory();
$orderReductionCart = $orderReductionCartFactory->create($orderShop, $reductionCart);

$orderShop->addOrderReductionCart($orderReductionCart);

if ($this->orderShopResolver->isPositiveAmount($orderShop)
&& $this->orderShopResolver->isPositiveAmountRemainingToBePaid($orderShop)) {
&& $this->orderShopResolver->isPositiveAmountRemainingToBePaid($orderShop)) {
$this->entityManager->create($orderReductionCart);
$this->entityManager->flush();

@@ -480,18 +477,16 @@ class OrderShopBuilder

// createOrderReductionCredit
public function addReductionCredit(
OrderShopInterface $orderShop,
ReductionCreditInterface $reductionCredit
): ?OrderReductionCreditInterface
{
OrderShopInterface $orderShop,
ReductionCreditInterface $reductionCredit
): ?OrderReductionCreditInterface {
$orderReductionCreditFactory = new OrderReductionCreditFactory();
$orderReductionCredit = $orderReductionCreditFactory->create($orderShop, $reductionCredit);

$orderShop->addOrderReductionCredit($orderReductionCredit);

if ($this->orderShopResolver->isPositiveAmount($orderShop)
&& $this->orderShopResolver->isPositiveAmountRemainingToBePaid($orderShop)) {

&& $this->orderShopResolver->isPositiveAmountRemainingToBePaid($orderShop)) {
$this->entityManager->create($orderReductionCredit);
$this->entityManager->flush();

@@ -511,16 +506,16 @@ class OrderShopBuilder
}

public function applyDeductAvailabilityProduct(
OrderShopInterface $orderShop,
OrderProductInterface $orderProduct
): void
{
OrderShopInterface $orderShop,
OrderProductInterface $orderProduct
): void {
switch ($orderProduct->getProduct()->getProductFamily()->getBehaviorCountStock()) {
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :

//Disponibilité par unité de référence
$oldAvailability = $this->productSolver->getAvailableQuantityInherited($orderProduct->getProduct());
$newAvailability = $oldAvailability - ($orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $orderProduct->getUnit()->getCoefficient()));
$newAvailability = $oldAvailability - ($orderProduct->getQuantityOrder(
) * ($orderProduct->getQuantityProduct() / $orderProduct->getUnit()->getCoefficient()));

$productFamily = $orderProduct->getProduct()->getProductFamily();
$productFamily->setAvailableQuantity($newAvailability);
@@ -559,17 +554,22 @@ class OrderShopBuilder

public function updatePriceByProductFamily(ProductFamilyInterface $productFamily)
{
$debug = '';

foreach ($this->merchantResolver->getCurrent()->getSections() as $section) {
// @TODO : faire la vérification isOpenSale depuis la méthode appelante
if (!$this->openingResolver->isOpenSale($section)) {
$countOrderProductUpdated = 0;

foreach ($productFamily->getProducts() as $product) {
$orderProducts = $this->orderProductStore->resetContext()->setSection($section)->getInCartsByProduct($product);
$orderProducts = $this->orderProductStore->resetContext()->setSection(
$section
)->getInCartsByProduct($product);

foreach ($orderProducts as $orderProduct) {
$quantityOrder = $orderProduct->getQuantityOrder();
$orderShop = $orderProduct->getOrderShop();

$orderShop->removeOrderProduct($orderProduct);
$this->entityManager->delete($orderProduct);
$this->entityManager->flush();
@@ -583,12 +583,12 @@ class OrderShopBuilder
}
}
if ($countOrderProductUpdated) {
// @TODO : faire le add flash dans le controller
$this->flashBagTranslator->add(
'success',
'orderProductUpdated',
'OrderShop',
array('%count%' => $countOrderProductUpdated)
'success',
'orderProductUpdated',
'OrderShop',
//array('%count%' => $countOrderProductUpdated)
['%count' => $debug]
);

$this->entityManager->flush();
@@ -604,17 +604,17 @@ class OrderShopBuilder
$orderShop->setStatTotal($this->priceSolver->getTotal($orderShop));
$orderShop->setStatTotalWithTax($this->priceSolver->getTotalWithTax($orderShop));
$orderShop->setStatTotalOrderProductsWithReductions(
$this->priceSolver->getTotalOrderProductsWithReductions($orderShop)
$this->priceSolver->getTotalOrderProductsWithReductions($orderShop)
);
$orderShop->setStatTotalOrderProductsWithTaxAndReductions(
$this->priceSolver->getTotalOrderProductsWithTaxAndReductions($orderShop)
$this->priceSolver->getTotalOrderProductsWithTaxAndReductions($orderShop)
);
$orderShop->setStatMarginOrderProductsWithReductions(
$this->priceSolver->getMarginOrderProductsWithReductions($orderShop)
$this->priceSolver->getMarginOrderProductsWithReductions($orderShop)
);
$orderShop->setStatDeliveryPriceWithReduction($this->priceSolver->getDeliveryPriceWithReduction($orderShop));
$orderShop->setStatDeliveryPriceWithTaxAndReduction(
$this->priceSolver->getDeliveryPriceWithTaxAndReduction($orderShop)
$this->priceSolver->getDeliveryPriceWithTaxAndReduction($orderShop)
);

$this->entityManager->update($orderShop);
@@ -665,14 +665,14 @@ class OrderShopBuilder
public function getProductsSalesStatistic(SectionInterface $section, $entity, $nbWeek = 2)
{
$productsSalesStatistic = new ProductsSalesStatistic(
$this->entityManager,
$entity,
$nbWeek,
$this->productSolver
$this->entityManager,
$entity,
$nbWeek,
$this->productSolver
);

$productsSalesStatistic->init($section, $this->distributionBuilder, $this->openingResolver);
$productsSalesStatistic->populateProperties($this->orderShopStore);
$productsSalesStatistic->init($section, $this->distributionBuilder);
$productsSalesStatistic->populateProperties($this->orderShopStore->resetContext()->setSection($section));

return $productsSalesStatistic->getAsArray();
}

+ 7
- 0
Builder/PointSale/PointSaleSectionBuilder.php Vedi File

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

namespace Lc\CaracoleBundle\Builder\PointSale;

class PointSaleSectionBuilder
{
}

+ 50
- 0
Container/PointSale/PointSaleSectionContainer.php Vedi File

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

namespace Lc\CaracoleBundle\Container\PointSale;

use Lc\CaracoleBundle\Builder\PointSale\PointSaleSectionBuilder;
use Lc\CaracoleBundle\Factory\PointSale\PointSaleSectionFactory;
use Lc\CaracoleBundle\Repository\PointSale\PointSaleSectionRepositoryQuery;
use Lc\CaracoleBundle\Repository\PointSale\PointSaleSectionStore;

class PointSaleSectionContainer
{
protected PointSaleSectionFactory $factory;
protected PointSaleSectionRepositoryQuery $repositoryQuery;
protected PointSaleSectionStore $store;
protected PointSaleSectionBuilder $builder;

public function __construct(
PointSaleSectionFactory $factory,
PointSaleSectionRepositoryQuery $repositoryQuery,
PointSaleSectionStore $store,
PointSaleSectionBuilder $builder
) {
$this->factory = $factory;
$this->repositoryQuery = $repositoryQuery;
$this->store = $store;
$this->builder = $builder;
}

public function getFactory(): PointSaleSectionFactory
{
return $this->factory;
}

public function getRepositoryQuery(): PointSaleSectionRepositoryQuery
{
return $this->repositoryQuery;
}

public function getStore(): PointSaleSectionStore
{
$this->store->resetContext();

return $this->store;
}

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

+ 51
- 16
Controller/AdminControllerTrait.php Vedi File

@@ -2,6 +2,7 @@

namespace Lc\CaracoleBundle\Controller;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
@@ -20,6 +21,7 @@ use Lc\CaracoleBundle\Doctrine\Extension\FilterMultipleMerchantsInterface;
use Lc\CaracoleBundle\Doctrine\Extension\FilterSectionInterface;
use Lc\CaracoleBundle\Form\Merchant\DuplicateToOtherMerchantFormType;
use Lc\CaracoleBundle\Form\Section\DuplicateToOtherSectionFormType;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Resolver\MerchantResolver;
use Lc\CaracoleBundle\Resolver\SectionResolver;
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
@@ -93,7 +95,7 @@ trait AdminControllerTrait
AdminContext $context,
EntityComponent $entityComponent,
TranslatorAdmin $translatorAdmin,
EntityManagerInterface $em
EntityManagerInterface $entityManager
) {
if (!$this->isGranted(
Permission::EA_EXECUTE_ACTION,
@@ -106,35 +108,68 @@ trait AdminControllerTrait
throw new InsufficientEntityPermissionException($context);
}

if (!$this->isInstanceOf(FilterMerchantInterface::class)) {
if (!$this->isInstanceOf(FilterMerchantInterface::class)
&& !$this->isInstanceOf(ProductFamilyInterface::class)) {
throw new \ErrorException('L\entité n\'est pas lié à un merchant.');
}

$duplicateOtherMerchantForm = $this->createForm(
DuplicateToOtherMerchantFormType::class,
null,
array(
[
'entityClass' => $context->getEntity()->getFqcn(),
'entityId' => $context->getEntity()->getInstance()->getId(),
'action' => $context->getRequest()->getUri(),
'attr' => ['id' => 'duplicate-other-merchant-form'],

)
]
);

$duplicateOtherMerchantForm->handleRequest($context->getRequest());

if ($duplicateOtherMerchantForm->isSubmitted() && $duplicateOtherMerchantForm->isValid()) {
$newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance());
$em->create($newEntity);
$entityManager->create($newEntity);
$merchant = $duplicateOtherMerchantForm->get('merchants')->getData();
$newEntity->setMerchant($merchant);
$em->update($newEntity);
$em->flush();

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();
}
else {
$newEntity->setMerchant($merchant);
}

$entityManager->update($newEntity);
$entityManager->flush();

$url = $this->get(AdminUrlGenerator::class)
->setAction(ActionDefinition::EDIT)
->setEntityId($newEntity->getId())
->setAction(ActionDefinition::INDEX)
->generateUrl();

$this->addFlashTranslator(
'success',
'duplicateToOtherMerchant',
@@ -142,21 +177,20 @@ trait AdminControllerTrait
['%merchant%' => $merchant->getTitle()]
);

//TODO switch merchant route
return $this->redirect($url);
}


if ($context->getRequest()->isXmlHttpRequest()) {
$response['data'] = $this->renderView(
'@LcCaracole/admin/merchant/modal/duplicate_entity_to_other_merchant.html.twig',
array(
[
'form_duplicate_entity_to_other_merchant' => $duplicateOtherMerchantForm->createView(),
)
]
);

return new Response(json_encode($response));
} else {
}
else {
throw new \ErrorException('La requête doit être effectué en ajax');
}
}
@@ -235,6 +269,7 @@ trait AdminControllerTrait
public function buildIndexActions(Actions $actions): void
{
parent::buildIndexActions($actions);

if ($this->isInstanceOf(FilterMerchantInterface::class)) {
$actions->add(Crud::PAGE_INDEX, $this->getDuplicateToOhterMerchantAction());
}

+ 7
- 0
Controller/ControllerTrait.php Vedi File

@@ -20,6 +20,7 @@ use Lc\CaracoleBundle\Container\Order\OrderShopContainer;
use Lc\CaracoleBundle\Container\Order\OrderStatusContainer;
use Lc\CaracoleBundle\Container\Order\OrderStatusHistoryContainer;
use Lc\CaracoleBundle\Container\PointSale\PointSaleContainer;
use Lc\CaracoleBundle\Container\PointSale\PointSaleSectionContainer;
use Lc\CaracoleBundle\Container\Product\ProductCategoryContainer;
use Lc\CaracoleBundle\Container\Product\ProductContainer;
use Lc\CaracoleBundle\Container\Product\ProductFamilyContainer;
@@ -92,6 +93,7 @@ trait ControllerTrait
DistributionContainer::class => DistributionContainer::class,
ProductFamilySectionPropertyContainer::class => ProductFamilySectionPropertyContainer::class,
QualityLabelContainer::class => QualityLabelContainer::class,
PointSaleSectionContainer::class => PointSaleSectionContainer::class,
]
);
}
@@ -353,4 +355,9 @@ trait ControllerTrait
{
return $this->get(QualityLabelContainer::class);
}

public function getPointSaleSectionContainer(): PointSaleSectionContainer
{
return $this->get(PointSaleSectionContainer::class);
}
}

+ 1
- 0
Controller/Section/SectionAdminController.php Vedi File

@@ -55,6 +55,7 @@ abstract class SectionAdminController extends AbstractAdminController
->hideOnIndex(),
BooleanField::new('isDefault'),
StatusField::new('status'),
BooleanField::new('isOnlineFrontend'),
],
$this->getSeoPanel(),
$this->getConfPanel(),

+ 1
- 1
Controller/Section/SwitchSectionAdminController.php Vedi File

@@ -14,7 +14,7 @@ use Symfony\Component\Routing\Annotation\Route;
class SwitchSectionAdminController extends AbstractController
{
/**
* @Route("/admin/section/switch", name="carac_section_switch")
* @Route("/admin/section/switch", name="admin_section_switch")
*/
public function switchSection(
Request $request,

+ 1
- 6
Controller/Ticket/TicketAdminController.php Vedi File

@@ -32,12 +32,7 @@ abstract class TicketAdminController extends SovTicketAdminController
public function configureActions(Actions $actions): Actions
{
$actions = parent::configureActions($actions);

if(!$this->getSectionCurrent()) {
$actions->disable(ActionDefinition::NEW, ActionDefinition::EDIT, ActionDefinition::DUPLICATE,ActionDefinition::DUPLICATE_TO_OTHER_SECTION, ActionDefinition::DELETE);
}else{
$actions->disable( ActionDefinition::EDIT, ActionDefinition::DUPLICATE,ActionDefinition::DUPLICATE_TO_OTHER_SECTION, ActionDefinition::DELETE);
}
$actions->disable( ActionDefinition::EDIT, ActionDefinition::DUPLICATE,ActionDefinition::DUPLICATE_TO_OTHER_SECTION, ActionDefinition::DELETE);

return $actions;
}

+ 2
- 2
Controller/User/GroupUserAdminController.php Vedi File

@@ -2,12 +2,12 @@

namespace Lc\CaracoleBundle\Controller\User;

use Lc\CaracoleBundle\Controller\ControllerTrait;
use Lc\CaracoleBundle\Controller\AdminControllerTrait;
use Lc\SovBundle\Controller\User\GroupUserAdminController as SovGroupUserAdminController;

abstract class GroupUserAdminController extends SovGroupUserAdminController
{
use ControllerTrait;
use AdminControllerTrait;

public function createEntity(string $entityFqcn)
{

+ 5
- 0
Definition/Field/PointSale/PointSaleFieldDefinition.php Vedi File

@@ -2,6 +2,7 @@

namespace Lc\CaracoleBundle\Definition\Field\PointSale;

use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Lc\CaracoleBundle\Field\Address\AddressField;
@@ -9,6 +10,7 @@ use Lc\SovBundle\Definition\Field\AbstractFieldDefinition;
use Lc\SovBundle\Field\CKEditorField;
use Lc\SovBundle\Field\ImageManagerField;
use Lc\SovBundle\Field\StatusField;
use Lc\SovBundle\Form\Common\FileUploadType;

class PointSaleFieldDefinition extends AbstractFieldDefinition
{
@@ -54,6 +56,9 @@ class PointSaleFieldDefinition extends AbstractFieldDefinition
'id' => IntegerField::new('id')->setSortable(true)->onlyOnIndex(),
'title' => TextField::new('title')->setSortable(true),
'code' => TextField::new('code'),
/*'image' => ImageField::new('image')
->setUploadDir('public/uploads/images/pointsale')
->setFormType(FileUploadType::class),*/
'image' => ImageManagerField::new('image'),
'description' => CKEditorField::new('description'),
'status' => StatusField::new('status')->setSortable(true),

+ 8
- 2
Definition/SectionSettingDefinition.php Vedi File

@@ -13,8 +13,7 @@ class SectionSettingDefinition extends AbstractSettingDefinition
const SETTING_ORDER_CLOSED_START = 'orderClosedStart';
const SETTING_ORDER_CLOSED_END = 'orderClosedEnd';
const SETTING_ORDER_MAXIMUM_PER_CYCLE = 'orderMaximumPerCycle';
/*const SETTING_COLOR_PRIMARY = 'colorPrimary';
const SETTING_COLOR_SECONDARY = 'colorSecondary';*/
const SETTING_OPENING_TEXT_CLOSED = 'openingTextClosed';

const VALUE_ORDER_STATE_DEFAULT = 'default';
const VALUE_ORDER_STATE_OPEN = 'open';
@@ -56,6 +55,13 @@ class SectionSettingDefinition extends AbstractSettingDefinition
]
);

$this->addSettingText(
[
'category' => self::CATEGORY_GENERAL,
'name' => self::SETTING_OPENING_TEXT_CLOSED
]
);

$this->addSettingText(
[
'name' => self::SETTING_ORDER_MAXIMUM_PER_CYCLE,

+ 21
- 17
EventSubscriber/Product/OnlineOrOfflineProductCategoryAfterProductFamilyEventSubscriber.php Vedi File

@@ -16,8 +16,10 @@ class OnlineOrOfflineProductCategoryAfterProductFamilyEventSubscriber implements
protected EntityManagerInterface $entityManager;
protected ProductCategoryContainer $productCategoryContainer;

public function __construct(EntityManagerInterface $entityManager, ProductCategoryContainer $productCategoryContainer)
{
public function __construct(
EntityManagerInterface $entityManager,
ProductCategoryContainer $productCategoryContainer
) {
$this->entityManager = $entityManager;
$this->productCategoryContainer = $productCategoryContainer;
}
@@ -25,8 +27,8 @@ class OnlineOrOfflineProductCategoryAfterProductFamilyEventSubscriber implements
public static function getSubscribedEvents()
{
return [
EntityManagerEvent::PRE_CREATE_EVENT => ['processBeforePersistProductFamilySectionInterface'],
EntityManagerEvent::PRE_UPDATE_EVENT => ['processBeforePersistProductFamilySectionInterface'],
EntityManagerEvent::PRE_CREATE_EVENT => ['processBeforePersistProductFamilySectionInterface'],
EntityManagerEvent::PRE_UPDATE_EVENT => ['processBeforePersistProductFamilySectionInterface'],
];
}

@@ -34,13 +36,12 @@ class OnlineOrOfflineProductCategoryAfterProductFamilyEventSubscriber implements
{
if ($event->getEntity() instanceof ProductFamilySectionPropertyInterface) {
$this->setProductCategoryByProductFamilySectionProperty($event->getEntity());
} else if ($event->getEntity() instanceof ProductFamilyInterface) {

foreach ($event->getEntity()->getProductFamilySectionProperties() as $productFamilySectionProperty) {
$this->setProductCategoryByProductFamilySectionProperty($productFamilySectionProperty);
} else {
if ($event->getEntity() instanceof ProductFamilyInterface) {
foreach ($event->getEntity()->getProductFamilySectionProperties() as $productFamilySectionProperty) {
$this->setProductCategoryByProductFamilySectionProperty($productFamilySectionProperty);
}
}


}
}

@@ -56,15 +57,18 @@ class OnlineOrOfflineProductCategoryAfterProductFamilyEventSubscriber implements
$this->productCategoryContainer->getBuilder()->setOnlineIfOnlineProductfamily($productCategory);
}
}
} else if ($productFamilySectionProperty->getStatus() == 0 || $productFamily->getStatus() == 0) {
$section = $productFamilySectionProperty->getSection();
$productCategoryArray = $productFamilySectionProperty->getProductFamily()->getProductCategories();
foreach ($productCategoryArray as $productCategory) {
if ($productCategory->getSection() === $section) {
$this->productCategoryContainer->getBuilder()->setOfflineIfOfflineProductfamily($productCategory);
} else {
if ($productFamilySectionProperty->getStatus() == 0 || $productFamily->getStatus() == 0) {
$section = $productFamilySectionProperty->getSection();
$productCategoryArray = $productFamily->getProductCategories();
foreach ($productCategoryArray as $productCategory) {
if ($productCategory->getSection() === $section) {
$this->productCategoryContainer->getBuilder()->setOfflineIfOfflineProductfamily(
$productCategory
);
}
}
}

}
}
}

+ 2
- 2
EventSubscriber/User/InitUserMerchantEventSubscriber.php Vedi File

@@ -36,7 +36,7 @@ class InitUserMerchantEventSubscriber implements EventSubscriberInterface

public function createUserMerchant(EntityManagerEvent $event)
{
$user = $event->getEntity();
/* $user = $event->getEntity();
$entityRepository = $this->em->getRepository(get_class($user));
if ($user instanceof UserInterface) {
$existingUser = $entityRepository->findOneByEmail($user->getEmail());
@@ -52,7 +52,7 @@ class InitUserMerchantEventSubscriber implements EventSubscriberInterface
);
$this->em->create($userMerchant);
}
}
}*/
}



+ 24
- 0
Factory/PointSale/PointSaleSectionFactory.php Vedi File

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

namespace Lc\CaracoleBundle\Factory\PointSale;

use App\Entity\PointSale\PointSaleSection;
use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface;
use Lc\CaracoleBundle\Model\PointSale\PointSaleSectionInterface;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\SovBundle\Factory\AbstractFactory;

class PointSaleSectionFactory extends AbstractFactory
{

public function create(PointSaleInterface $pointSale, SectionInterface $section): PointSaleSectionInterface
{
$pointSaleSection = new PointSaleSection();

$pointSaleSection->setPointSale($pointSale);
$pointSaleSection->setSection($section);

return $pointSaleSection;
}

}

+ 2
- 0
Factory/Product/ProductFamilyFactory.php Vedi File

@@ -6,6 +6,7 @@ use App\Entity\Product\ProductFamily;
use Lc\CaracoleBundle\Context\SectionContextTrait;
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\SovBundle\Factory\AbstractFactory;

@@ -15,6 +16,7 @@ class ProductFamilyFactory extends AbstractFactory
{
$productFamily = new ProductFamily();

$productFamily->setBehaviorAddToCart(ProductFamilyModel::BEHAVIOR_ADD_TO_CART_SIMPLE);
$productFamily->setSaleStatus(true);
$productFamily->setStatus(1);


+ 2
- 2
Factory/Reduction/ReductionCatalogFactory.php Vedi File

@@ -10,12 +10,12 @@ use Lc\SovBundle\Factory\AbstractFactory;
class ReductionCatalogFactory extends AbstractFactory
{

public function create(MerchantInterface $merchant): ReductionCatalogInterface
public function create(MerchantInterface $merchant, int $status = 1): ReductionCatalogInterface
{
$reductionCatalog = new ReductionCatalog();

$reductionCatalog->setMerchant($merchant);
$reductionCatalog->setStatus(1);
$reductionCatalog->setStatus($status);

return $reductionCatalog;
}

+ 2
- 1
Factory/User/UserPointSaleFactory.php Vedi File

@@ -2,6 +2,7 @@

namespace Lc\CaracoleBundle\Factory\User;

use App\Entity\User\UserPointSale;
use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface;
use Lc\CaracoleBundle\Model\User\UserPointSaleInterface;
use Lc\SovBundle\Factory\AbstractFactory;
@@ -11,7 +12,7 @@ class UserPointSaleFactory extends AbstractFactory
{
public function create(UserInterface $user, PointSaleInterface $pointSale): UserPointSaleInterface
{
$userPointSale = parent::create();
$userPointSale = new UserPointSale();

$userPointSale->setUser($user);
$userPointSale->setPointSale($pointSale);

+ 8
- 40
Model/PointSale/PointSaleInterface.php Vedi File

@@ -13,83 +13,50 @@ use Lc\SovBundle\Model\User\UserInterface;
interface PointSaleInterface
{
public function getTitle(): ?string;

public function setTitle(string $title);

public function getDescription(): ?string;

public function setDescription(?string $description);

public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

public function getOrderAmountMin(): ?float;

public function setOrderAmountMin(float $orderAmountMin): PointSaleInterface;

/**
* @return Collection|MerchantInterface[]
*/
public function getMerchants(): Collection;

public function addMerchant(MerchantInterface $merchant): PointSaleInterface;

public function removeMerchant(MerchantInterface $merchant): PointSaleInterface;

public function getCode(): ?string;

public function setCode(?string $code): PointSaleInterface;

public function getDeliveryPrice(): ?float;

public function setDeliveryPrice(float $deliveryPrice): PointSaleInterface;

public function getIsPublic(): ?bool;

public function setIsPublic(bool $isPublic): PointSaleInterface;

public function getAddress(): ?AddressInterface;

public function setAddress(AddressInterface $address): PointSaleInterface;

/**
* @return Collection|UserPointSaleInterface[]
*/
public function getUserPointSales(): Collection;

public function addUserPointSale(UserPointSaleInterface $userPointSale
): PointSaleInterface;

public function removeUserPointSale(UserPointSaleInterface $userPointSale
): PointSaleInterface;

public function getImage(): ?File;

public function setImage(?File $image): PointSaleInterface;

public function getMetaTitle(): ?string;

public function setMetaTitle(?string $metaTitle);

public function getMetaDescription(): ?string;

public function setMetaDescription(?string $metaDescription);

public function setOldUrls($oldUrls);

public function getOldUrls(): ?array;

public function getSlug(): ?string;

public function setSlug(?string $slug);

/**
@@ -102,18 +69,19 @@ interface PointSaleInterface
* @return $this
*/
public function setPosition(float $position);

public function clearPosition();

public function getStatus(): ?float;

public function setStatus(float $status);

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;

public function setUpdatedAt(\DateTimeInterface $updatedAt);

/**
* @return Collection|PointSaleSectionInterface[]
*/
public function getPointSaleSections(): Collection;
public function addPointSaleSection(PointSaleSectionInterface $pointSaleSection): PointSaleInterface;
public function removePointSaleSection(PointSaleSectionInterface $pointSaleSection): PointSaleInterface;

}

+ 36
- 2
Model/PointSale/PointSaleModel.php Vedi File

@@ -20,7 +20,6 @@ use App\Entity\File\File;
abstract class PointSaleModel extends AbstractFullEntity implements FilterMultipleMerchantsInterface,
OrderAmountMinInterface, PointSaleInterface
{

use OrderAmountMinTrait;

/**
@@ -59,10 +58,16 @@ abstract class PointSaleModel extends AbstractFullEntity implements FilterMultip
*/
protected $image;

/**
* @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\PointSale\PointSaleSectionInterface", mappedBy="pointSale", cascade={"persist"})
*/
protected $pointSaleSections;

public function __construct()
{
$this->merchants = new ArrayCollection();
$this->userPointSales = new ArrayCollection();
$this->pointSaleSections = new ArrayCollection();
}

public function __toString()
@@ -108,7 +113,6 @@ abstract class PointSaleModel extends AbstractFullEntity implements FilterMultip
return $this;
}


public function getDeliveryPrice(): ?float
{
return $this->deliveryPrice;
@@ -187,4 +191,34 @@ abstract class PointSaleModel extends AbstractFullEntity implements FilterMultip

return $this;
}

/**
* @return Collection|PointSaleSectionInterface[]
*/
public function getPointSaleSections(): Collection
{
return $this->pointSaleSections;
}

public function addPointSaleSection(PointSaleSectionInterface $pointSaleSection): self
{
if (!$this->pointSaleSections->contains($pointSaleSection)) {
$this->pointSaleSections[] = $pointSaleSection;
$pointSaleSection->setPointSale($this);
}

return $this;
}

public function removePointSaleSection(PointSaleSectionInterface $pointSaleSection): self
{
if ($this->pointSaleSections->removeElement($pointSaleSection)) {
// set the owning side to null (unless already changed)
if ($pointSaleSection->getPointSale() === $this) {
$pointSaleSection->setPointSale(null);
}
}

return $this;
}
}

+ 15
- 0
Model/PointSale/PointSaleSectionInterface.php Vedi File

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

namespace Lc\CaracoleBundle\Model\PointSale;

use Lc\CaracoleBundle\Model\Section\SectionInterface;

interface PointSaleSectionInterface
{
public function getSection(): SectionInterface;
public function setSection(SectionInterface $section): PointSaleSectionInterface;
public function getPointSale(): PointSaleInterface;
public function setPointSale(PointSaleInterface $pointSale): PointSaleSectionInterface;
public function getOrderAmountMin(): ?float;
public function setOrderAmountMin(float $orderAmountMin): self;
}

+ 68
- 0
Model/PointSale/PointSaleSectionModel.php Vedi File

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

namespace Lc\CaracoleBundle\Model\PointSale;

use Doctrine\ORM\Mapping as ORM;
use Lc\CaracoleBundle\Doctrine\Extension\OrderAmountMinTrait;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\SovBundle\Doctrine\EntityInterface;

/**
* @ORM\MappedSuperclass()
*/
abstract class PointSaleSectionModel implements EntityInterface, PointSaleSectionInterface
{
/**
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Section\SectionInterface", inversedBy="pointSaleSections")
* @ORM\JoinColumn(nullable=false)
*/
protected $section;

/**
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\PointSale\PointSaleInterface", inversedBy="pointSaleSections")
* @ORM\JoinColumn(nullable=false)
*/
protected $pointSale;


/**
* @ORM\Column(type="float", nullable=true)
*/
protected $orderAmountMin;

public function getSection(): SectionInterface
{
return $this->section;
}

public function setSection(SectionInterface $section): self
{
$this->section = $section;

return $this;
}

public function getPointSale(): PointSaleInterface
{
return $this->pointSale;
}

public function setPointSale(PointSaleInterface $pointSale): self
{
$this->pointSale = $pointSale;

return $this;
}

public function getOrderAmountMin(): ?float
{
return $this->orderAmountMin;
}

public function setOrderAmountMin(?float $orderAmountMin): self
{
$this->orderAmountMin = $orderAmountMin;

return $this;
}
}

+ 1
- 0
Model/Product/ProductCategoryModel.php Vedi File

@@ -61,6 +61,7 @@ abstract class ProductCategoryModel extends AbstractFullEntity implements TreeIn
$parent = $this->getParent();
$title = $parent ? $parent->getTitle() . ' - ' : '';
$title .= $this->getTitle();

return $title;
}


+ 4
- 1
Model/Product/ProductFamilyModel.php Vedi File

@@ -46,6 +46,7 @@ abstract class ProductFamilyModel extends AbstractFullEntity implements ProductP
const QUALITY_LABEL_AOC = 'aoc';
const QUALITY_LABEL_AOP = 'aop';
const QUALITY_LABEL_IGP = 'igp';
const QUALITY_LABEL_RECUP = 'recup';

static $organicLabels = [
self::QUALITY_LABEL_AB,
@@ -57,6 +58,8 @@ abstract class ProductFamilyModel extends AbstractFullEntity implements ProductP
self::QUALITY_LABEL_AOC,
self::QUALITY_LABEL_AOP,
self::QUALITY_LABEL_IGP,
// @TODO : à gérer autrement
self::QUALITY_LABEL_RECUP,
];

const TYPE_EXPIRATION_DATE_DLC = 'dlc';
@@ -101,7 +104,7 @@ abstract class ProductFamilyModel extends AbstractFullEntity implements ProductP
protected $products;

/**
* @ORM\Column(type="string", length=255, nullable=true)
* @ORM\Column(type="text", nullable=true)
*/
protected $subtitle;


+ 8
- 0
Model/Section/SectionInterface.php Vedi File

@@ -6,6 +6,7 @@ namespace Lc\CaracoleBundle\Model\Section;
use Doctrine\Common\Collections\Collection;
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface;
use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Model\PointSale\PointSaleSectionInterface;
use Lc\CaracoleBundle\Model\Product\ProductCategoryInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilySectionPropertyInterface;
use Lc\CaracoleBundle\Model\Setting\SectionSettingInterface;
@@ -163,4 +164,11 @@ interface SectionInterface
public function getUpdatedAt(): ?\DateTimeInterface;

public function setUpdatedAt(\DateTimeInterface $updatedAt);

/**
* @return Collection|PointSaleSectionInterface[]
*/
public function getPointSaleSections(): Collection;
public function addPointSaleSection(PointSaleSectionInterface $pointSaleSection): SectionInterface;
public function removePointSaleSection(PointSaleSectionInterface $pointSaleSection): SectionInterface;
}

+ 53
- 0
Model/Section/SectionModel.php Vedi File

@@ -9,6 +9,7 @@ use Gedmo\Mapping\Annotation as Gedmo;
use Lc\CaracoleBundle\Doctrine\Extension\FilterMerchantInterface;
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface;
use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Model\PointSale\PointSaleSectionInterface;
use Lc\CaracoleBundle\Model\Product\ProductCategoryInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilySectionPropertyInterface;
use Lc\CaracoleBundle\Model\Setting\SectionSettingInterface;
@@ -96,6 +97,16 @@ abstract class SectionModel extends AbstractFullEntity implements FilterMerchant
*/
protected $productFamilySectionProperties;

/**
* @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\PointSale\PointSaleSectionInterface", mappedBy="section")
*/
protected $pointSaleSections;

/**
* @ORM\Column(type="boolean", nullable=true)
*/
protected $isOnlineFrontend;

public function __construct()
{
$this->orderShops = new ArrayCollection();
@@ -405,4 +416,46 @@ abstract class SectionModel extends AbstractFullEntity implements FilterMerchant

return $this;
}

/**
* @return Collection|PointSaleSectionInterface[]
*/
public function getPointSaleSections(): Collection
{
return $this->pointSaleSections;
}

public function addPointSaleSection(PointSaleSectionInterface $pointSaleSection): self
{
if (!$this->pointSaleSections->contains($pointSaleSection)) {
$this->pointSaleSections[] = $pointSaleSection;
$pointSaleSection->setSection($this);
}

return $this;
}

public function removePointSaleSection(PointSaleSectionInterface $pointSaleSection): self
{
if ($this->pointSaleSections->removeElement($pointSaleSection)) {
// set the owning side to null (unless already changed)
if ($pointSaleSection->getSection() === $this) {
$pointSaleSection->setSection(null);
}
}

return $this;
}

public function getIsOnlineFrontend(): ?bool
{
return $this->isOnlineFrontend;
}

public function setIsOnlineFrontend(?bool $isOnlineFrontend): self
{
$this->isOnlineFrontend = $isOnlineFrontend;

return $this;
}
}

+ 2
- 1
Model/User/UserPointSaleModel.php Vedi File

@@ -4,12 +4,13 @@ namespace Lc\CaracoleBundle\Model\User;

use Doctrine\ORM\Mapping as ORM;
use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface;
use Lc\SovBundle\Doctrine\EntityInterface;
use Lc\SovBundle\Model\User\UserInterface;

/**
* @ORM\MappedSuperclass
*/
abstract class UserPointSaleModel implements UserPointSaleInterface
abstract class UserPointSaleModel implements UserPointSaleInterface, EntityInterface
{
/**
* @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface", inversedBy="userPointSales")

+ 8
- 6
Notification/MailMailjetNotification.php Vedi File

@@ -15,6 +15,8 @@ class MailMailjetNotification extends SovMailMailjetNotification
{
protected MerchantResolver $merchantResolver;

const MERCHANT = 'merchant';

public function __construct(
MailjetTransport $mailjetTransport,
Environment $templating,
@@ -29,10 +31,10 @@ class MailMailjetNotification extends SovMailMailjetNotification

public function send($params = [])
{
$merchantCurrent = $this->merchantResolver->getCurrent();
$merchant = isset($params[self::MERCHANT]) ? $params[self::MERCHANT] : $this->merchantResolver->getCurrent();

$merchantConfigEmailFrom = $this->settingSolver->getSettingValue(
$merchantCurrent,
$merchant,
MerchantSettingDefinition::SETTING_EMAIL_FROM
);
$emailFrom = (isset($params[self::FROM_EMAIL]) && $params[self::FROM_EMAIL] && strlen(
@@ -40,16 +42,16 @@ class MailMailjetNotification extends SovMailMailjetNotification
)) ? $params[self::FROM_EMAIL] : $merchantConfigEmailFrom;

$merchantConfigEmailFromName = $this->settingSolver->getSettingValue(
$merchantCurrent,
$merchant,
MerchantSettingDefinition::SETTING_EMAIL_FROM_NAME
);
$emailFromName = isset($params[self::FROM_NAME]) ?? $merchantConfigEmailFromName;
$emailFromName = isset($params[self::FROM_NAME]) ? $params[self::FROM_NAME] : $merchantConfigEmailFromName;

$merchantConfigEmailSubjectPrefix = $this->settingSolver->getSettingValue(
$merchantCurrent,
$merchant,
MerchantSettingDefinition::SETTING_EMAIL_SUBJECT_PREFIX
);
$emailSubjectPrefix = isset($params[self::SUBJECT_PREFIX]) ?? $merchantConfigEmailSubjectPrefix;
$emailSubjectPrefix = isset($params[self::SUBJECT_PREFIX]) ? $params[self::SUBJECT_PREFIX] : $merchantConfigEmailSubjectPrefix;
if ($emailSubjectPrefix && strlen($emailSubjectPrefix)) {
$emailSubjectPrefix .= ' ';
}

+ 2
- 3
Repository/Order/OrderProductStore.php Vedi File

@@ -28,9 +28,8 @@ class OrderProductStore extends AbstractStore

public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{
if($this->section) {
$query->filterBySection($this->section);
}
$this->addFilterBySectionOptionnal($query);

return $query;
}


+ 28
- 6
Repository/Order/OrderShopRepositoryQuery.php Vedi File

@@ -9,6 +9,7 @@ use Lc\CaracoleBundle\Model\Order\OrderPaymentInterface;
use Lc\CaracoleBundle\Model\Product\ProductInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\CaracoleBundle\Model\User\VisitorInterface;
use Lc\CaracoleBundle\Repository\SectionRepositoryQueryTrait;
use Lc\SovBundle\Model\User\UserInterface;
@@ -32,13 +33,13 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery
protected bool $isJoinDeliveryPointSale = false;
protected bool $isJoinOrderPayment = false;
protected bool $isFilteredByStatus = false;
protected bool $isJoinMainOrderShop = false;

public function __construct(OrderShopRepository $repository, PaginatorInterface $paginator)
{
parent::__construct($repository, 'orderShop', $paginator);
}


public function selectSumStatTotalWithTax(): self
{
return $this
@@ -56,7 +57,6 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery
);
}


public function selectSum(): self
{
$this->joinProduct();
@@ -269,14 +269,21 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery

public function filterIsNotComplementaryOrderShop(): self
{
return $this
->andWhere('.mainOrderShop = false OR .mainOrderShop IS NULL');
return $this->andWhere('.mainOrderShop = false OR .mainOrderShop IS NULL');
}

public function filterIsComplementaryOrderShop(): self
{
return $this->andWhere('.mainOrderShop = true OR .mainOrderShop IS NOT NULL');
}

public function filterSectionMainOrderShop(SectionInterface $section)
{
$this->joinMainOrderShop();

return $this
->andWhere('.mainOrderShop = true OR .mainOrderShop IS NOT NULL');
->andWhere('mainOrderShop.section = :sectionMainOrderShop')
->setParameter('sectionMainOrderShop', $section);
}

public function filterIsNullMainOrderShop(): self
@@ -290,6 +297,11 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery
return $this->andWhere('.deliveryDate > :today')->setParameter('today', (new DateTime())->setTime(23, 59));
}

public function filterHasOrderProducts()
{
return $this->andWhere('orderShop.orderProducts IS NOT EMPTY');
}

public function selectOrderReductionCarts(): self
{
$this->joinOrderReductionCarts();
@@ -297,7 +309,6 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery
return $this->addSelect('orderReductionCarts');
}


public function joinOrderProducts(bool $addSelect = false): self
{
if (!$this->isJoinOrderProducts) {
@@ -433,4 +444,15 @@ class OrderShopRepositoryQuery extends AbstractRepositoryQuery
return $this;
}

public function joinMainOrderShop(): self
{
if (!$this->isJoinMainOrderShop) {
$this->isJoinMainOrderShop = true;

return $this
->leftJoin('.mainOrderShop', 'mainOrderShop');
}
return $this;
}

}

+ 173
- 157
Repository/Order/OrderShopStore.php Vedi File

@@ -28,6 +28,7 @@ use Lc\CaracoleBundle\Solver\Reduction\ReductionCartSolver;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\CaracoleBundle\Repository\AbstractStore;
use Lc\SovBundle\Repository\RepositoryQueryInterface;
use Lc\SovBundle\Solver\Setting\SettingSolver;
use Lc\SovBundle\Translation\FlashBagTranslator;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
@@ -53,25 +54,26 @@ class OrderShopStore extends AbstractStore
protected OrderShopSolver $orderShopSolver;
protected ReductionCartStore $reductionCartStore;
protected DistributionBuilder $distributionBuilder;
protected SettingSolver $settingSolver;

public function __construct(
OrderShopRepositoryQuery $query,
EntityManagerInterface $entityManager,
PriceSolver $priceSolver,
DocumentBuilder $documentBuilder,
ReductionCreditStore $reductionCreditStore,
ReductionCartSolver $reductionCartSolver,
SectionStore $sectionStore,
OrderProductStore $orderProductStore,
MerchantStore $merchantStore,
FlashBagTranslator $flashBagTranslator,
ParameterBagInterface $parameterBag,
UrlGeneratorInterface $router,
OrderShopSolver $orderShopSolver,
ReductionCartStore $reductionCartStore,
DistributionBuilder $distributionBuilder
)
{
OrderShopRepositoryQuery $query,
EntityManagerInterface $entityManager,
PriceSolver $priceSolver,
DocumentBuilder $documentBuilder,
ReductionCreditStore $reductionCreditStore,
ReductionCartSolver $reductionCartSolver,
SectionStore $sectionStore,
OrderProductStore $orderProductStore,
MerchantStore $merchantStore,
FlashBagTranslator $flashBagTranslator,
ParameterBagInterface $parameterBag,
UrlGeneratorInterface $router,
OrderShopSolver $orderShopSolver,
ReductionCartStore $reductionCartStore,
DistributionBuilder $distributionBuilder,
SettingSolver $settingSolver
) {
$this->query = $query;
$this->entityManager = $entityManager;
$this->priceSolver = $priceSolver;
@@ -87,6 +89,7 @@ class OrderShopStore extends AbstractStore
$this->orderShopSolver = $orderShopSolver;
$this->reductionCartStore = $reductionCartStore;
$this->distributionBuilder = $distributionBuilder;
$this->settingSolver = $settingSolver;
}

public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
@@ -98,8 +101,8 @@ class OrderShopStore extends AbstractStore
public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{
$this
->addFilterBySectionOptionnal($query)
->addFilterByMerchantViaSectionOptionnal($query);
->addFilterBySectionOptionnal($query)
->addFilterByMerchantViaSectionOptionnal($query);

return $query;
}
@@ -115,14 +118,16 @@ class OrderShopStore extends AbstractStore
public function getByCurrentDistribution($params = [], $query = null)
{
return $this->getBy(
array_merge(
[
'distribution' => $this->distributionBuilder->guessCurrentDistributionOrder($this->section),
'isValid' => true,
],
$params
),
$query
array_merge(
[
'distribution' => $this->distributionBuilder->guessCurrentDistributionOrder(
$this->section
),
'isValid' => true,
],
$params
),
$query
);
}

@@ -131,14 +136,14 @@ class OrderShopStore extends AbstractStore
public function getByCurrentDistributionAndUser(UserInterface $user = null, array $params = [], $query = null)
{
return $this->getByCurrentDistribution(
array_merge(
[
'user' => $user,
'excludeComplementaryOrderShops' => true
],
$params
),
$query
array_merge(
[
'user' => $user,
'excludeComplementaryOrderShops' => true
],
$params
),
$query
);
}

@@ -148,14 +153,16 @@ class OrderShopStore extends AbstractStore
public function countByCurrentDistribution(array $params, $query = null)
{
return $this->countBy(
array_merge(
[
'distribution' => $this->distributionBuilder->guessCurrentDistributionOrder($this->section),
'excludeComplementaryOrderShops' => isset($params['excludeComplementaryOrderShops']) ?? true,
],
$params
),
$query
array_merge(
[
'distribution' => $this->distributionBuilder->guessCurrentDistributionOrder(
$this->section
),
'excludeComplementaryOrderShops' => isset($params['excludeComplementaryOrderShops']) ?? true,
],
$params
),
$query
);

// @TODO : optimisation à remettre en place
@@ -198,26 +205,26 @@ class OrderShopStore extends AbstractStore
public function countValidByUserAllMerchant($user, $query = null): int
{
return $this->countBy(
[
'user' => $user,
'isValid' => true,
// @TODO : à tester
'isMerchantOnline' => true,
'excludeComplementaryOrderShops' => true
],
$query
[
'user' => $user,
'isValid' => true,
// @TODO : à tester
'isMerchantOnline' => true,
'excludeComplementaryOrderShops' => true
],
$query
);
}

public function countValidByUser(UserInterface $user = null, $query = null): int
{
return $this->countBy(
[
'user' => $user,
'isValid' => true,
'excludeComplementaryOrderShops' => true
],
$query
[
'user' => $user,
'isValid' => true,
'excludeComplementaryOrderShops' => true
],
$query
);
}

@@ -225,23 +232,21 @@ class OrderShopStore extends AbstractStore
public function countValidByCurrentDistribution($query = null): int
{
return $this->countBy(
[
'distribution' => $this->distributionBuilder->guessCurrentDistributionOrder($this->section),
'isValid' => true,
'excludeComplementaryOrderShops' => true
],
$query
[
'distribution' => $this->distributionBuilder->guessCurrentDistributionOrder($this->section),
'isValid' => true,
'excludeComplementaryOrderShops' => true
],
$query
);
}

// countValidOrderWithReductionCredit
public function countValidWithReductionCredit(
ReductionCreditInterface $reductionCredit,
UserInterface $user = null,
$query = null
): int
{

ReductionCreditInterface $reductionCredit,
UserInterface $user = null,
$query = null
): int {
//TODO vérifier que ne pas utiliser createDefaultQuery est pertinent
$query = $this->createQuery($query);

@@ -250,50 +255,51 @@ class OrderShopStore extends AbstractStore
}

$query
->selectCount()
->filterByReductionCredit($reductionCredit)
->filterByStatus(OrderStatusModel::$statusAliasAsValid);
->selectCount()
->filterByReductionCredit($reductionCredit)
->filterByStatus(OrderStatusModel::$statusAliasAsValid);

return $query->count();
}

// countValidOrderWithReductionCart
public function countValidWithReductionCart(
ReductionCartInterface $reductionCart,
$query = null
): int
{
ReductionCartInterface $reductionCart,
$query = null
): int {
$query = $this->createQuery($query);

$query
->selectCount()
->filterByReductionCart($reductionCart)
->filterByStatus(OrderStatusModel::$statusAliasAsValid);
->selectCount()
->filterByReductionCart($reductionCart)
->filterByStatus(OrderStatusModel::$statusAliasAsValid);

return $query->count();
}

// countValidOrderWithReductionCartPerUser
public function countValidWithReductionCartByUser(
ReductionCartInterface $reductionCart,
UserInterface $user,
$query = null
): int
{
ReductionCartInterface $reductionCart,
UserInterface $user,
$query = null
): int {
$query = $this->createDefaultQuery($query);

$query
->selectCount()
->filterByUser($user)
->filterByReductionCart($reductionCart)
->filterByStatus(OrderStatusModel::$statusAliasAsValid);
->selectCount()
->filterByUser($user)
->filterByReductionCart($reductionCart)
->filterByStatus(OrderStatusModel::$statusAliasAsValid);

return $query->count();
}

// findCartCurrent
public function getOneCartCurrent(UserInterface $user = null, VisitorInterface $visitor = null, $query = null): ?OrderShopInterface
{
public function getOneCartCurrent(
UserInterface $user = null,
VisitorInterface $visitor = null,
$query = null
): ?OrderShopInterface {
if (is_null($user) && is_null($visitor)) {
return null;
}
@@ -309,23 +315,25 @@ class OrderShopStore extends AbstractStore
}

$query
->selectOrderReductionCarts()
->filterByStatus(OrderStatusModel::$statusAliasAsCart);
->selectOrderReductionCarts()
->filterByStatus(OrderStatusModel::$statusAliasAsCart);

return $query->findOne();
}

// findLastOrderValidOfWeek
//getOneLastValidByCycle
public function getOneLastValidByDistribution(DistributionInterface $distribution, $query = null): ?OrderShopInterface
{
public function getOneLastValidByDistribution(
DistributionInterface $distribution,
$query = null
): ?OrderShopInterface {
$query = $this->createDefaultQuery($query);

$query
->filterByDistribution($distribution)
->filterByStatus(OrderStatusModel::$statusAliasAsValid)
->filterIsNotComplementaryOrderShop()
->orderBy('.cycleId', 'DESC');
->filterByDistribution($distribution)
->filterByStatus(OrderStatusModel::$statusAliasAsValid)
->filterIsNotComplementaryOrderShop()
->orderBy('.cycleId', 'DESC');

return $query->findOne();
}
@@ -336,9 +344,9 @@ class OrderShopStore extends AbstractStore
$query = $this->createDefaultQuery($query);

$query
->filterByStatus(OrderStatusModel::$statusAliasAsValid)
->filterIsNotComplementaryOrderShop()
->orderBy('.idValidOrder', 'DESC');
->filterByStatus(OrderStatusModel::$statusAliasAsValid)
->filterIsNotComplementaryOrderShop()
->orderBy('.idValidOrder', 'DESC');

return $query->findOne();
}
@@ -362,9 +370,11 @@ class OrderShopStore extends AbstractStore

$orderShops = $query->find();

if (isset($params['mergeComplementaryOrderShops'])) {
if (isset($params['mergeComplementaryOrderShops']) && $params['mergeComplementaryOrderShops'] == true) {
$mergeComplementaryOrderShopsSameSection = isset($params['mergeComplementaryOrderShopsSameSection'])
? $params['mergeComplementaryOrderShopsSameSection'] : false;
foreach ($orderShops as $orderShop) {
$this->orderShopSolver->mergeComplentaryOrderShops($orderShop);
$this->orderShopSolver->mergeComplentaryOrderShops($orderShop, true, $mergeComplementaryOrderShopsSameSection);
}
}

@@ -429,12 +439,21 @@ class OrderShopStore extends AbstractStore
$query->filterMinimumTomorrowDelivery();
}

if (isset($params['mergeComplementaryOrderShops'])) {
if (isset($params['mergeComplementaryOrderShops']) && $params['mergeComplementaryOrderShops']) {
$query
->joinComplementaryOrderShops();
->joinComplementaryOrderShops();
}

if (isset($params['excludeComplementaryOrderShops']) || isset($params['mergeComplementaryOrderShops'])) {
if (isset($params['isComplementaryOrderShop']) && $params['isComplementaryOrderShop']) {
$query->filterIsComplementaryOrderShop();

if(isset($params['sectionMainOrderShop']) && $params['sectionMainOrderShop']) {
$query->filterSectionMainOrderShop($params['sectionMainOrderShop']);
}
}

if ((isset($params['excludeComplementaryOrderShops']) && $params['excludeComplementaryOrderShops'])
|| (isset($params['mergeComplementaryOrderShops']) && $params['mergeComplementaryOrderShops'])) {
$query->filterIsNullMainOrderShop();
}

@@ -466,11 +485,10 @@ class OrderShopStore extends AbstractStore
}

public function isReductionCreditUsed(
ReductionCreditInterface $reductionCredit,
UserInterface $user = null,
$query = null
)
{
ReductionCreditInterface $reductionCredit,
UserInterface $user = null,
$query = null
) {
if ($this->countValidWithReductionCredit($reductionCredit, $user, $query)) {
return true;
} else {
@@ -481,8 +499,8 @@ class OrderShopStore extends AbstractStore
public function getReductionCreditsAvailableByUser(UserInterface $user): array
{
$reductionCredits = $this->reductionCreditStore
->setMerchant($this->merchant)
->getByTypeAndUser(ReductionCreditModel::TYPE_CREDIT, $user);
->setMerchant($this->merchant)
->getByTypeAndUser(ReductionCreditModel::TYPE_CREDIT, $user);

$reductionCreditsArray = [];
foreach ($reductionCredits as $reductionCredit) {
@@ -497,8 +515,8 @@ class OrderShopStore extends AbstractStore
public function getReductionGiftsAvailableByUser(UserInterface $user): array
{
$reductionGifts = $this->reductionCreditStore
->setMerchant($this->merchant)
->getByTypeAndUser(ReductionCreditModel::TYPE_GIFT, $user);
->setMerchant($this->merchant)
->getByTypeAndUser(ReductionCreditModel::TYPE_GIFT, $user);

$reductionGiftsArray = [];
foreach ($reductionGifts as $reductionGift) {
@@ -514,16 +532,15 @@ class OrderShopStore extends AbstractStore
public function getReductionCartRemainingQuantity(ReductionCartInterface $reductionCart): float
{
return $reductionCart->getAvailableQuantity() - $this->countValidWithReductionCart(
$reductionCart
);
$reductionCart
);
}

// getReductionCartUsedQuantityPerUser
public function getReductionCartUsedQuantityByUser(
ReductionCartInterface $reductionCart,
UserInterface $user
): float
{
ReductionCartInterface $reductionCart,
UserInterface $user
): float {
return $this->countValidWithReductionCartByUser($reductionCart, $user);
}

@@ -535,15 +552,14 @@ class OrderShopStore extends AbstractStore

// getReductionCartRemainingQuantityPerUser
public function getReductionCartRemainingQuantityByUser(
ReductionCartInterface $reductionCart,
UserInterface $user
): float
{
ReductionCartInterface $reductionCart,
UserInterface $user
): float {
if ($reductionCart->getAvailableQuantityPerUser()) {
return $reductionCart->getAvailableQuantityPerUser() - $this->countValidWithReductionCartByUser(
$reductionCart,
$user
);
$reductionCart,
$user
);
}

return false;
@@ -553,17 +569,16 @@ class OrderShopStore extends AbstractStore
public function getReductionCartAvailableByUser(UserInterface $user, $query = null)
{
$reductionCarts = $this->reductionCartStore
->setMerchant($this->merchant)
->getOnline();
->setMerchant($this->merchant)
->getOnline();

$reductionCartsArray = [];
foreach ($reductionCarts as $reductionCart) {
if ($this->reductionCartSolver->matchWithUser($reductionCart, $user)
&& $this->reductionCartSolver->matchWithGroupUser($reductionCart, $user)
&& $this->getReductionCartRemainingQuantityByUser($reductionCart, $user)
&& ($reductionCart->getUsers()->count() > 0 || $reductionCart->getGroupUsers()->count() > 0)
&& (!$this->merchant || $reductionCart->getMerchant() == $this->merchant)) {

&& $this->reductionCartSolver->matchWithGroupUser($reductionCart, $user)
&& $this->getReductionCartRemainingQuantityByUser($reductionCart, $user)
&& ($reductionCart->getUsers()->count() > 0 || $reductionCart->getGroupUsers()->count() > 0)
&& (!$this->merchant || $reductionCart->getMerchant() == $this->merchant)) {
$reductionCartsArray[] = $reductionCart;
}
}
@@ -573,36 +588,38 @@ class OrderShopStore extends AbstractStore

//countValidOrderProductsOfCyclesByProducts
public function countValidOrderProductsOfDistributionsByProducts(
array $distributions,
array $products,
$query = null
): array
{
array $distributions,
array $products,
$query = null
): array {
$query = $this->createDefaultQuery($query);
$query
->filterByAlias(OrderStatusModel::$statusAliasAsValid)
->filterByDistributions($distributions)
->filterByProducts($products)
->selectSum()
->groupBy('distribution.cycleNumber, product.id');
->filterByAlias(OrderStatusModel::$statusAliasAsValid)
->filterByDistributions($distributions)
->filterByProducts($products)
->selectSum()
->groupBy('distribution.cycleNumber, product.id');


return $query->find();
}

//countValidOrderProductsOfCycleByProduct
public function countValidOrderProductsOfDistributionByProduct(DistributionInterface $distribution, ProductInterface $product, $query = null): ?string
{
public function countValidOrderProductsOfDistributionByProduct(
DistributionInterface $distribution,
ProductInterface $product,
$query = null
): ?string {
//TODO attention à vérifier
$query = $this->createQuery($query);

$query
->filterByAlias(OrderStatusModel::$statusAliasAsValid)
->filterByDistribution($distribution)
->filterByProduct($product)
->selectSumQuantityOrder()
->joinDistribution()
->groupBy('distribution.cycleNumber, product.id');
->filterByAlias(OrderStatusModel::$statusAliasAsValid)
->filterByDistribution($distribution)
->filterByProduct($product)
->selectSumQuantityOrder()
->joinDistribution()
->groupBy('distribution.cycleNumber, product.id');

$result = $query->findOne();

@@ -613,10 +630,9 @@ class OrderShopStore extends AbstractStore
}

public function isReductionCreditAllowAddToOrder(
OrderShopInterface $orderShop,
ReductionCreditInterface $reductionCredit
)
{
OrderShopInterface $orderShop,
ReductionCreditInterface $reductionCredit
) {
$user = $orderShop->getUser();

// appartient à l'utilisateur

+ 5
- 0
Repository/PointSale/PointSaleRepositoryQuery.php Vedi File

@@ -64,4 +64,9 @@ class PointSaleRepositoryQuery extends AbstractRepositoryQuery
}
return $this;
}

public function innerJoinDeliveryAvailabilityPointSale()
{
return $this->innerJoin('.deliveryAvailabilityPointSale');
}
}

+ 15
- 0
Repository/PointSale/PointSaleSectionRepository.php Vedi File

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

namespace Lc\CaracoleBundle\Repository\PointSale;

use App\Entity\PointSale\PointSaleSection;
use Doctrine\Persistence\ManagerRegistry;
use Lc\SovBundle\Repository\AbstractRepository;

class PointSaleSectionRepository extends AbstractRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, PointSaleSection::class);
}
}

+ 23
- 0
Repository/PointSale/PointSaleSectionRepositoryQuery.php Vedi File

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

namespace Lc\CaracoleBundle\Repository\PointSale;

use Knp\Component\Pager\PaginatorInterface;
use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface;
use Lc\CaracoleBundle\Repository\SectionRepositoryQueryTrait;
use Lc\SovBundle\Repository\AbstractRepositoryQuery;

class PointSaleSectionRepositoryQuery extends AbstractRepositoryQuery
{
use SectionRepositoryQueryTrait;

public function __construct(PointSaleSectionRepository $repository, PaginatorInterface $paginator)
{
parent::__construct($repository, 'pointSaleSection', $paginator);
}

public function filterByPointSale(PointSaleInterface $pointSale): self
{
return $this->andWhereEqual('pointSale', $pointSale);
}
}

+ 43
- 0
Repository/PointSale/PointSaleSectionStore.php Vedi File

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

namespace Lc\CaracoleBundle\Repository\PointSale;

use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface;
use Lc\CaracoleBundle\Repository\AbstractStore;
use Lc\CaracoleBundle\Repository\SectionStoreTrait;
use Lc\SovBundle\Repository\RepositoryQueryInterface;

class PointSaleSectionStore extends AbstractStore
{
use SectionStoreTrait;

protected PointSaleSectionRepositoryQuery $query;

public function __construct(PointSaleSectionRepositoryQuery $query)
{
$this->query = $query;
}

public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{
return $query;
}

public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{
$this->addFilterBySectionOptionnal($query);
return $query;
}

public function relationsDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{
return $query;
}

public function getOneByPointSale(PointSaleInterface $pointSale, $query = null)
{
$query = $this->createDefaultQuery($query);
$query->filterByPointSale($pointSale);
return $query->findOne();
}
}

+ 1
- 1
Repository/PointSale/PointSaleStore.php Vedi File

@@ -25,7 +25,7 @@ class PointSaleStore extends AbstractStore

public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{
$query->filterByMerchant($this->merchant);
$this->addFilterByMerchantOptionnal($query);
return $query;
}


+ 0
- 2
Repository/Product/ProductCategoryRepositoryQuery.php Vedi File

@@ -30,8 +30,6 @@ class ProductCategoryRepositoryQuery extends AbstractRepositoryQuery
return $this;
}



public function hasProductFamilyOnline(): self
{
$this->joinProductFamilies();

+ 1
- 1
Repository/Product/ProductCategoryStore.php Vedi File

@@ -22,7 +22,7 @@ class ProductCategoryStore extends AbstractStore

public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{
$query->orderBy('position');
$query->addOrderBy('.parent')->addOrderBy('.position');
return $query;
}


+ 1
- 1
Repository/Product/ProductFamilyRepositoryQuery.php Vedi File

@@ -161,7 +161,7 @@ class ProductFamilyRepositoryQuery extends AbstractRepositoryQuery
return $this->andWhereEqual('supplier', $supplier);
}

public function joinProductCategories(bool $addSelect = false): self
public function joinProductCategories(bool $addSelect = true): self
{
if (!$this->isJoinProductCategories) {
$this->isJoinProductCategories = true;

+ 1
- 0
Repository/Product/ProductFamilyStore.php Vedi File

@@ -208,6 +208,7 @@ class ProductFamilyStore extends AbstractStore
'ids' => [],
'categories' => [],
];

foreach ($productFamilies as $productFamily) {
$conditions['ids'][] = $productFamily->getId();
$conditions['categories'] = array_merge(

+ 2
- 2
Repository/Reduction/ReductionCreditRepositoryQuery.php Vedi File

@@ -44,13 +44,13 @@ class ReductionCreditRepositoryQuery extends AbstractRepositoryQuery
public function filterInactive()
{
$this->joinUsers();
return $this->having('COUNT(users.id) = 0');
return $this->andWhere('.users IS EMPTY');
}

public function filterActive()
{
$this->joinUsers();
return $this->having('COUNT(users.id) > 0');
return $this->andWhere('.users IS NOT EMPTY');
}

public function joinUsers()

+ 5
- 1
Repository/Section/SectionRepositoryQuery.php Vedi File

@@ -20,6 +20,10 @@ class SectionRepositoryQuery extends AbstractRepositoryQuery
return $this->andWhereEqual('isDefault', $isDefault);
}


public function filterIsOnlineFrontend()
{
return $this->filterIsOnline()
&& $this->andWhereEqual('isOnlineFrontend', true);
}

}

+ 6
- 0
Repository/Section/SectionStore.php Vedi File

@@ -75,5 +75,11 @@ class SectionStore extends AbstractStore
// @TODO : à implémenter avec le nouveau système d'ouverture des commandes
}

public function getOnlineFrontend($query = null)
{
$query = $this->createDefaultQuery($query);
$query->filterIsOnlineFrontend();
return $query->find();
}

}

+ 18
- 2
Resolver/MerchantResolver.php Vedi File

@@ -126,7 +126,7 @@ class MerchantResolver
$merchant = $this->getCurrent();
}

//TODO Pas de REPO !!!!!
// @TODO Pas de REPO !!!!!
return $this->userMerchantRepository->findOneBy(
[
'user' => $user,
@@ -135,6 +135,17 @@ class MerchantResolver
);
}

public function getAbsoluteUrl(MerchantInterface $merchant, string $name, array $parameters = []): string
{
$url = $this->settingSolver->getSettingValue($merchant, MerchantSettingDefinition::SETTING_URL);

if(substr($url, strlen($url) - 1, 1) == '/') {
$url = substr($url, 0, strlen($url) - 1);
}

return $url . $this->router->generate($name, $parameters);
}

public function getUrl(SectionInterface $section)
{
$url = $this->settingSolver->getSettingValue($section->getMerchant(), MerchantSettingDefinition::SETTING_URL);
@@ -143,7 +154,12 @@ class MerchantResolver
$url .= $section->getSlug();
}

return$url;
return $url;
}

public function getUrlAdmin(MerchantInterface $merchant)
{
return $this->settingSolver->getSettingValue($merchant, MerchantSettingDefinition::SETTING_URL).'admin';
}

public function getMerchantUser(UserInterface $user = null)

+ 31
- 5
Resolver/OpeningResolver.php Vedi File

@@ -2,11 +2,9 @@

namespace Lc\CaracoleBundle\Resolver;

use App\Entity\Section\Section;
use Lc\CaracoleBundle\Definition\SectionSettingDefinition;
use Lc\CaracoleBundle\Model\Section\OpeningInterface;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\CaracoleBundle\Model\Section\SectionModel;
use Lc\CaracoleBundle\Repository\Order\OrderShopStore;
use Lc\CaracoleBundle\Repository\Section\OpeningStore;
use Lc\CaracoleBundle\Solver\Section\OpeningSolver;
@@ -123,18 +121,21 @@ class OpeningResolver
}

// isHolidays
public function isClosingPeriod(SectionInterface $section = null)
public function isClosingPeriod(SectionInterface $section = null, \DateTime $date = null)
{
if (is_null($section)) {
$section = $this->sectionResolver->getCurrent();
}

$date = new \DateTime();
if(is_null($date)) {
$date = new \DateTime();
}

$orderClosedStart = $this->settingSolver->getSettingValue(
$section,
SectionSettingDefinition::SETTING_ORDER_CLOSED_START
);

$orderClosedEnd = $this->settingSolver->getSettingValue(
$section,
SectionSettingDefinition::SETTING_ORDER_CLOSED_END
@@ -248,6 +249,13 @@ class OpeningResolver
}

$date = new \DateTime();
if($this->isClosingPeriod($section)) {
$date = $this->settingSolver->getSettingValue(
$section,
SectionSettingDefinition::SETTING_ORDER_CLOSED_END
);
}

$openingArray = $this->openingStore
->setSection($section)
->get();
@@ -268,7 +276,7 @@ class OpeningResolver
return '';
}

public function isOpenSaleOnlyComplementaryOrders(Section $section = null, UserInterface $user = null)
public function isOpenSaleOnlyComplementaryOrders(SectionInterface $section = null, UserInterface $user = null)
{
if (is_null($section)) {
$section = $this->sectionResolver->getCurrent();
@@ -286,6 +294,24 @@ class OpeningResolver
&& count($orderShopsUser) > 0;
}

public function getMessageOpeningNextSale(SectionInterface $section): ?string
{
$openingTextClosed = $this->settingSolver->getSettingValue(
$section,
SectionSettingDefinition::SETTING_OPENING_TEXT_CLOSED
);
if ($openingTextClosed && strlen($openingTextClosed) > 0) {
return $openingTextClosed ;
}

$dateOpeningNextSale = $this->getFormatedDateOpeningNextSale($section);
if ($dateOpeningNextSale && strlen($dateOpeningNextSale) > 0) {
return 'Réouverture aux commandes le <u>'.$dateOpeningNextSale.'</u>' ;
}

return null;
}

public function getMessages(): array
{
return $this->messages;

+ 14
- 1
Resources/translations/admin.fr.yaml Vedi File

@@ -15,10 +15,12 @@ menu:


flash_message:
success:
duplicateToOtherMerchant: "Le document a bien été dupliqué sur le marchand : %merchant%"
error:
formValidation: Une erreur est survenue lors de la soumission du formulaire

settings_saved: Paramètres mis à jour
duplicateToOtherMerchant: "Le document a bien été dupliqué sur le marchand : %merchant%"
duplicateToOtherSection: "Le document a bien été dupliqué sur la section : %section%"

action:
@@ -86,6 +88,11 @@ entity:
code: Code
code_help: Code utilisé pour retrouver l'ambassade dans le tunnel de commande (Non sensible à la casse)
image: Image
pointSaleSections: Sections

PointSaleSection:
fields:
orderAmountMin: Montant minimum de commande

Address:
fields:
@@ -105,6 +112,7 @@ entity:
Merchant:
label: Marchand
label_plurial: Marchands

Section:
label: Section
label_plurial: Sections
@@ -112,6 +120,8 @@ entity:
cycle: Cycle de vente
isDefault: Section par défaut
cycleType: Cycle
isOnlineFrontend: Visible sur le site

TaxRate:
label: Règle de taxe
label_plurial: Règles de taxes
@@ -208,6 +218,9 @@ entity:
label: Catégorie
label_plurial: Catégories
ProductFamily:
flashes:
success:
duplicateToOtherMerchant: Duplication du produit sur un autre marchand réussie
fields:
priceWithTax: Prix de vente
sales: Historique des ventes

+ 20
- 1
Resources/views/admin/order/field/complementary.html.twig Vedi File

@@ -1,4 +1,22 @@
{% set value = entity.instance.complementaryOrderShops|length %}
{% set order_shop = entity.instance %}
{% set main_order_shop = entity.instance.mainOrderShop %}
{% if main_order_shop is defined and main_order_shop is not null %}
{% if order_shop.getSection() != main_order_shop.getSection() or section_container.solver.isSectionWithdrawal(order_shop.getSection()) %}
<span class="badge badge-warning section-{{ main_order_shop.getSection().getDevAlias() }}">
Complément {{ main_order_shop.getSection() }}
</span>
{% else %}
<span class="badge badge-warning">Complément</span>
{% endif %}
{% else %}
<span class="badge badge-secondary">Principale</span>
{% set complementary_order_shops = entity.instance.complementaryOrderShops %}
{% if complementary_order_shops and complementary_order_shops|length > 0 %}
<span class="badge badge-success section-{{ order_shop.getSection().getDevAlias() }}">{{ complementary_order_shops|length}} complément{% if complementary_order_shops|length > 1 %}s{% endif %}</span>
{% endif %}
{% endif %}

{# {% set value = entity.instance.complementaryOrderShops|length %}
{% if value > 0 %}
<span class="badge badge-success">
{{ value|length }} compléments
@@ -8,3 +26,4 @@
non
</span>
{% endif %}
#}

+ 5
- 1
Resources/views/admin/order/field/distribution.html.twig Vedi File

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

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

+ 5
- 8
Solver/Config/UnitSolver.php Vedi File

@@ -2,20 +2,17 @@

namespace Lc\CaracoleBundle\Solver\Config;



use Lc\CaracoleBundle\Model\Config\UnitInterface;

class UnitSolver
{
public function getWeight(UnitInterface $unit, int $quantityProduct, ?int $quantity){
if($quantity) {
public function getWeight(UnitInterface $unit, float $quantityProduct, ?float $quantity)
{
if ($quantity) {
return ($quantityProduct / $unit->getCoefficient()) * $quantity;
}else{
}
else {
return 0;
}
}


}

+ 76
- 67
Solver/Order/OrderShopSolver.php Vedi File

@@ -17,6 +17,7 @@ use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
use Lc\CaracoleBundle\Model\Product\ProductInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySectionPropertySolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver;

@@ -26,8 +27,8 @@ class OrderShopSolver
protected ProductSolver $productSolver;

public function __construct(
EntityManagerInterface $entityManager,
ProductSolver $productSolver
EntityManagerInterface $entityManager,
ProductSolver $productSolver
) {
$this->entityManager = $entityManager;
$this->productSolver = $productSolver;
@@ -36,8 +37,8 @@ class OrderShopSolver
public static function getTypeDeliveryChoices()
{
return [
OrderShopModel::DELIVERY_TYPE_HOME,
OrderShopModel::DELIVERY_TYPE_POINTSALE,
OrderShopModel::DELIVERY_TYPE_HOME,
OrderShopModel::DELIVERY_TYPE_POINTSALE,
];
}

@@ -76,8 +77,8 @@ class OrderShopSolver

// getOrderProductsByProductFamily
public function getOrderProductsByProductFamily(
OrderShopInterface $orderShop,
ProductFamilyInterface $productFamily
OrderShopInterface $orderShop,
ProductFamilyInterface $productFamily
): array {
$arrayOrderProducts = [];

@@ -91,9 +92,9 @@ class OrderShopSolver
}

public function getQuantityOrderByProduct(
OrderShopInterface $orderShop,
ProductInterface $product,
$byWeight = false
OrderShopInterface $orderShop,
ProductInterface $product,
$byWeight = false
): int {
$quantity = 0;
$productFamily = $product->getProductFamily();
@@ -101,11 +102,13 @@ class OrderShopSolver

foreach ($orderShop->getOrderProducts() as $orderProduct) {
if ($orderProduct->getProduct()->getId() == $product->getId()
|| (($behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY || $behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE)
&& $orderProduct->getProduct()->getProductFamily()->getId() == $productFamily->getId())) {
|| (($behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY || $behaviorCountStock == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE)
&& $orderProduct->getProduct()->getProductFamily()->getId() == $productFamily->getId())) {
if ($byWeight) {
$quantity += $orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct(
) / $this->productSolver->getUnitInherited($orderProduct->getProduct())->getCoefficient());
) / $this->productSolver->getUnitInherited(
$orderProduct->getProduct()
)->getCoefficient());
} else {
$quantity += $orderProduct->getQuantityOrder();
}
@@ -117,20 +120,17 @@ class OrderShopSolver

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

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

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

@@ -138,9 +138,8 @@ class OrderShopSolver
if (!$quantityOrder) {
$quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product, true);
} else {
$quantityAsked = ($this->productSolver->getQuantityInherited(
$product
) / $this->productSolver->getUnitInherited($product)->getCoefficient()) * $quantityOrder;
$quantityAsked = ($this->productSolver->getQuantityInherited($product)
/ $this->productSolver->getUnitInherited($product)->getCoefficient()) * $quantityOrder;
}

if ($checkCart) {
@@ -149,7 +148,7 @@ class OrderShopSolver
}

if (($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY
|| $productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT)) {
|| $productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT)) {
if (!$quantityOrder) {
$quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product);
}
@@ -169,7 +168,7 @@ class OrderShopSolver
public function isOneProductAvailableAddCart(OrderShopInterface $orderShop, $products): bool
{
foreach ($products as $product) {
if ($this->isProductAvailable($product, 1, true, $orderShop)) {
if ($this->isProductAvailable($orderShop->getSection(), $orderShop, $product, 1, true)) {
return true;
}
}
@@ -180,10 +179,11 @@ class OrderShopSolver
public function isOrderProductAvailableAddCart(OrderProductInterface $orderProduct, OrderShopInterface $orderShop)
{
return $this->isProductAvailable(
$orderProduct->getProduct(),
$orderProduct->getQuantityOrder(),
true,
$orderShop
$orderShop->getSection(),
$orderShop,
$orderProduct->getProduct(),
1,
true
);
}

@@ -259,33 +259,42 @@ class OrderShopSolver
}

public function mergeComplentaryOrderShops(
OrderShopInterface $orderShop,
bool $combineProducts = true
OrderShopInterface $orderShop,
bool $combineProducts = true,
bool $onlySameSection = false
): OrderShopInterface {
$this->entityManager->refresh($orderShop);

if ($this->getValidComplementaryOrderShops($orderShop)) {
foreach ($this->getValidComplementaryOrderShops($orderShop) as $complementaryOrderShop) {
foreach ($complementaryOrderShop->getOrderProducts() as $orderProductAdd) {
$updated = false;
foreach ($orderShop->getOrderProducts() as $orderProduct) {
if ($combineProducts && $orderProduct->getProduct()->getId() == $orderProductAdd->getProduct(
)->getId()
&& (string)$orderProduct->getPrice() == (string)$orderProductAdd->getPrice()
) {
$orderProduct->setUpdatedOnMergeComplementaryOrderShop(true);
$orderProduct->setQuantityOrder(
$orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
);

$updated = true;

if (!$onlySameSection || $complementaryOrderShop->getSection()->getId()
== $orderShop->getSection()->getId()) {

// @TODO : obligatoire sinon un seul orderProduct de présent
$this->entityManager->refresh($complementaryOrderShop);

foreach ($complementaryOrderShop->getOrderProducts() as $orderProductAdd) {
$updated = false;
foreach ($orderShop->getOrderProducts() as $orderProduct) {
if ($combineProducts && $orderProduct->getProduct()->getId(
) == $orderProductAdd->getProduct()->getId()
&& (string)$orderProduct->getPrice() == (string)$orderProductAdd->getPrice()
) {
$orderProduct->setUpdatedOnMergeComplementaryOrderShop(true);
$orderProduct->setQuantityOrder(
$orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()
);

$updated = true;
}
}
}

if (!$updated) {
$orderProductAdd->setOnMergeComplementaryOrderShop($complementaryOrderShop);
$orderProductAdd->setCreatedOnMergeComplementaryOrderShop(true);
$orderShop->addOrderProduct($orderProductAdd);
if (!$updated) {
$orderProductAdd->setOnMergeComplementaryOrderShop($complementaryOrderShop);
$orderProductAdd->setCreatedOnMergeComplementaryOrderShop(true);
$orderShop->addOrderProduct($orderProductAdd);
}
}
}
}
@@ -295,8 +304,8 @@ class OrderShopSolver
}

public function isReductionCreditAddedToOrder(
OrderShopInterface $orderShop,
ReductionCreditInterface $reductionCredit
OrderShopInterface $orderShop,
ReductionCreditInterface $reductionCredit
) {
foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
if ($orderReductionCredit->getReductionCredit() == $reductionCredit) {
@@ -309,8 +318,8 @@ class OrderShopSolver


public function hasOrderProductAlreadyInCart(
OrderShopInterface $orderShop,
OrderProductInterface $orderProductTest
OrderShopInterface $orderShop,
OrderProductInterface $orderProductTest
): ?OrderProductInterface {
foreach ($orderShop->getOrderProducts() as $orderProduct) {
if ($orderProduct->getProduct() == $orderProductTest->getProduct()) {
@@ -324,9 +333,9 @@ class OrderShopSolver
public function isValid(OrderShopInterface $orderShop): bool
{
if ($orderShop->getOrderStatus() && in_array(
$orderShop->getOrderStatus()->getAlias(),
OrderStatusModel::$statusAliasAsValid
) > 0) {
$orderShop->getOrderStatus()->getAlias(),
OrderStatusModel::$statusAliasAsValid
) > 0) {
return true;
}

@@ -336,9 +345,9 @@ class OrderShopSolver
public function isCart(OrderShopInterface $orderShop): bool
{
if ($orderShop->getOrderStatus() && in_array(
$orderShop->getOrderStatus()->getAlias(),
OrderStatusModel::$statusAliasAsCart
) > 0) {
$orderShop->getOrderStatus()->getAlias(),
OrderStatusModel::$statusAliasAsCart
) > 0) {
return true;
}

@@ -347,7 +356,7 @@ class OrderShopSolver

public function isDone(OrderShopInterface $orderShop): bool
{
if ($orderShop->getOrderStatus() && $orderShop->getOrderStatus()->getAlias() == OrderStatusModel::ALIAS_DONE ) {
if ($orderShop->getOrderStatus() && $orderShop->getOrderStatus()->getAlias() == OrderStatusModel::ALIAS_DONE) {
return true;
}
return false;
@@ -364,12 +373,12 @@ class OrderShopSolver
}

return max(
$this->productSolver->getAvailableQuantityInherited($product) - $this->getQuantityOrderByProduct(
$orderShop,
$product,
$byWeight
),
0
$this->productSolver->getAvailableQuantityInherited($product) - $this->getQuantityOrderByProduct(
$orderShop,
$product,
$byWeight
),
0
);
}


+ 16
- 2
Solver/PointSale/PointSaleSolver.php Vedi File

@@ -1,10 +1,9 @@
<?php


namespace Lc\CaracoleBundle\Solver\PointSale;


use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface;
use Lc\CaracoleBundle\Model\Section\SectionInterface;

class PointSaleSolver
{
@@ -36,4 +35,19 @@ class PointSaleSolver

return $html;
}

public function getOrderAmountMin(PointSaleInterface $pointSale, SectionInterface $section)
{
foreach($pointSale->getPointSaleSections() as $pointSaleSection) {
if($pointSaleSection->getSection()->getId() == $section->getId()) {
$orderAmountMin = $pointSaleSection->getOrderAmountMin();

if(!is_null($orderAmountMin)) {
return $orderAmountMin;
}
}
}

return $pointSale->getOrderAmountMin();
}
}

+ 4
- 6
Solver/Product/ProductFamilySolver.php Vedi File

@@ -14,7 +14,6 @@ use Lc\CaracoleBundle\Model\Section\SectionInterface;

class ProductFamilySolver
{

protected ProductSolver $productSolver;
protected ProductFamilySectionPropertySolver $productFamilySectionPropertySolver;
protected ProductCategorySolver $productCategorySolver;
@@ -26,7 +25,6 @@ class ProductFamilySolver
$this->productCategorySolver = $productCategorySolver;
}


public static function getBehaviorCountStockChoices(): array
{
return [
@@ -170,24 +168,24 @@ class ProductFamilySolver
return $productsOnlineArray;
}


public function getReductionCatalogInherited(ProductFamilyInterface $productFamily): ?ReductionCatalogInterface
{
return $productFamily->getReductionCatalog();
}


public function getProductCategoryParent(ProductFamilyInterface $productFamily, SectionInterface $section)
{
$productCategories = $productFamily->getProductCategories();

if (count($productCategories) > 0) {

foreach ($productCategories as $productCategory) {
if($productCategory->getSection() === $section && $productCategory->getParent()!==null){
if($productCategory->getSection()->getId() == $section->getId()
&& $productCategory->getParent() !== null) {

return $productCategory->getParent();
}
}

}

return false;

+ 8
- 4
Statistic/Product/ProductsSalesStatistic.php Vedi File

@@ -2,6 +2,7 @@

namespace Lc\CaracoleBundle\Statistic\Product;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Builder\Distribution\DistributionBuilder;
use Lc\CaracoleBundle\Container\Order\OrderShopContainer;
@@ -56,11 +57,14 @@ class ProductsSalesStatistic extends Statistic
// Initialise les valeurs des données pour chaque Interval de date
public function init(SectionInterface $section, DistributionBuilder $distributionBuilder)
{
$this->distributionList = $distributionBuilder->getDistributionListFromCurrentOrder($section, $this->nbCycle);
$distributionArray = $distributionBuilder->getDistributionListFromCurrentOrder($section, $this->nbCycle);
$this->distributionList = $distributionArray->toArray();

// if ($openingResolver->isOpenSale($section, null,OpeningResolver::OPENING_CONTEXT_BACKEND) == false && date('w') > 2) {
// $currentCycleNumber = $currentCycleNumber - 1;
// }
// @TODO : à retravailler pour inclure cette logique directement dans getDistributionListFromCurrentOrder()
$distributionCurrentOrder = $distributionBuilder->guessCurrentDistributionOrder($section);
if(!$distributionArray->contains($distributionCurrentOrder)) {
array_unshift($this->distributionList, $distributionCurrentOrder);
}

foreach ($this->distributionList as $distribution){
$this->labels[$this->getKey($distribution->getCycleNumber(),$distribution->getYear())] = $distribution->getCycleNumber();

+ 1
- 1
Twig/FormTwigExtension.php Vedi File

@@ -54,7 +54,7 @@ class FormTwigExtension extends AbstractExtension
SwitchSectionFormType::class,
null,
[
'action' => $this->urlGenerator->generate('carac_section_switch'),
'action' => $this->urlGenerator->generate('admin_section_switch'),
'attr' => ['class' => 'switch-section'],
'section' => $section,
]

+ 1
- 1
Twig/StoreTwigExtension.php Vedi File

@@ -194,7 +194,7 @@ class StoreTwigExtension extends AbstractExtension
return $this->merchantResolver->getUserMerchant();
}

public function getMerchantSetting(MerchantInterface $merchant, string $settingName): string
public function getMerchantSetting(MerchantInterface $merchant, string $settingName): ?string
{
return $this->settingSolver->getSettingValue($merchant, $settingName);
}

Loading…
Annulla
Salva