Browse Source

Intégration app product édition avancé

packProduct
Fabien Normand 3 years ago
parent
commit
c16c9a2f71
55 changed files with 1118 additions and 1214 deletions
  1. +17
    -5
      Builder/Order/OrderProductBuilder.php
  2. +17
    -10
      Builder/Order/OrderShopBuilder.php
  3. +9
    -0
      Container/Credit/CreditHistoryContainer.php
  4. +14
    -0
      Container/Product/ProductFamilyContainer.php
  5. +1
    -1
      Controller/ControllerTrait.php
  6. +37
    -5
      Definition/MerchantSettingDefinition.php
  7. +1
    -1
      Definition/SectionSettingDefinition.php
  8. +0
    -10
      Definition/SectionSettingDefinitionInterface.php
  9. +0
    -15
      Doctrine/Extension/ProductPropertyTrait.php
  10. +1
    -1
      Event/Order/CartChangeEvent.php
  11. +2
    -14
      EventSubscriber/OpeningEventSubscriber.php
  12. +3
    -5
      EventSubscriber/SettingEventSubscriber.php
  13. +3
    -1
      Factory/Order/OrderStatusHistoryFactory.php
  14. +9
    -13
      Form/Order/OrderProductType.php
  15. +68
    -18
      Form/Order/OrderProductsType.php
  16. +5
    -14
      Form/Setting/BaseSettingType.php
  17. +180
    -0
      Form/Ticket/TicketFormType.php
  18. +0
    -4
      Model/Address/AddressInterface.php
  19. +0
    -68
      Model/Credit/CreditHistoryInterface.php
  20. +0
    -70
      Model/Credit/CreditHistoryModel.php
  21. +7
    -56
      Model/Order/OrderProductModel.php
  22. +1
    -1
      Model/Order/OrderShopModel.php
  23. +0
    -235
      Model/Product/ProductFamilyInterface.php
  24. +0
    -230
      Model/Product/ProductFamilyModel.php
  25. +0
    -33
      Model/Product/ProductInterface.php
  26. +0
    -182
      Model/Product/ProductModel.php
  27. +1
    -1
      Model/Ticket/TicketModel.php
  28. +16
    -12
      Notification/MailMailjetNotification.php
  29. +6
    -0
      Repository/Address/AddressRepositoryQuery.php
  30. +9
    -0
      Repository/Address/AddressStore.php
  31. +3
    -1
      Repository/Order/OrderProductStore.php
  32. +18
    -12
      Repository/Order/OrderShopStore.php
  33. +5
    -0
      Repository/Order/OrderStatusRepositoryQuery.php
  34. +7
    -0
      Repository/Order/OrderStatusStore.php
  35. +4
    -1
      Repository/Product/ProductFamilyStore.php
  36. +2
    -1
      Repository/Reduction/ReductionCartRepositoryQuery.php
  37. +3
    -1
      Repository/Reduction/ReductionCartStore.php
  38. +3
    -1
      Repository/Reduction/ReductionCatalogStore.php
  39. +2
    -1
      Repository/Reduction/ReductionCreditRepositoryQuery.php
  40. +3
    -1
      Repository/Reduction/ReductionCreditStore.php
  41. +53
    -0
      Resolver/OrderShopResolver.php
  42. +107
    -0
      Resolver/ProductFamilyResolver.php
  43. +34
    -8
      Resolver/SectionResolver.php
  44. +3
    -1
      Resources/translations/admin.fr.yaml
  45. +78
    -0
      Solver/Credit/CreditHistorySolver.php
  46. +65
    -0
      Solver/Order/OrderProductSolver.php
  47. +41
    -41
      Solver/Order/OrderShopSolver.php
  48. +14
    -5
      Solver/Price/OrderProductPriceSolver.php
  49. +11
    -3
      Solver/Price/OrderShopPriceSolver.php
  50. +2
    -2
      Solver/Price/PriceSolver.php
  51. +13
    -7
      Solver/Price/PriceSolverTrait.php
  52. +52
    -22
      Solver/Price/ProductPriceSolver.php
  53. +35
    -99
      Solver/Product/ProductFamilySolver.php
  54. +148
    -0
      Solver/Product/ProductSolver.php
  55. +5
    -2
      Transformer/Order/OrderShopTransformer.php

+ 17
- 5
Builder/Order/OrderProductBuilder.php View File

use Lc\CaracoleBundle\Model\Order\OrderProductInterface; use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
use Lc\CaracoleBundle\Repository\Order\OrderProductStore; use Lc\CaracoleBundle\Repository\Order\OrderProductStore;
use Lc\CaracoleBundle\Resolver\Price\PriceResolver; use Lc\CaracoleBundle\Resolver\Price\PriceResolver;
use Lc\CaracoleBundle\Solver\Order\OrderProductSolver;
use Lc\CaracoleBundle\Solver\Price\PriceSolver; use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver;


class OrderProductBuilder class OrderProductBuilder
{ {
protected EntityManagerInterface $entityManager; protected EntityManagerInterface $entityManager;
protected PriceSolver $priceSolver; protected PriceSolver $priceSolver;
protected OrderProductStore $orderProductStore; protected OrderProductStore $orderProductStore;
protected ProductSolver $productSolver;
protected ProductFamilySolver $productFamilySolver;
protected OrderProductSolver $orderProductSolver;


public function __construct( public function __construct(
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
PriceSolver $priceSolver, PriceSolver $priceSolver,
OrderProductStore $orderProductStore
OrderProductStore $orderProductStore,
ProductSolver $productSolver,
OrderProductSolver $orderProductSolver,
ProductFamilySolver $productFamilySolver
) { ) {
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->priceSolver = $priceSolver; $this->priceSolver = $priceSolver;
$this->orderProductStore = $orderProductStore; $this->orderProductStore = $orderProductStore;
$this->productSolver = $productSolver;
$this->orderProductSolver = $orderProductSolver;
$this->productFamilySolver = $productFamilySolver;
} }


public function init(OrderProductInterface $orderProduct) :OrderProductInterface public function init(OrderProductInterface $orderProduct) :OrderProductInterface
{ {
$orderProduct->setTitle($orderProduct->getTitleOrderShop());
$orderProduct->setTitle($this->orderProductSolver->getTitleOrderShop($orderProduct));
$orderProduct->setPrice($this->priceSolver->getPrice($orderProduct->getProduct())); $orderProduct->setPrice($this->priceSolver->getPrice($orderProduct->getProduct()));
$orderProduct->setBuyingPrice($this->priceSolver->getBuyingPrice($orderProduct->getProduct())); $orderProduct->setBuyingPrice($this->priceSolver->getBuyingPrice($orderProduct->getProduct()));
$orderProduct->setUnit($orderProduct->getProduct()->getUnitInherited());
$orderProduct->setTaxRate($orderProduct->getProduct()->getTaxRateInherited());
$orderProduct->setQuantityProduct($orderProduct->getProduct()->getQuantityInherited());
$orderProduct->setUnit($this->productSolver->getUnitInherited($orderProduct->getProduct()));
$orderProduct->setTaxRate($this->productFamilySolver->getTaxRateInherited($orderProduct->getProduct()));
$orderProduct->setQuantityProduct($this->productSolver->getQuantityInherited($orderProduct->getProduct()));


return $orderProduct; return $orderProduct;
} }

+ 17
- 10
Builder/Order/OrderShopBuilder.php View File

use Lc\CaracoleBundle\Resolver\Price\PriceResolver; use Lc\CaracoleBundle\Resolver\Price\PriceResolver;
use Lc\CaracoleBundle\Solver\Order\OrderShopSolver; use Lc\CaracoleBundle\Solver\Order\OrderShopSolver;
use Lc\CaracoleBundle\Solver\Price\PriceSolver; use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver;
use Lc\CaracoleBundle\Statistic\Product\ProductsSalesStatistic; use Lc\CaracoleBundle\Statistic\Product\ProductsSalesStatistic;
use Lc\SovBundle\Model\User\UserInterface; use Lc\SovBundle\Model\User\UserInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
protected EventDispatcherInterface $eventDispatcher; protected EventDispatcherInterface $eventDispatcher;
protected FlashBagInterface $flashBag; protected FlashBagInterface $flashBag;
protected OpeningResolver $openingResolver; protected OpeningResolver $openingResolver;
protected ProductSolver $productSolver;


public function __construct( public function __construct(
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
PriceSolver $priceSolver, PriceSolver $priceSolver,
EventDispatcherInterface $eventDispatcher, EventDispatcherInterface $eventDispatcher,
FlashBagInterface $flashBag, FlashBagInterface $flashBag,
OpeningResolver $openingResolver
OpeningResolver $openingResolver,
ProductSolver $productSolver
) { ) {
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->orderShopStore = $orderShopStore; $this->orderShopStore = $orderShopStore;
$this->eventDispatcher = $eventDispatcher; $this->eventDispatcher = $eventDispatcher;
$this->flashBag = $flashBag; $this->flashBag = $flashBag;
$this->openingResolver = $openingResolver; $this->openingResolver = $openingResolver;
$this->productSolver = $productSolver;
} }


public function create( public function create(
UserInterface $user = null, UserInterface $user = null,
VisitorInterface $visitor = null VisitorInterface $visitor = null
): OrderShopInterface { ): OrderShopInterface {

$orderShopFactory = new OrderShopFactory(); $orderShopFactory = new OrderShopFactory();
$orderShop = $orderShopFactory->create($section, $user, $visitor); $orderShop = $orderShopFactory->create($section, $user, $visitor);


$this->setOrderStatus($orderShop, OrderStatusModel::ALIAS_CART); $this->setOrderStatus($orderShop, OrderStatusModel::ALIAS_CART);


//TODO flush ???
$this->entityManager->create($orderShop);
$this->entityManager->flush();


return $orderShop; return $orderShop;
} }
UserInterface $user = null, UserInterface $user = null,
VisitorInterface $visitor = null VisitorInterface $visitor = null
): OrderShopInterface { ): OrderShopInterface {
$cart = $this->orderShopStore->getCartBy(
$cart = $this->orderShopStore->getOneCartCurrent(
[ [
'section' => $section, 'section' => $section,
'user' => $user, 'user' => $user,
string $alias, string $alias,
bool $forceByAdmin = false bool $forceByAdmin = false
): OrderShopInterface { ): OrderShopInterface {
$orderStatus = $this->orderStatusStore->getRepositoryQuery()->findOneByAlias($alias);

$orderStatus = $this->orderStatusStore->getOneByAlias($alias);


if ($orderStatus) { if ($orderStatus) {
if ($orderShop->getOrderStatus() === null if ($orderShop->getOrderStatus() === null
): bool { ): bool {
$return = false; $return = false;


if ($this->orderProductStore->isOrderProductAvailableAddCart($orderProductAdd, $orderShop)) {
if ($this->orderShopSolver->isOrderProductAvailableAddCart($orderProductAdd, $orderShop)) {
if ($orderProductAdd->getQuantityOrder() > 0) { if ($orderProductAdd->getQuantityOrder() > 0) {
$updated = false; $updated = false;
$this->orderProductBuilder->init($orderProductAdd); $this->orderProductBuilder->init($orderProductAdd);
foreach ($orderShop->getOrderProducts() as $orderProduct) { foreach ($orderShop->getOrderProducts() as $orderProduct) {
if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId() if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()
&& $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery() && $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery()
&& (string)$this->priceResolver->getPrice($orderProduct)
== (string)$this->priceResolver->getPrice($orderProductAdd)
&& (string)$this->priceSolver->getPrice($orderProduct)
== (string)$this->priceSolver->getPrice($orderProductAdd)
&& $orderProduct->getOrderProductReductionCatalog()->compare( && $orderProduct->getOrderProductReductionCatalog()->compare(
$orderProductAdd->getOrderProductReductionCatalog() $orderProductAdd->getOrderProductReductionCatalog()
)) { )) {
$this->entityManager->create($orderProductReductionCatalog); $this->entityManager->create($orderProductReductionCatalog);
} }
//TODO est-ce un update ou un create ??? //TODO est-ce un update ou un create ???
$this->entityManager->update($orderProductAdd);
$this->entityManager->persist($orderProductAdd);
$this->entityManager->update($orderShop); $this->entityManager->update($orderShop);
} }


case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE : case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :


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


} }


// setDeliveryAddress // setDeliveryAddress
public function initDeliveryAddress(OrderShopInterface $orderShop, AddressInterface $address):void
public function initDeliveryAddress(OrderShopInterface $orderShop, AddressInterface $address = null):void
{ {
$orderShop->setDeliveryAddress($address); $orderShop->setDeliveryAddress($address);
$orderShop->setDeliveryInfos($address ? $address->getDeliveryInfos() : null); $orderShop->setDeliveryInfos($address ? $address->getDeliveryInfos() : null);

+ 9
- 0
Container/Credit/CreditHistoryContainer.php View File

use Lc\CaracoleBundle\Factory\Credit\CreditHistoryFactory; use Lc\CaracoleBundle\Factory\Credit\CreditHistoryFactory;
use Lc\CaracoleBundle\Repository\Credit\CreditHistoryRepositoryQuery; use Lc\CaracoleBundle\Repository\Credit\CreditHistoryRepositoryQuery;
use Lc\CaracoleBundle\Repository\Credit\CreditHistoryStore; use Lc\CaracoleBundle\Repository\Credit\CreditHistoryStore;
use Lc\CaracoleBundle\Solver\Credit\CreditHistorySolver;


class CreditHistoryContainer class CreditHistoryContainer
{ {
protected CreditHistoryRepositoryQuery $repositoryQuery; protected CreditHistoryRepositoryQuery $repositoryQuery;
protected CreditHistoryStore $store; protected CreditHistoryStore $store;
protected CreditHistoryBuilder $builder; protected CreditHistoryBuilder $builder;
protected CreditHistorySolver $solver;


public function __construct( public function __construct(
CreditHistoryFactory $factory, CreditHistoryFactory $factory,
CreditHistoryRepositoryQuery $repositoryQuery, CreditHistoryRepositoryQuery $repositoryQuery,
CreditHistorySolver $solver,
CreditHistoryStore $store, CreditHistoryStore $store,
CreditHistoryBuilder $builder CreditHistoryBuilder $builder
) { ) {
$this->factory = $factory; $this->factory = $factory;
$this->repositoryQuery = $repositoryQuery; $this->repositoryQuery = $repositoryQuery;
$this->solver = $solver;
$this->store = $store; $this->store = $store;
$this->builder = $builder; $this->builder = $builder;
} }
return $this->repositoryQuery; return $this->repositoryQuery;
} }


public function getSolver(): CreditHistorySolver
{
return $this->solver;
}

public function getStore(): CreditHistoryStore public function getStore(): CreditHistoryStore
{ {
return $this->store; return $this->store;

+ 14
- 0
Container/Product/ProductFamilyContainer.php View File

use Lc\CaracoleBundle\Factory\Product\ProductFamilyFactory; use Lc\CaracoleBundle\Factory\Product\ProductFamilyFactory;
use Lc\CaracoleBundle\Repository\Product\ProductFamilyRepositoryQuery; use Lc\CaracoleBundle\Repository\Product\ProductFamilyRepositoryQuery;
use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore; use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore;
use Lc\CaracoleBundle\Resolver\ProductFamilyResolver;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver; use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;


class ProductFamilyContainer class ProductFamilyContainer
protected ProductFamilyRepositoryQuery $repositoryQuery; protected ProductFamilyRepositoryQuery $repositoryQuery;
protected ProductFamilyStore $store; protected ProductFamilyStore $store;
protected ProductFamilyBuilder $builder; protected ProductFamilyBuilder $builder;
protected ProductFamilyResolver $resolver;


public function __construct( public function __construct(
ProductFamilyFactory $factory, ProductFamilyFactory $factory,
ProductFamilyRepositoryQuery $repositoryQuery, ProductFamilyRepositoryQuery $repositoryQuery,
ProductFamilyStore $store, ProductFamilyStore $store,
ProductFamilyBuilder $builder ProductFamilyBuilder $builder
ProductFamilyResolver $resolver
) { ) {
$this->factory = $factory; $this->factory = $factory;
$this->solver = $solver; $this->solver = $solver;
$this->repositoryQuery = $repositoryQuery; $this->repositoryQuery = $repositoryQuery;
$this->store = $store; $this->store = $store;
$this->builder = $builder; $this->builder = $builder;
$this->resolver = $resolver;
} }


public function getFactory(): ProductFamilyFactory public function getFactory(): ProductFamilyFactory
return $this->store; return $this->store;
} }


public function getResolver(): ProductFamilyResolver
{
return $this->resolver;
}

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

} }

+ 1
- 1
Controller/ControllerTrait.php View File



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


public function getMerchantCurrent(): MerchantInterface public function getMerchantCurrent(): MerchantInterface

+ 37
- 5
Definition/MerchantSettingDefinition.php View File

class MerchantSettingDefinition extends AbstractSettingDefinition implements MerchantSettingDefinitionInterface class MerchantSettingDefinition extends AbstractSettingDefinition implements MerchantSettingDefinitionInterface
{ {
const CATEGORY_GENERAL = 'general'; const CATEGORY_GENERAL = 'general';
const CATEGORY_EMAIL = 'email';

const SETTING_URL = 'url'; const SETTING_URL = 'url';
const SETTING_EMAIL_SUBJECT_PREFIX = 'emailSubjectPrefix';
const SETTING_EMAIL_FROM = 'emailFrom';
const SETTING_EMAIL_FROM_NAME = 'emailFromName';
const SETTING_EMAIL_CONTACT = 'emailContact';


public function __construct() public function __construct()
{ {
$this $this
->addSettingText(
->addSettingText(
[
'name' => self::SETTING_URL,
'category' => self::CATEGORY_GENERAL,
]
);

$this->addSettingText(
[
'category' => self::CATEGORY_EMAIL,
'name' => self::SETTING_EMAIL_SUBJECT_PREFIX,
]
);
$this->addSettingText(
[
'category' => self::CATEGORY_EMAIL,
'name' => self::SETTING_EMAIL_FROM,
]
);
$this->addSettingText(
[
'category' => self::CATEGORY_EMAIL,
'name' => self::SETTING_EMAIL_FROM_NAME,
]
);
$this->addSettingText(
[ [
'name' => self::SETTING_URL,
'category' => self::CATEGORY_GENERAL,
'category' => self::CATEGORY_EMAIL,
'name' => self::SETTING_EMAIL_CONTACT,
] ]
);
);
} }


public function getCategories() public function getCategories()
{ {
return [ return [
self::CATEGORY_GENERAL,
self::CATEGORY_GENERAL,
self::CATEGORY_EMAIL,
]; ];
} }



+ 1
- 1
Definition/SectionSettingDefinition.php View File



use Lc\SovBundle\Definition\AbstractSettingDefinition; use Lc\SovBundle\Definition\AbstractSettingDefinition;


class SectionSettingDefinition extends AbstractSettingDefinition implements SectionSettingDefinitionInterface
class SectionSettingDefinition extends AbstractSettingDefinition
{ {
const CATEGORY_GENERAL = 'general'; const CATEGORY_GENERAL = 'general';



+ 0
- 10
Definition/SectionSettingDefinitionInterface.php View File

<?php


namespace Lc\CaracoleBundle\Definition;


interface SectionSettingDefinitionInterface
{

}

+ 0
- 15
Doctrine/Extension/ProductPropertyTrait.php View File

return $this->buyingPriceByRefUnit; return $this->buyingPriceByRefUnit;
} }


public function getBuyingPriceByRefUnitInherited(): ?float
{
return $this->getBuyingPriceByRefUnit();
}

public function setBuyingPriceByRefUnit(?float $buyingPriceByRefUnit): self public function setBuyingPriceByRefUnit(?float $buyingPriceByRefUnit): self
{ {
$this->buyingPriceByRefUnit = $buyingPriceByRefUnit; $this->buyingPriceByRefUnit = $buyingPriceByRefUnit;
return $this->priceByRefUnit; return $this->priceByRefUnit;
} }


public function getPriceByRefUnitInherited(): ?float
{
return $this->getPriceByRefUnit();
}

public function setPriceByRefUnit(?float $priceByRefUnit): self public function setPriceByRefUnit(?float $priceByRefUnit): self
{ {
$this->priceByRefUnit = $priceByRefUnit; $this->priceByRefUnit = $priceByRefUnit;
return $this; return $this;
} }


public function getQuantityInherited(): ?float
{
return $this->getQuantity();
}

public function getAvailableQuantity(): ?float public function getAvailableQuantity(): ?float
{ {
return $this->availableQuantity; return $this->availableQuantity;

+ 1
- 1
Event/Order/CartChangeEvent.php View File



protected OrderShopInterface $orderShop; protected OrderShopInterface $orderShop;


public function __construct(OrderShopInterface $orderShop, OrderStatusInterface $orderStatus, bool $forceByAdmin)
public function __construct(OrderShopInterface $orderShop)
{ {
$this->orderShop = $orderShop; $this->orderShop = $orderShop;
} }

+ 2
- 14
EventSubscriber/OpeningEventSubscriber.php View File

namespace Lc\CaracoleBundle\EventSubscriber; namespace Lc\CaracoleBundle\EventSubscriber;


use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Definition\MerchantSettingDefinitionInterface;
use Lc\CaracoleBundle\Factory\Setting\MerchantSettingFactory;
use Lc\CaracoleBundle\Factory\Setting\SectionSettingFactory;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\CaracoleBundle\Definition\SectionSettingDefinitionInterface;
use Lc\CaracoleBundle\Repository\Merchant\MerchantRepository;
use Lc\CaracoleBundle\Repository\Section\OpeningRepositoryQuery;
use Lc\CaracoleBundle\Repository\Section\SectionRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\KernelEvents;


class OpeningEventSubscriber implements EventSubscriberInterface class OpeningEventSubscriber implements EventSubscriberInterface
{ {
protected $entityManager;
protected $openingRepositoryQuery;
protected EntityManagerInterface $entityManager;


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


public static function getSubscribedEvents() public static function getSubscribedEvents()


public function initOpenings() public function initOpenings()
{ {

} }


} }

+ 3
- 5
EventSubscriber/SettingEventSubscriber.php View File



use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Definition\MerchantSettingDefinitionInterface; use Lc\CaracoleBundle\Definition\MerchantSettingDefinitionInterface;
use Lc\CaracoleBundle\Definition\SectionSettingDefinition;
use Lc\CaracoleBundle\Factory\Setting\MerchantSettingFactory; use Lc\CaracoleBundle\Factory\Setting\MerchantSettingFactory;
use Lc\CaracoleBundle\Factory\Setting\SectionSettingFactory; use Lc\CaracoleBundle\Factory\Setting\SectionSettingFactory;
use Lc\CaracoleBundle\Model\Section\SectionInterface; use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\CaracoleBundle\Definition\SectionSettingDefinitionInterface;
use Lc\CaracoleBundle\Repository\Merchant\MerchantRepository;
use Lc\CaracoleBundle\Repository\Merchant\MerchantStore; use Lc\CaracoleBundle\Repository\Merchant\MerchantStore;
use Lc\CaracoleBundle\Repository\Section\SectionRepository;
use Lc\CaracoleBundle\Repository\Section\SectionStore; use Lc\CaracoleBundle\Repository\Section\SectionStore;
use Lc\SovBundle\Solver\Setting\SettingSolver; use Lc\SovBundle\Solver\Setting\SettingSolver;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
{ {
protected EntityManagerInterface $entityManager; protected EntityManagerInterface $entityManager;
protected MerchantSettingDefinitionInterface $merchantSettingDefinition; protected MerchantSettingDefinitionInterface $merchantSettingDefinition;
protected SectionSettingDefinitionInterface $sectionSettingDefinition;
protected SectionSettingDefinition $sectionSettingDefinition;
protected MerchantStore $merchantStore; protected MerchantStore $merchantStore;
protected SectionStore $sectionStore; protected SectionStore $sectionStore;
protected MerchantSettingFactory $merchantSettingFactory; protected MerchantSettingFactory $merchantSettingFactory;
public function __construct( public function __construct(
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
MerchantSettingDefinitionInterface $merchantSettingDefinition, MerchantSettingDefinitionInterface $merchantSettingDefinition,
SectionSettingDefinitionInterface $sectionSettingDefinition,
SectionSettingDefinition $sectionSettingDefinition,
MerchantStore $merchantStore, MerchantStore $merchantStore,
SectionStore $sectionStore, SectionStore $sectionStore,
MerchantSettingFactory $merchantSettingFactory, MerchantSettingFactory $merchantSettingFactory,

+ 3
- 1
Factory/Order/OrderStatusHistoryFactory.php View File

use Lc\CaracoleBundle\Model\Order\OrderShopInterface; use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Model\Order\OrderStatusHistoryInterface; use Lc\CaracoleBundle\Model\Order\OrderStatusHistoryInterface;
use Lc\CaracoleBundle\Model\Order\OrderStatusHistoryModel; use Lc\CaracoleBundle\Model\Order\OrderStatusHistoryModel;
use Lc\CaracoleBundle\Model\Order\OrderStatusInterface;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;


class OrderStatusHistoryFactory extends AbstractFactory class OrderStatusHistoryFactory extends AbstractFactory
{ {
public function create(OrderShopInterface $orderShop, string $status, string $origin = OrderStatusHistoryModel::ORIGIN_USER): OrderStatusHistoryInterface
public function create(OrderShopInterface $orderShop, OrderStatusInterface $status, string $origin = OrderStatusHistoryModel::ORIGIN_USER): OrderStatusHistoryInterface
{ {
$orderStatusHistory = new OrderStatusHistory(); $orderStatusHistory = new OrderStatusHistory();


$orderStatusHistory->setOrderShop($orderShop); $orderStatusHistory->setOrderShop($orderShop);
$orderStatusHistory->setOrderStatus($status); $orderStatusHistory->setOrderStatus($status);
$orderStatusHistory->setOrigin($origin); $orderStatusHistory->setOrigin($origin);
$orderStatusHistory->setCreatedAt(new \DateTime());


return $orderStatusHistory; return $orderStatusHistory;
} }

+ 9
- 13
Form/Order/OrderProductType.php View File

namespace Lc\CaracoleBundle\Form\Order; namespace Lc\CaracoleBundle\Form\Order;


use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Form\Product\ProductToIdTransformer;
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Lc\CaracoleBundle\Form\Product\ProductToIdTransformer;


class OrderProductType extends AbstractType class OrderProductType extends AbstractType
{ {


public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$data = $options['data'];

$builder $builder
->add(
'quantityOrder',
NumberType::class,
array(
'html5' => true
)
)
->add('quantityOrder', NumberType::class)
->add('product', HiddenType::class); ->add('product', HiddenType::class);


$builder->get('product')->addModelTransformer($this->productTransformer); $builder->get('product')->addModelTransformer($this->productTransformer);


public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(
[
'data_class' => $this->entityManager->getEntityName(OrderProductInterface::class),
]
);
$resolver->setDefaults([
'data_class' => $this->entityManager->getEntityName(
OrderProductInterface::class
),
]);
} }
} }

+ 68
- 18
Form/Order/OrderProductsType.php View File



namespace Lc\CaracoleBundle\Form\Order; namespace Lc\CaracoleBundle\Form\Order;


use App\Repository\Product\ProductFamilyStore;
use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Factory\Order\OrderProductFactory;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;
use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;


class OrderProductsType extends AbstractType class OrderProductsType extends AbstractType
{ {
protected EntityManagerInterface $entityManager;
protected ProductFamilyStore $productFamilyStore;
protected OrderProductFactory $orderProductFactory;
protected ProductFamilySolver $productFamilySolver;

public function __construct(
EntityManagerInterface $entityManager,
ProductFamilyStore $productFamilyStore,
OrderProductFactory $orderProductFactory,
ProductFamilySolver $productFamilySolver
) {
$this->entityManager = $entityManager;
$this->productFamilyStore = $productFamilyStore;
$this->orderProductFactory = $orderProductFactory;
$this->productFamilySolver = $productFamilySolver;
}

public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$builder->add(
'orderProducts',
CollectionType::class,
array(
'label' => false,
'entry_type' => OrderProductType::class,
'entry_options' => ['label' => false],
'allow_add' => true,
'allow_delete' => true,
'required' => true
)
);
if (isset($options['data']['id_product_family'])) {
$idProductFamily = $options['data']['id_product_family'];
$productFamily = $this->productFamilyStore->getOneById($idProductFamily);

$builder->add('id_product_family', HiddenType::class, [
'data' => $productFamily->getId()
]);

if ($productFamily) {
if ($productFamily->getActiveProducts()
&& $productFamily->getBehaviorAddToCart() == 'multiple') {
$cpt = 0;

foreach ($this->productFamilySolver->getProductsGroupByTitle($productFamily) as $key => $product) {
$orderProduct = $this->orderProductFactory->create($product[0], 0);
$builder->add('order_product_' . $cpt, OrderProductType::class, [
'data' => $orderProduct
]);
$cpt++;
}
} else {
$product = null;
if ($productFamily->getActiveProducts()) {
$products = $productFamily->getProductsOnline();
if ($products && count($products) > 0) {
$product = $products[0];
}
} else {
$originProduct = $this->productFamilySolver->getOriginProduct($productFamily);
if ($originProduct && $originProduct->getStatus() == 1) {
$product = $originProduct;
}
}

$orderProduct = $this->orderProductFactory->create($product, 1);

$builder->add('order_product_0', OrderProductType::class, [
'data' => $orderProduct
]);
}
}
}
} }


public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults(
[
]
);
$resolver->setDefaults([
// Configure your form options here
]);
} }
}
}

+ 5
- 14
Form/Setting/BaseSettingType.php View File



namespace Lc\CaracoleBundle\Form\Setting; namespace Lc\CaracoleBundle\Form\Setting;


use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Lc\CaracoleBundle\Definition\MerchantSettingDefinitionInterface; use Lc\CaracoleBundle\Definition\MerchantSettingDefinitionInterface;
use Lc\CaracoleBundle\Definition\SectionSettingDefinition;
use Lc\CaracoleBundle\Model\Setting\MerchantSettingInterface; use Lc\CaracoleBundle\Model\Setting\MerchantSettingInterface;
use Lc\CaracoleBundle\Model\Setting\SectionSettingInterface; use Lc\CaracoleBundle\Model\Setting\SectionSettingInterface;
use Lc\CaracoleBundle\Definition\SectionSettingDefinitionInterface;
use Lc\SovBundle\Form\Common\FileManagerType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Lc\SovBundle\Form\Setting\BaseSettingType as SovBaseSettingType; use Lc\SovBundle\Form\Setting\BaseSettingType as SovBaseSettingType;


abstract class BaseSettingType extends SovBaseSettingType abstract class BaseSettingType extends SovBaseSettingType
{ {
protected $em;
protected $merchantSettingDefinition;
protected $sectionSettingDefinition;
protected EntityManagerInterface $em;
protected MerchantSettingDefinitionInterface $merchantSettingDefinition;
protected SectionSettingDefinition $sectionSettingDefinition;


public function __construct( public function __construct(
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
MerchantSettingDefinitionInterface $merchantSettingDefinition, MerchantSettingDefinitionInterface $merchantSettingDefinition,
SectionSettingDefinitionInterface $sectionSettingDefinition
SectionSettingDefinition $sectionSettingDefinition
) { ) {
$this->em = $entityManager; $this->em = $entityManager;
$this->merchantSettingDefinition = $merchantSettingDefinition; $this->merchantSettingDefinition = $merchantSettingDefinition;

+ 180
- 0
Form/Ticket/TicketFormType.php View File

<?php

namespace Lc\CaracoleBundle\Form\Ticket;

use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Repository\Order\OrderShopStore;
use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\SovBundle\Component\FormComponent;
use Lc\SovBundle\Doctrine\EntityManager;
use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Solver\Ticket\TicketSolver;
use Lc\SovBundle\Translation\TranslatorAdmin;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Validator\Constraints\File;

class TicketFormType extends AbstractType
{
protected Security $security;
protected EntityManager $entityManager;
protected TranslatorAdmin $translatorAdmin;
protected TicketSolver $ticketSolver;
protected FormComponent $formComponent;
protected OrderShopStore $orderShopStore;
protected PriceSolver $priceSolver;

public function __construct(
Security $security,
EntityManager $entityManager,
TranslatorAdmin $translatorAdmin,
TicketSolver $ticketSolver,
FormComponent $formComponent,
OrderShopStore $orderShopStore,
PriceSolver $priceSolver
) {
$this->security = $security;
$this->entityManager = $entityManager;
$this->translatorAdmin = $translatorAdmin;
$this->ticketSolver = $ticketSolver;
$this->formComponent = $formComponent;
$this->orderShopStore = $orderShopStore;
$this->priceSolver = $priceSolver;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
$isConnected = $this->security->getUser();
$entityName = $this->entityManager->getEntityName(TicketInterface::class);

if (!$isConnected) {
$builder->add(
'visitorFirstname',
TextType::class,
[
'label' => 'Prénom'
]
)
->add(
'visitorLastname',
TextType::class,
[
'label' => 'Nom'
]
)
->add(
'visitorEmail',
EmailType::class,
[
'label' => 'Email'
]
);
}

$builder->add(
'type',
ChoiceType::class,
[
'label' => 'Type',
'choices' => $this->translatorAdmin->transChoices(
$this->ticketSolver->getTypeChoices(),
'Ticket',
'type'
),
]
);

if ($isConnected) {
$builder->add(
'orderShop',
EntityType::class,
[
'class' => $this->entityManager->getEntityName(OrderShopInterface::class),
'multiple' => false,
'expanded' => false,
'choices' => $this->orderShopStore->getBy(
[
'user' => $this->security->getUser(),
'isValid' => true
]
),
'label' => 'field.default.order',
'placeholder' => '-- Choisissez une commande --',
'required' => false,
'choice_label' => function ($orderShop, $key, $value) {
return 'Commande du ' . $orderShop->getValidationDate()->format(
'd/m/Y'
) . ' (' . number_format(
$this->priceSolver->getTotalWithTax($orderShop),
2
) . ' €)';
},
'translation_domain' => 'admin',
]
);
} else {
$this->formComponent->addCaptchaType($builder);
}

$builder->add(
'subject',
TextType::class
);

$builder->add(
'message',
TextareaType::class,
[
'mapped' => false,
'label' => 'Message'
]
);

$builder->add(
'image',
FileType::class,
[
'label' => 'Photo',
'mapped' => false,
'required' => false,
'constraints' => [
new File(
[
'maxSize' => '2048k',
'mimeTypes' => [
'image/png',
'image/jpeg',
'image/jpg',
'image/gif',
],
'mimeTypesMessage' => "Mauvais format d'image (formats acceptés : jpeg, png, gif)",
]
)
],
]
);
}

/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => $this->entityManager->getEntityName(TicketInterface::class),
]
);
}
}

+ 0
- 4
Model/Address/AddressInterface.php View File



namespace Lc\CaracoleBundle\Model\Address; namespace Lc\CaracoleBundle\Model\Address;



use Lc\CaracoleBundle\Model\Merchant\MerchantInterface; use Lc\CaracoleBundle\Model\Merchant\MerchantInterface;
use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface; use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface;
use Lc\SovBundle\Model\User\UserInterface; use Lc\SovBundle\Model\User\UserInterface;


/**
* @ORM\MappedSuperclass()
*/
interface AddressInterface interface AddressInterface
{ {
public function getUser(): ?UserInterface; public function getUser(): ?UserInterface;

+ 0
- 68
Model/Credit/CreditHistoryInterface.php View File

*/ */
interface CreditHistoryInterface interface CreditHistoryInterface
{ {
public function getCreatedBy(): ?UserInterface;


public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function __toString();

public function getAmount(): ?float;

public function setAmount(?float $amount);

public function getAmountInherited(): float;

public function getMeanPaymentInherited(): string;

public function getPaidAtInherited(): ?\DateTimeInterface;

public function getReferenceInherited(): ?string;

public function getCommentInherited(): ?string;

public function getMeanPaymentInheritedLabel(): string;

public function getType(): ?string;

public function setType(string $type): CreditHistoryModel;

public function getUserMerchant(): ?UserMerchantInterface;

public function setUserMerchant(?UserMerchantInterface $userMerchant): CreditHistoryModel;

public function getOrderPayment(): ?OrderPaymentInterface;

public function setOrderPayment(?OrderPaymentInterface $orderPayment): CreditHistoryModel;

public function getOrderRefund(): ?OrderRefundInterface;

public function setOrderRefund(?OrderRefundInterface $orderRefund): CreditHistoryModel;

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

public function setMeanPayment(?string $meanPayment): CreditHistoryModel;

public function getMeanPayment(): ?string;

public function getReference(): ?string;

public function setReference(?string $reference): CreditHistoryModel;

public function getPaidAt(): ?\DateTimeInterface;

public function setPaidAt(?\DateTimeInterface $paidAt): CreditHistoryModel;

public function getComment(): ?string;

public function setComment(?string $comment): CreditHistoryModel;

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;

public function setUpdatedAt(\DateTimeInterface $updatedAt);
} }

+ 0
- 70
Model/Credit/CreditHistoryModel.php View File

return $this; return $this;
} }


public function getAmountInherited(): float
{
if ($this->getOrderPayment() !== null) {
return $this->getOrderPayment()->getAmount();
} else {
if ($this->getOrderRefund() !== null) {
return $this->getOrderRefund()->getAmount();
} else {
return $this->getAmount();
}
}
}

public function getMeanPaymentInherited(): string
{
if ($this->getOrderPayment() !== null) {
return $this->getOrderPayment()->getMeanPayment();
} else {
if ($this->getOrderRefund() !== null) {
return $this->getOrderRefund()->getMeanPayment();
} else {
return $this->getMeanPayment();
}
}
}

public function getPaidAtInherited(): ?\DateTimeInterface
{
if ($this->getOrderPayment() !== null) {
return $this->getOrderPayment()->getPaidAt();
} else {
if ($this->getOrderRefund() !== null) {
return $this->getOrderRefund()->getPaidAt();
} else {
return $this->getPaidAt();
}
}
}

public function getReferenceInherited(): ?string
{
if ($this->getOrderPayment() !== null) {
return $this->getOrderPayment()->getReference();
} else {
if ($this->getOrderRefund() !== null) {
return $this->getOrderRefund()->getReference();
} else {
return $this->getReference();
}
}
}

public function getCommentInherited(): ?string
{
if ($this->getOrderPayment() !== null) {
return $this->getOrderPayment()->getComment();
} else {
if ($this->getOrderRefund() !== null) {
return $this->getOrderRefund()->getComment();
} else {
return $this->getComment();
}
}
}

public function getMeanPaymentInheritedLabel(): string
{
return 'field.default.meanPaymentOptions.' . $this->getMeanPaymentInherited();
}

public function getType(): ?string public function getType(): ?string
{ {
return $this->type; return $this->type;

+ 7
- 56
Model/Order/OrderProductModel.php View File

use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Lc\CaracoleBundle\Doctrine\Extension\PriceInterface; use Lc\CaracoleBundle\Doctrine\Extension\PriceInterface;
use Lc\CaracoleBundle\Model\Product\ProductInterface; use Lc\CaracoleBundle\Model\Product\ProductInterface;
use Lc\SovBundle\Doctrine\EntityInterface;


/** /**
* @ORM\MappedSuperclass() * @ORM\MappedSuperclass()
*/ */
abstract class OrderProductModel implements PriceInterface
abstract class OrderProductModel implements PriceInterface, EntityInterface
{ {
use PriceTrait; use PriceTrait;


} }
} }


public function getTitleOrderShop()
{
$product = $this->getProduct();
$productFamily = $product->getProductFamily();

$titleProduct = $product->getTitle();
$titleProductFamily = $productFamily->getTitle();

if (strlen($titleProduct) > 0 && strlen($titleProductFamily) > 0) {
$title = $titleProductFamily . ' - ' . $titleProduct;
} else {
$title = strlen($titleProduct) ? $titleProduct : $titleProductFamily;
}

if ($productFamily->hasProductsWithVariousWeight()) {
$title .= ' - ' . $product->getQuantityLabelInherited();
}

return $title;
}

public function getTitleSummaryAfterAddCart()
{
$title = '';

$product = $this->getProduct();
$productFamily = $product->getProductFamily();
$titleProduct = $product->getTitleInherited();
$titleProductFamily = $productFamily->getTitle();

// multiple
if ($productFamily->getActiveProducts() && $productFamily->getBehaviorAddToCart() == 'multiple') {
$title .= $titleProduct;
if ($productFamily->hasProductsWithVariousWeight()) {
$title .= ' - ' . $product->getQuantityLabelInherited();
}
}

// simple
if ($productFamily->getBehaviorAddToCart() == 'simple') {
if ($productFamily->getActiveProducts()) {
$title .= $titleProduct;
if ($productFamily->hasProductsWithVariousWeight()) {
$title .= ' - ' . $product->getQuantityLabelInherited();
}
}
}

return $title;
}

// isOrderProductAvailable // isOrderProductAvailable
public function isAvailable()
/*public function isAvailable()
{ {
return $this->getProduct()->isAvailable($this->getQuantityOrder()); return $this->getProduct()->isAvailable($this->getQuantityOrder());
}
}*/


// isOrderProductAvailableAddCart // isOrderProductAvailableAddCart
public function isAvailableAddCart(OrderShopInterface $orderShop = null)
// @TODO : à remettre en place si nécessaire
/*public function isAvailableAddCart(OrderShopInterface $orderShop = null)
{ {
$product = $this->getProduct(); $product = $this->getProduct();
return $this->isProductAvailable($product, $this->getQuantityOrder(), true, $orderShop); return $this->isProductAvailable($product, $this->getQuantityOrder(), true, $orderShop);
}
}*/


public function getOrderShop(): ?OrderShopInterface public function getOrderShop(): ?OrderShopInterface
{ {

+ 1
- 1
Model/Order/OrderShopModel.php View File

protected $meanPayment; protected $meanPayment;


/** /**
* @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\Order\OrderStatusHistoryInterface", mappedBy="orderShop", orphanRemoval=true)
* @ORM\OneToMany(targetEntity="Lc\CaracoleBundle\Model\Order\OrderStatusHistoryInterface", mappedBy="orderShop", orphanRemoval=true, cascade={"persist"})
*/ */
protected $orderStatusHistories; protected $orderStatusHistories;



+ 0
- 235
Model/Product/ProductFamilyInterface.php View File



namespace Lc\CaracoleBundle\Model\Product; namespace Lc\CaracoleBundle\Model\Product;



use Doctrine\Common\Collections\Collection;
use Lc\CaracoleBundle\Model\Reduction\ReductionCatalogInterface;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\SovBundle\Model\File\FileInterface;

/** /**
* @ORM\MappedSuperclass() * @ORM\MappedSuperclass()
*/ */
interface ProductFamilyInterface interface ProductFamilyInterface
{ {
public function getBehaviorCountStockChoices(): array;

public function getBehaviorDisplaySaleChoices(): array;

public function getBehaviorStockCycleChoices(): array;

public function getWaringMessageTypeChoices(): array;

public function getBehaviorAddToCartChoices(): array;

public function getBehaviorPriceChoices(): array;

public function getPropertyOrganicLabelChoices(): array;

public function getTypeExpirationDateChoices(): array;

public function getBehaviorExpirationDateChoices(): array;

public function getSection(): SectionInterface;

public function setSection(SectionInterface $section): ProductFamilyModel;

public function getAvailableQuantityInherited();

public function getTaxRateInherited();

public function getActiveProducts(): ?bool;

public function setActiveProducts(bool $activeProducts): ProductFamilyModel;

public function getProductsQuantityAsTitle(): ?bool;

public function setProductsQuantityAsTitle(bool $productsQuantityAsTitle
): ProductFamilyModel;

public function getProductsType(): ?string;

public function setProductsType(?string $productsType): ProductFamilyModel;

public function getQuantityLabel(): ?string;

public function setQuantityLabel(?string $quantityLabel): ProductFamilyModel;

/**
* @return Collection|ProductInterface[]
*/
public function getProducts(): Collection;

public function getProductsOnline(): Collection;

public function addProduct(ProductInterface $product): ProductFamilyModel;

public function removeProduct(ProductInterface $product): ProductFamilyModel;

public function getReductionCatalog(): ?ReductionCatalogInterface;

public function getReductionCatalogInherited(): ?ReductionCatalogInterface;

public function setReductionCatalog(?ReductionCatalogInterface $reductionCatalog
): ProductFamilyModel;

/**
* @return Collection|ProductCategoryInterface[]
*/
public function getProductCategories(): Collection;

public function initProductCategories();

public function addProductCategory(ProductCategoryInterface $productCategory
): ProductFamilyModel;

public function removeProductCategory(ProductCategoryInterface $productCategory
): ProductFamilyModel;

public function getProductCategoryParent();

public function getProductCategoryChild();

public function getSubtitle(): ?string;

public function setSubtitle(?string $subtitle): ProductFamilyModel;

public function getWarningMessage(): ?string;

public function setWarningMessage(?string $warningMessage): ProductFamilyModel;

public function getWarningMessageType(): ?string;

public function setWarningMessageType(?string $warningMessageType
): ProductFamilyModel;

public function getNote(): ?string;

public function setNote(?string $note): ProductFamilyModel;

public function getBehaviorOutOfStock(): ?string;

public function setBehaviorOutOfStock(?string $behaviorOutOfStock
): ProductFamilyModel;

public function getBehaviorCountStock(): ?string;

public function setBehaviorCountStock(string $behaviorCountStock
): ProductFamilyModel;

public function getExportTitle(): ?string;

public function setExportTitle(?string $exportTitle): ProductFamilyModel;

public function getExportNote(): ?string;

public function setExportNote(?string $exportNote): ProductFamilyModel;

public function getBehaviorStockCycle(): ?string;

public function setBehaviorStockCycle(string $behaviorStockWeek
): ProductFamilyModel;

public function getAvailabilityRenewedThisWeek(): ?bool;

public function setAvailabilityRenewedThisWeek(?bool $availabilityRenewedThisWeek
): ProductFamilyModel;

public function getBehaviorDisplaySale(): ?string;

public function setBehaviorDisplaySale(string $behaviorDisplaySale
): ProductFamilyModel;

public function isPropertyNoveltyOnline(): ?bool;

public function getPropertyNoveltyExpirationDate(): ?\DateTimeInterface;

public function setPropertyNoveltyExpirationDate(?\DateTimeInterface $propertyNoveltyExpirationDate
): ProductFamilyModel;

public function getPropertyOrganicLabel(): ?string;

public function setPropertyOrganicLabel(?string $propertyOrganicLabel
): ProductFamilyModel;

public function getPropertyAllergens(): ?string;

public function setPropertyAllergens(?string $propertyAllergens
): ProductFamilyModel;

public function getPropertyComposition(): ?string;

public function setPropertyComposition(?string $propertyComposition
): ProductFamilyModel;

public function getPropertyFragrances(): ?string;

public function setPropertyFragrances(?string $propertyFragrances
): ProductFamilyModel;

public function countProperties(): bool;

public function getBehaviorExpirationDate(): ?string;

public function setBehaviorExpirationDate(?string $behaviorExpirationDate
): ProductFamilyModel;

public function getTypeExpirationDate(): ?string;

public function setTypeExpirationDate(?string $typeExpirationDate
): ProductFamilyModel;

public function getPropertyWeight(): ?string;

public function setPropertyWeight(?string $propertyWeight): ProductFamilyModel;

public function getPropertyQuantity(): ?string;

public function setPropertyQuantity(?string $propertyQuantity): ProductFamilyModel;

public function getPropertyVariety(): ?string;

public function setPropertyVariety(?string $propertyVariety): ProductFamilyModel;

public function getPropertyFeature(): ?string;

public function setPropertyFeature(?string $propertyFeature): ProductFamilyModel;

public function getPropertyAlcoholLevel(): ?string;

public function setPropertyAlcoholLevel(?string $propertyAlcoholLevel
): ProductFamilyModel;

public function getPropertyPackaging(): ?string;

public function setPropertyPackaging(?string $propertyPackaging
): ProductFamilyModel;

public function getPropertyCharacteristics(): ?string;

public function setPropertyCharacteristics(?string $propertyCharacteristics
): ProductFamilyModel;

public function getBehaviorAddToCart(): ?string;

public function setBehaviorAddToCart(?string $behaviorAddToCart
): ProductFamilyModel;

public function getBehaviorPrice(): ?string;

public function getBehaviorPriceInherited();

public function setBehaviorPrice(?string $behaviorPrice): ProductFamilyModel;

public function hasProductsWithVariousWeight();

public function getProductsGroupByTitle();

public function getOriginProduct();

public function getOriginProductOnline();

public function hasOneProductOnline();

public function getSaleStatus(): ?bool;

public function setSaleStatus(bool $saleStatus): ProductFamilyModel;

public function getFieldBuyingPrice();

public function getFieldPrice();

public function getImage(): ?FileInterface;


public function setImage(?FileInterface $image): ProductFamilyModel;
} }

+ 0
- 230
Model/Product/ProductFamilyModel.php View File

{ {
use ProductPropertyTrait; use ProductPropertyTrait;



const BEHAVIOR_COUNT_STOCK_UNLIMITED = 'unlimited'; const BEHAVIOR_COUNT_STOCK_UNLIMITED = 'unlimited';
const BEHAVIOR_COUNT_STOCK_BY_MEASURE = 'by-measure'; const BEHAVIOR_COUNT_STOCK_BY_MEASURE = 'by-measure';
const BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY = 'by-product-family'; const BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY = 'by-product-family';
return $this; return $this;
} }


//TODO move
public function getAvailableQuantityInherited()
{
$availableQuantity = 0;

switch ($this->getBehaviorCountStock()) {
case self::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
case self::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :

$availableQuantity = $this->getAvailableQuantity();
break;

case self::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :

foreach ($this->getProductsOnline() as $product) {
$availableQuantity += $product->getAvailableQuantityInherited();
}
break;

case self::BEHAVIOR_COUNT_STOCK_UNLIMITED :
$availableQuantity = false;
break;
}

return $availableQuantity;
}

//TODO move
public function getTaxRateInherited()
{
if ($this->getTaxRate()) {
return $this->getTaxRate();
} else {
return $this->getSection()->getMerchant()->getTaxRate();
}
}

public function getActiveProducts(): ?bool public function getActiveProducts(): ?bool
{ {
return $this->activeProducts; return $this->activeProducts;
return $this->products; return $this->products;
} }


//TODO move
public function getProductsOnline(): Collection
{
$products = $this->getProducts();
$productsOnlineArray = new ArrayCollection();

foreach ($products as $product) {
if ($product->getStatus() == 1 && $product->getOriginProduct() != true) {
$productsOnlineArray[] = $product;
}
}

return $productsOnlineArray;
}

public function addProduct(ProductInterface $product): self public function addProduct(ProductInterface $product): self
{ {
if (!$this->products->contains($product)) { if (!$this->products->contains($product)) {
return $this->reductionCatalog; return $this->reductionCatalog;
} }


//TODO move
public function getReductionCatalogInherited(): ?ReductionCatalogInterface
{
return $this->getReductionCatalog();
}

public function setReductionCatalog(?ReductionCatalogInterface $reductionCatalog): self public function setReductionCatalog(?ReductionCatalogInterface $reductionCatalog): self
{ {
$this->reductionCatalog = $reductionCatalog; $this->reductionCatalog = $reductionCatalog;
return $this; return $this;
} }


//TODO move
public function getProductCategoryParent()
{
$productCategories = $this->getProductCategories();

if (count($productCategories) > 0) {
return $productCategories[0]->getParent();
}

return false;
}


//TODO move
public function getProductCategoryChild()
{
$productCategories = $this->getProductCategories();

foreach ($productCategories as $productCategory) {
if ($productCategory->getParent()) {
return $productCategory;
}
}

return false;
}

public function getSubtitle(): ?string public function getSubtitle(): ?string
{ {
return $this->subtitle; return $this->subtitle;
return $this; return $this;
} }


//TODO move
public function isPropertyNoveltyOnline(): ?bool
{
if ($this->getPropertyNoveltyExpirationDate()) {
$now = new \DateTime();
if ($now <= $this->getPropertyNoveltyExpirationDate()) {
return true;
}
}

return false;
}

public function getPropertyNoveltyExpirationDate(): ?\DateTimeInterface public function getPropertyNoveltyExpirationDate(): ?\DateTimeInterface
{ {
return $this->propertyNoveltyExpirationDate; return $this->propertyNoveltyExpirationDate;
return $this; return $this;
} }


//TODO move
public function countProperties(): bool
{
$count = 0;

$count += (int)strlen($this->getPropertyOrganicLabel()) > 0;
$count += (int)strlen($this->getPropertyWeight()) > 0;
$count += (int)strlen($this->getPropertyFragrances()) > 0;
$count += (int)strlen($this->getPropertyComposition()) > 0;
$count += (int)strlen($this->getPropertyAllergens()) > 0;
$count += (int)strlen($this->getPropertyAlcoholLevel()) > 0;
$count += (int)strlen($this->getPropertyCharacteristics()) > 0;
$count += (int)strlen($this->getPropertyFeature()) > 0;
$count += (int)strlen($this->getPropertyPackaging()) > 0;
$count += (int)strlen($this->getPropertyQuantity()) > 0;
$count += (int)strlen($this->getPropertyVariety()) > 0;
$count += (int)($this->getPropertyExpirationDate() != null);

return $count;
}

public function getBehaviorExpirationDate(): ?string public function getBehaviorExpirationDate(): ?string
{ {
return $this->behaviorExpirationDate; return $this->behaviorExpirationDate;
return $this; return $this;
} }



public function getPropertyWeight(): ?string public function getPropertyWeight(): ?string
{ {
return $this->propertyWeight; return $this->propertyWeight;
return $this; return $this;
} }



public function getPropertyQuantity(): ?string public function getPropertyQuantity(): ?string
{ {
return $this->propertyQuantity; return $this->propertyQuantity;
return $this; return $this;
} }



public function getPropertyPackaging(): ?string public function getPropertyPackaging(): ?string
{ {
return $this->propertyPackaging; return $this->propertyPackaging;
return $this->behaviorPrice; return $this->behaviorPrice;
} }


//TODO move
public function getBehaviorPriceInherited()
{
return $this->getBehaviorPrice();
}

public function setBehaviorPrice(?string $behaviorPrice): self public function setBehaviorPrice(?string $behaviorPrice): self
{ {
$this->behaviorPrice = $behaviorPrice; $this->behaviorPrice = $behaviorPrice;
return $this; return $this;
} }


//TODO move
public function hasProductsWithVariousWeight()
{
if ($this->getActiveProducts()) {
$arrayCountProducts = [];
$products = $this->getProductsOnline();

foreach ($products as $product) {
$titleProduct = $product->getTitleInherited();
if (!isset($arrayCountProducts[$titleProduct])) {
$arrayCountProducts[$titleProduct] = [];
}

if (!in_array($product->getQuantityLabelInherited(), $arrayCountProducts[$titleProduct])) {
$arrayCountProducts[$titleProduct][] = $product->getQuantityLabelInherited();
}

if (count($arrayCountProducts[$titleProduct]) > 1) {
return true;
}
}
}

return false;
}

//TODO move
public function getProductsGroupByTitle()
{
$arrayProductsGroupByTitle = [];
$products = $this->getProductsOnline();

foreach ($products as $product) {
if ($product->getStatus() == 1) {
$titleProduct = $product->getTitleInherited();
if (!isset($arrayProductsGroupByTitle[$titleProduct])) {
$arrayProductsGroupByTitle[$titleProduct] = [];
}
$arrayProductsGroupByTitle[$titleProduct][] = $product;
}
}

return $arrayProductsGroupByTitle;
}

//TODO move
public function getOriginProduct()
{
$products = $this->getProducts();

foreach ($products as $product) {
if ($product->getOriginProduct()) {
return $product;
}
}
}

//TODO move
public function getOriginProductOnline()
{
$originProduct = $this->getOriginProduct();

if ($originProduct->getStatus() == 1) {
return $originProduct;
} else {
return false;
}
}

//TODO move
public function hasOneProductOnline()
{
if (($this->getActiveProducts() && count($this->getProductsOnline()) > 0)
|| (!$this->getActiveProducts() && $this->getOriginProduct())) {
return true;
}

return false;
}

public function getSaleStatus(): ?bool public function getSaleStatus(): ?bool
{ {
return $this->saleStatus; return $this->saleStatus;
return $this; return $this;
} }


//TODO move
public function getFieldBuyingPrice()
{
if ($this->getBehaviorPrice() === self::BEHAVIOR_PRICE_BY_PIECE) {
return 'buyingPrice';
} elseif ($this->getBehaviorPrice() === self::BEHAVIOR_PRICE_BY_REFERENCE_UNIT) {
return 'buyingPriceByRefUnit';
}
}

//TODO move
public function getFieldPrice()
{
if ($this->getBehaviorPrice() === self::BEHAVIOR_PRICE_BY_PIECE) {
return 'price';
} elseif ($this->getBehaviorPrice() === self::BEHAVIOR_PRICE_BY_REFERENCE_UNIT) {
return 'priceByRefUnit';
}
}


public function getImage(): ?FileInterface public function getImage(): ?FileInterface
{ {
return $this->image; return $this->image;

+ 0
- 33
Model/Product/ProductInterface.php View File

*/ */
interface ProductInterface interface ProductInterface
{ {
public function getQuantityMaxAddCart(OrderShopInterface $orderShop);

public function getProductQuantity();

public function getBuyingPriceInherited();

public function getBuyingPriceByRefUnitInherited();

public function getPriceInherited();

public function getPriceByRefUnitInherited();

public function getBehaviorPriceInherited();

public function getReductionCatalogInherited();

public function getUnitInherited();

public function getTitleInherited();

public function getQuantityInherited();

public function getQuantityLabelInherited();

public function getQuantityTitle($productFamily);

public function getAvailableQuantityInherited();

public function getTaxRateInherited();


public function getProductFamily(): ?ProductFamilyInterface; public function getProductFamily(): ?ProductFamilyInterface;




public function getExportTitle(): ?string; public function getExportTitle(): ?string;


public function getExportTitleInherited(): ?string;

public function setExportTitle(?string $exportTitle): \Lc\CaracoleBundle\Model\Product\ProductModel; public function setExportTitle(?string $exportTitle): \Lc\CaracoleBundle\Model\Product\ProductModel;


public function getExportNote(): ?string; public function getExportNote(): ?string;


public function getExportNoteInherited(): ?string;

public function setExportNote(?string $exportNote): \Lc\CaracoleBundle\Model\Product\ProductModel; public function setExportNote(?string $exportNote): \Lc\CaracoleBundle\Model\Product\ProductModel;
} }

+ 0
- 182
Model/Product/ProductModel.php View File

return $title; return $title;
} }


// @TODO : move
// getProductQuantityMaxAddCart
public function getQuantityMaxAddCart(OrderShopInterface $orderShop)
{
$productFamily = $this->getProductFamily();

$byWeight = false;
if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
$byWeight = true;
}

return $this->getAvailableQuantityInherited() - $orderShop->getQuantityOrderByProduct($this, $byWeight);
}

// @TODO : move
// getProductQuantity
public function getProductQuantity()
{
$productFamily = $this->getProductFamily();

if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
return $this->getQuantityInherited() / $this->getUnitInherited()->getCoefficient();
} else {
return 1;
}
}

// @TODO : move
public function getBuyingPriceInherited()
{
if ($this->getBuyingPrice()) {
return $this->getBuyingPrice();
} else {
return $this->getProductFamily()->getBuyingPrice();
}
}

// @TODO : move
public function getBuyingPriceByRefUnitInherited()
{
if ($this->getBuyingPriceByRefUnit()) {
return $this->getBuyingPriceByRefUnit();
} else {
return $this->getProductFamily()->getBuyingPriceByRefUnit();
}
}

// @TODO : move
public function getPriceInherited()
{
if ($this->getPrice()) {
return $this->getPrice();
} else {
return $this->getProductFamily()->getPrice();
}
}

// @TODO : move
public function getPriceByRefUnitInherited()
{
if ($this->getPriceByRefUnit()) {
return $this->getPriceByRefUnit();
} else {
return $this->getProductFamily()->getPriceByRefUnit();
}
}

// @TODO : move
public function getBehaviorPriceInherited()
{
return $this->getProductFamily()->getBehaviorPrice();
}

// @TODO : move
public function getReductionCatalogInherited()
{
return $this->getProductFamily()->getReductionCatalog();
}

// @TODO : move
public function getUnitInherited()
{
if ($this->getUnit()) {
return $this->getUnit();
} else {
return $this->getProductFamily()->getUnit();
}
}

// @TODO : move
public function getTitleInherited()
{
if ($this->getTitle()) {
return $this->getTitle();
} else {
return $this->getProductFamily()->getTitle();
}
}

// @TODO : move
public function getQuantityInherited()
{
if ($this->getQuantity()) {
return $this->getQuantity();
} else {
return $this->getProductFamily()->getQuantity();
}
}

// @TODO : move
public function getQuantityLabelInherited()
{
$quantity = $this->getQuantityInherited();
$unit = $this->getUnitInherited();
return $quantity . $unit->getWordingShort();
}

// @TODO : move
public function getQuantityTitle($productFamily)
{
$title = $this->getQuantityLabelInherited();
if ($productFamily->hasProductsWithVariousWeight()) {
$title .= ', ' . $this->getTitleInherited();
}
return $title;
}

// @TODO : move
public function getAvailableQuantityInherited()
{
switch ($this->getProductFamily()->getBehaviorCountStock()) {
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
return $this->getProductFamily()->getAvailableQuantity();
break;
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :
return $this->getAvailableQuantity();
break;
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_UNLIMITED :
return false;
break;
}
}

// @TODO : move
public function getTaxRateInherited()
{
return $this->getProductFamily()->getTaxRateInherited();
}

public function getProductFamily(): ?ProductFamilyInterface public function getProductFamily(): ?ProductFamilyInterface
{ {
return $this->productFamily; return $this->productFamily;
return $this; return $this;
} }



public function getExportTitle(): ?string public function getExportTitle(): ?string
{ {
return $this->exportTitle; return $this->exportTitle;
} }
//TODO move
public function getExportTitleInherited(): ?string
{
$exportTitle = $this->getExportTitle();
if ($exportTitle && strlen($exportTitle)) {
return $exportTitle;
} else {
$productFamily = $this->getProductFamily();
if ($productFamily) {
return $productFamily->getExportTitle();
}
}

return null;
}


public function setExportTitle(?string $exportTitle): self public function setExportTitle(?string $exportTitle): self
{ {
return $this->exportNote; return $this->exportNote;
} }


//TODO move
public function getExportNoteInherited(): ?string
{
$exportNote = $this->getExportNote();
if ($exportNote && strlen($exportNote)) {
return $exportNote;
} else {
$productFamily = $this->getProductFamily();
if ($productFamily) {
return $productFamily->getExportNote();
}
}

return null;
}

public function setExportNote(?string $exportNote): self public function setExportNote(?string $exportNote): self
{ {
$this->exportNote = $exportNote; $this->exportNote = $exportNote;

+ 1
- 1
Model/Ticket/TicketModel.php View File

return $this; return $this;
} }


public function getOrderShop(): OrderShopInterface
public function getOrderShop(): ?OrderShopInterface
{ {
return $this->orderShop; return $this->orderShop;
} }

+ 16
- 12
Notification/MailMailjetNotification.php View File



use Lc\CaracoleBundle\Definition\MerchantSettingDefinition; use Lc\CaracoleBundle\Definition\MerchantSettingDefinition;
use Lc\CaracoleBundle\Resolver\MerchantResolver; use Lc\CaracoleBundle\Resolver\MerchantResolver;
use Lc\SovBundle\Solver\Setting\SettingSolver;
use Mailjet\MailjetSwiftMailer\SwiftMailer\MailjetTransport; use Mailjet\MailjetSwiftMailer\SwiftMailer\MailjetTransport;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Twig\Environment; use Twig\Environment;
const ATTACHMENT_CONTENT_TYPE = 'attachment-content-type'; const ATTACHMENT_CONTENT_TYPE = 'attachment-content-type';
//const DISPOSITION_NOTIFICATION_TO = 'disposition-notification-to' ; //const DISPOSITION_NOTIFICATION_TO = 'disposition-notification-to' ;


protected $transport;
protected $templating;
protected $parameterBag;
protected $merchantResolver;
protected MailjetTransport $transport;
protected Environment $templating;
protected ParameterBagInterface $parameterBag;
protected MerchantResolver $merchantResolver;
protected SettingSolver $settingSolver;


public function __construct( public function __construct(
MailjetTransport $mailjetTransport, MailjetTransport $mailjetTransport,
Environment $templating, Environment $templating,
ParameterBagInterface $parameterBag, ParameterBagInterface $parameterBag,
MerchantResolver $merchantResolver
MerchantResolver $merchantResolver,
SettingSolver $settingSolver
) { ) {
$this->transport = $mailjetTransport; $this->transport = $mailjetTransport;
$this->templating = $templating; $this->templating = $templating;
$this->parameterBag = $parameterBag; $this->parameterBag = $parameterBag;
$this->merchantResolver = $merchantResolver; $this->merchantResolver = $merchantResolver;
$this->settingSolver = $settingSolver;
} }


public function send($params = []) public function send($params = [])
{ {
$merchantCurrent = $this->merchantResolver->getCurrent(); $merchantCurrent = $this->merchantResolver->getCurrent();


$merchantConfigEmailFrom = $merchantCurrent->getSettingValue(MerchantSettingDefinition::EMAIL_FROM);
$merchantConfigEmailFrom = $this->settingSolver->getSettingValue($merchantCurrent, MerchantSettingDefinition::SETTING_EMAIL_FROM);
$emailFrom = (isset($params[self::FROM_EMAIL]) && $params[self::FROM_EMAIL] && strlen($params[self::FROM_EMAIL])) ? $params[self::FROM_EMAIL] : $merchantConfigEmailFrom; $emailFrom = (isset($params[self::FROM_EMAIL]) && $params[self::FROM_EMAIL] && strlen($params[self::FROM_EMAIL])) ? $params[self::FROM_EMAIL] : $merchantConfigEmailFrom;


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


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


if ($this->parameterBag->get('mailjet.dev.redirect.active')==1) { if ($this->parameterBag->get('mailjet.dev.redirect.active')==1) {
$message->addTo($this->parameterBag->get('mailjet.dev.redirect.email'), $message->addTo($this->parameterBag->get('mailjet.dev.redirect.email'),
isset($params[self::TO_NAME]) ? $params[self::TO_NAME] : null);
isset($params[self::TO_NAME]) ?? null);
} else { } else {
$message->addTo( $message->addTo(
$params[self::TO_EMAIL], $params[self::TO_EMAIL],
isset($params[self::TO_NAME]) ? $params[self::TO_NAME] : null);
isset($params[self::TO_NAME]) ?? null);
} }


$contentData = [] ; $contentData = [] ;

+ 6
- 0
Repository/Address/AddressRepositoryQuery.php View File



use Knp\Component\Pager\PaginatorInterface; use Knp\Component\Pager\PaginatorInterface;
use Lc\CaracoleBundle\Repository\MerchantRepositoryQueryTrait; use Lc\CaracoleBundle\Repository\MerchantRepositoryQueryTrait;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Repository\AbstractRepositoryQuery; use Lc\SovBundle\Repository\AbstractRepositoryQuery;


class AddressRepositoryQuery extends AbstractRepositoryQuery class AddressRepositoryQuery extends AbstractRepositoryQuery
{ {
parent::__construct($repository, 'r', $paginator); parent::__construct($repository, 'r', $paginator);
} }

public function filterByUser(UserInterface $user)
{
return $this->andWhereEqual('user', $user);
}
} }

+ 9
- 0
Repository/Address/AddressStore.php View File

namespace Lc\CaracoleBundle\Repository\Address; namespace Lc\CaracoleBundle\Repository\Address;


use Lc\CaracoleBundle\Repository\MerchantStoreTrait; use Lc\CaracoleBundle\Repository\MerchantStoreTrait;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Repository\AbstractStore; use Lc\SovBundle\Repository\AbstractStore;
use Lc\SovBundle\Repository\RepositoryQueryInterface; use Lc\SovBundle\Repository\RepositoryQueryInterface;


{ {
return $query; return $query;
} }

public function getByUser(UserInterface $user)
{
$query = $this->createDefaultQuery();
$query->filterByUser($user);
return $query->find();
}

} }

+ 3
- 1
Repository/Order/OrderProductStore.php View File



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



+ 18
- 12
Repository/Order/OrderShopStore.php View File

use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface; use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditModel; use Lc\CaracoleBundle\Model\Reduction\ReductionCreditModel;
use Lc\CaracoleBundle\Repository\Merchant\MerchantStore; use Lc\CaracoleBundle\Repository\Merchant\MerchantStore;
use Lc\CaracoleBundle\Repository\Reduction\ReductionCartStore;
use Lc\CaracoleBundle\Repository\Reduction\ReductionCreditStore; use Lc\CaracoleBundle\Repository\Reduction\ReductionCreditStore;
use Lc\CaracoleBundle\Repository\Section\SectionStore; use Lc\CaracoleBundle\Repository\Section\SectionStore;
use Lc\CaracoleBundle\Resolver\OpeningResolver; use Lc\CaracoleBundle\Resolver\OpeningResolver;
protected ParameterBagInterface $parameterBag; protected ParameterBagInterface $parameterBag;
protected UrlGeneratorInterface $router; protected UrlGeneratorInterface $router;
protected OrderShopSolver $orderShopSolver; protected OrderShopSolver $orderShopSolver;
protected ReductionCartStore $reductionCartStore;


public function __construct( public function __construct(
OrderShopRepositoryQuery $query, OrderShopRepositoryQuery $query,
FlashBagInterface $flashBag, FlashBagInterface $flashBag,
ParameterBagInterface $parameterBag, ParameterBagInterface $parameterBag,
UrlGeneratorInterface $router, UrlGeneratorInterface $router,
OrderShopSolver $orderShopSolver
OrderShopSolver $orderShopSolver,
ReductionCartStore $reductionCartStore
) { ) {
$this->query = $query; $this->query = $query;
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->parameterBag = $parameterBag; $this->parameterBag = $parameterBag;
$this->router = $router; $this->router = $router;
$this->orderShopSolver = $orderShopSolver; $this->orderShopSolver = $orderShopSolver;
$this->reductionCartStore = $reductionCartStore;
} }


public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
} }


// getOrderShopsOfWeekByUser // getOrderShopsOfWeekByUser
public function getByCurrentCycleAndUser(UserInterface $user, array $params = [], $query = null)
public function getByCurrentCycleAndUser(UserInterface $user = null, array $params = [], $query = null)
{ {
return $this->getByCurrentCycle( return $this->getByCurrentCycle(
array_merge( array_merge(
public function countByCurrentCycle(array $params, $query = null) public function countByCurrentCycle(array $params, $query = null)
{ {
return $this->countBy( return $this->countBy(
[
'cycleNumber' => $this->orderShopSolver->getCycleNumberCurrentOrder($this->section),
'excludeComplementaryOrderShops' => isset($params['excludeComplementaryOrderShops']) ?? true,
],
array_merge(
[
'cycleNumber' => $this->orderShopSolver->getCycleNumberCurrentOrder($this->section),
'excludeComplementaryOrderShops' => isset($params['excludeComplementaryOrderShops']) ?? true,
],
$params
),
$query $query
); );


); );
} }


public function countValidByUser(UserInterface $user, $query = null): int
public function countValidByUser(UserInterface $user = null, $query = null): int
{ {
return $this->countBy( return $this->countBy(
[ [
// findAllAvailableForUser / getReductionCartsAvailableByUser // findAllAvailableForUser / getReductionCartsAvailableByUser
public function getReductionCartAvailableByUser(UserInterface $user, $query = null) public function getReductionCartAvailableByUser(UserInterface $user, $query = null)
{ {
$query = $this->createQuery($query);
$reductionCarts = $query->find();
$reductionCarts = $this->reductionCartStore->getOnline();


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

+ 5
- 0
Repository/Order/OrderStatusRepositoryQuery.php View File

{ {
parent::__construct($repository, 'r', $paginator); parent::__construct($repository, 'r', $paginator);
} }

public function filterByAlias(string $alias)
{
return $this->andWhereEqual('alias', $alias);
}
} }

+ 7
- 0
Repository/Order/OrderStatusStore.php View File

{ {
return $query; return $query;
} }

public function getOneByAlias(string $alias, $query = null)
{
$query = $this->createDefaultQuery($query);
$query->filterByAlias($alias);
return $query->findOne();
}
} }

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



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

return $query; return $query;
} }



+ 2
- 1
Repository/Reduction/ReductionCartRepositoryQuery.php View File



use Knp\Component\Pager\PaginatorInterface; use Knp\Component\Pager\PaginatorInterface;
use Lc\CaracoleBundle\Repository\MerchantRepositoryQueryTrait; use Lc\CaracoleBundle\Repository\MerchantRepositoryQueryTrait;
use Lc\CaracoleBundle\Repository\SectionRepositoryQueryTrait;
use Lc\SovBundle\Repository\AbstractRepositoryQuery; use Lc\SovBundle\Repository\AbstractRepositoryQuery;


class ReductionCartRepositoryQuery extends AbstractRepositoryQuery class ReductionCartRepositoryQuery extends AbstractRepositoryQuery
{ {
use MerchantRepositoryQueryTrait;
use SectionRepositoryQueryTrait;


public function __construct(ReductionCartRepository $repository, PaginatorInterface $paginator) public function __construct(ReductionCartRepository $repository, PaginatorInterface $paginator)
{ {

+ 3
- 1
Repository/Reduction/ReductionCartStore.php View File



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

+ 3
- 1
Repository/Reduction/ReductionCatalogStore.php View File



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

+ 2
- 1
Repository/Reduction/ReductionCreditRepositoryQuery.php View File

use Knp\Component\Pager\PaginatorInterface; use Knp\Component\Pager\PaginatorInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditModel; use Lc\CaracoleBundle\Model\Reduction\ReductionCreditModel;
use Lc\CaracoleBundle\Repository\MerchantRepositoryQueryTrait; use Lc\CaracoleBundle\Repository\MerchantRepositoryQueryTrait;
use Lc\CaracoleBundle\Repository\SectionRepositoryQueryTrait;
use Lc\SovBundle\Model\User\UserInterface; use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Repository\AbstractRepositoryQuery; use Lc\SovBundle\Repository\AbstractRepositoryQuery;


class ReductionCreditRepositoryQuery extends AbstractRepositoryQuery class ReductionCreditRepositoryQuery extends AbstractRepositoryQuery
{ {
use MerchantRepositoryQueryTrait;
use SectionRepositoryQueryTrait;


public function __construct(ReductionCreditRepository $repository, PaginatorInterface $paginator) public function __construct(ReductionCreditRepository $repository, PaginatorInterface $paginator)
{ {

+ 3
- 1
Repository/Reduction/ReductionCreditStore.php View File



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

+ 53
- 0
Resolver/OrderShopResolver.php View File

<?php

namespace Lc\CaracoleBundle\Resolver;

use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Solver\Order\OrderShopSolver;
use Lc\CaracoleBundle\Solver\Price\PriceSolver;

class OrderShopResolver
{
protected PriceSolver $priceSolver;
protected OrderShopSolver $orderShopSolver;

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

public function getTotalRemainingToBePaid(OrderShopInterface $orderShop): float
{
return $this->priceSolver->getTotalWithTax($orderShop) - $this->orderShopSolver->getTotalOrderPayments(
$orderShop
);
}

// isOrderShopPositiveAmount
public function isPositiveAmount(OrderShopInterface $orderShop): bool
{
return $this->priceSolver->getTotalWithTax($orderShop) >= 0;
}

public function isPaid(OrderShopInterface $orderShop, $mergeComplementaryOrderShop = false): bool
{
$totalOrderPayments = $this->orderShopSolver->getTotalOrderPayments($orderShop, $mergeComplementaryOrderShop);
$totalOrder = $this->priceSolver->getTotalWithTax($orderShop);

if ((abs($totalOrderPayments - $totalOrder) < 0.00001
|| $totalOrderPayments >= $totalOrder)
&& $totalOrder > 0) {
return true;
} else {
return false;
}
}

// isOrderShopPositiveAmountRemainingToBePaid
public function isPositiveAmountRemainingToBePaid(OrderShopInterface $orderShop): bool
{
return $this->getTotalRemainingToBePaid($orderShop) > 0;
}

}

+ 107
- 0
Resolver/ProductFamilyResolver.php View File

<?php

namespace Lc\CaracoleBundle\Resolver;

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

class ProductFamilyResolver
{
protected PriceSolver $priceSolver;
protected ProductFamilySolver $productFamilySolver;

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

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

public function getCheapestProduct(ProductFamilyInterface $productFamily)
{
$priceSolver = $this->priceSolver;

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

public function getCheapestProductByRefUnit(ProductFamilyInterface $productFamily)
{
$priceSolver = $this->priceSolver;

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

public function getMostExpensiveProductByRefUnit(ProductFamilyInterface $productFamily)
{
$priceSolver = $this->priceSolver;

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

private function getCheapestOrMostExpensiveProduct(
ProductFamilyInterface $productFamily,
$comparisonFunction,
$returnSelfIfNotActiveProducts
) {
if ($productFamily->getActiveProducts()) {
$products = $this->productFamilySolver->getProductsOnline($productFamily)->getValues();
if (count($products) > 0) {
usort($products, $comparisonFunction);
return $products[0];
}
} else {
return $this->productFamilySolver->getOriginProduct($productFamily);
}
if ($returnSelfIfNotActiveProducts) {
return $productFamily;
} else {
return false;
}
}
}

+ 34
- 8
Resolver/SectionResolver.php View File

protected MerchantResolver $merchantResolver; protected MerchantResolver $merchantResolver;
protected SectionStore $sectionStore; protected SectionStore $sectionStore;
protected RequestStack $requestStack; protected RequestStack $requestStack;
protected UrlResolver $urlResolver;


public function __construct(EntityManagerInterface $entityManager, MerchantResolver $merchantResolver, SectionStore $sectionStore, RequestStack $requestStack)
{
public function __construct(
EntityManagerInterface $entityManager,
MerchantResolver $merchantResolver,
SectionStore $sectionStore,
RequestStack $requestStack,
UrlResolver $urlResolver
) {
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->merchantResolver = $merchantResolver; $this->merchantResolver = $merchantResolver;
$this->sectionStore = $sectionStore; $this->sectionStore = $sectionStore;
$this->requestStack = $requestStack; $this->requestStack = $requestStack;
$this->urlResolver = $urlResolver;
} }


public function getCurrent() public function getCurrent()
$requestAttributesArray = $this->requestStack->getMainRequest()->attributes->all(); $requestAttributesArray = $this->requestStack->getMainRequest()->attributes->all();


// admin // admin
if(isset($requestAttributesArray['easyadmin_context'])) {
if (isset($requestAttributesArray['easyadmin_context'])) {
$currentAdminSection = null; $currentAdminSection = null;
$userMerchant = $this->merchantResolver->getUserMerchant(); $userMerchant = $this->merchantResolver->getUserMerchant();


} }


return $currentAdminSection; return $currentAdminSection;
}
// front
} // front
else { else {
return $this->sectionStore
->setMerchant($this->merchantResolver->getCurrent())
->getOneDefault();
$sectionCurrent = null;
$isCli = php_sapi_name() === 'cli';

// local
if ($isCli || $this->urlResolver->isServerLocalhost()) {
$sectionArray = $this->sectionStore
->setMerchant($this->merchantResolver->getCurrent())
->getOnline();

foreach ($sectionArray as $section) {
if ($section->getDevAlias() == $_ENV['CURRENT_SECTION_LOCAL']) {
$sectionCurrent = $section;
}
}
}
// distant
else {
$sectionCurrent = $this->sectionStore
->setMerchant($this->merchantResolver->getCurrent())
->getOneDefault();
}

return $sectionCurrent;
} }
} }



+ 3
- 1
Resources/translations/admin.fr.yaml View File

behaviorTaxRateChoices: behaviorTaxRateChoices:
tax-excluded: TVA exclue tax-excluded: TVA exclue
tax-included: Tva incluse tax-included: Tva incluse

PointSale: PointSale:
label: Point de vente label: Point de vente
label_plurial: Points de vente label_plurial: Points de vente
individual: Particulier individual: Particulier
civility: Civilité civility: Civilité
zip: Code postal zip: Code postal
city: Ville
city: Commune
address: Adresse address: Adresse
phone: Téléphone phone: Téléphone
company: Entreprise company: Entreprise
siret: SIRET siret: SIRET
tva: Numero de TVA tva: Numero de TVA

Merchant: Merchant:
label: Marchand label: Marchand
label_plurial: Marchands label_plurial: Marchands

+ 78
- 0
Solver/Credit/CreditHistorySolver.php View File

<?php

namespace Lc\CaracoleBundle\Solver\Credit;

use Lc\CaracoleBundle\Model\Credit\CreditHistoryInterface;

class CreditHistorySolver
{
public function getMeanPaymentInheritedLabel(CreditHistoryInterface $creditHistory): string
{
return 'entity.CreditHistory.fields.meanPaymentOptions.' . $this->getMeanPaymentInherited($creditHistory);
}

public function getAmountInherited(CreditHistoryInterface $creditHistory): float
{
if ($creditHistory->getOrderPayment() !== null) {
return $creditHistory->getOrderPayment()->getAmount();
} else {
if ($creditHistory->getOrderRefund() !== null) {
return $creditHistory->getOrderRefund()->getAmount();
} else {
return $creditHistory->getAmount();
}
}
}

public function getMeanPaymentInherited(CreditHistoryInterface $creditHistory): string
{
if ($creditHistory->getOrderPayment() !== null) {
return $creditHistory->getOrderPayment()->getMeanPayment();
} else {
if ($creditHistory->getOrderRefund() !== null) {
return $creditHistory->getOrderRefund()->getMeanPayment();
} else {
return $creditHistory->getMeanPayment();
}
}
}

public function getPaidAtInherited(CreditHistoryInterface $creditHistory): ?\DateTimeInterface
{
if ($creditHistory->getOrderPayment() !== null) {
return $creditHistory->getOrderPayment()->getPaidAt();
} else {
if ($creditHistory->getOrderRefund() !== null) {
return $creditHistory->getOrderRefund()->getPaidAt();
} else {
return $creditHistory->getPaidAt();
}
}
}

public function getReferenceInherited(CreditHistoryInterface $creditHistory): ?string
{
if ($creditHistory->getOrderPayment() !== null) {
return $creditHistory->getOrderPayment()->getReference();
} else {
if ($creditHistory->getOrderRefund() !== null) {
return $creditHistory->getOrderRefund()->getReference();
} else {
return $creditHistory->getReference();
}
}
}

public function getCommentInherited(CreditHistoryInterface $creditHistory): ?string
{
if ($creditHistory->getOrderPayment() !== null) {
return $creditHistory->getOrderPayment()->getComment();
} else {
if ($creditHistory->getOrderRefund() !== null) {
return $creditHistory->getOrderRefund()->getComment();
} else {
return $creditHistory->getComment();
}
}
}
}

+ 65
- 0
Solver/Order/OrderProductSolver.php View File



namespace Lc\CaracoleBundle\Solver\Order; namespace Lc\CaracoleBundle\Solver\Order;


use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver;

class OrderProductSolver class OrderProductSolver
{ {
protected ProductSolver $productSolver;
protected ProductFamilySolver $productFamilySolver;

public function __construct(ProductSolver $productSolver, ProductFamilySolver $productFamilySolver)
{
$this->productSolver = $productSolver;
$this->productFamilySolver = $productFamilySolver;
}

// groupOrderProductsByProductFamily // groupOrderProductsByProductFamily
public function getOrderProductsByProductFamily(array $orderProducts): array public function getOrderProductsByProductFamily(array $orderProducts): array
{ {


return $orderProductsByStorageOrder; return $orderProductsByStorageOrder;
} }

public function getTitleOrderShop(OrderProductInterface $orderProduct)
{
$product = $orderProduct->getProduct();
$productFamily = $product->getProductFamily();

$titleProduct = $product->getTitle();
$titleProductFamily = $productFamily->getTitle();

if (strlen($titleProduct) > 0 && strlen($titleProductFamily) > 0) {
$title = $titleProductFamily . ' - ' . $titleProduct;
} else {
$title = strlen($titleProduct) ? $titleProduct : $titleProductFamily;
}

if ($this->productFamilySolver->hasProductsWithVariousWeight($productFamily)) {
$title .= ' - ' . $this->productSolver->getQuantityLabelInherited($product);
}

return $title;
}

public function getTitleSummaryAfterAddCart(OrderProductInterface $orderProduct)
{
$title = '';

$product = $orderProduct->getProduct();
$productFamily = $product->getProductFamily();
$titleProduct = $this->productSolver->getTitleInherited($product);
$titleProductFamily = $productFamily->getTitle();

// multiple
if ($productFamily->getActiveProducts() && $productFamily->getBehaviorAddToCart() == 'multiple') {
$title .= $titleProduct;
if ($this->productFamilySolver->hasProductsWithVariousWeight($productFamily)) {
$title .= ' - ' . $this->productSolver->getQuantityLabelInherited($product);
}
}

// simple
if ($productFamily->getBehaviorAddToCart() == 'simple') {
if ($productFamily->getActiveProducts()) {
$title .= $titleProduct;
if ($this->productFamilySolver->hasProductsWithVariousWeight($productFamily)) {
$title .= ' - ' . $this->productSolver->getQuantityLabelInherited($product);
}
}
}

return $title;
}
} }

+ 41
- 41
Solver/Order/OrderShopSolver.php View File

use Lc\CaracoleBundle\Model\Product\ProductFamilyModel; use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
use Lc\CaracoleBundle\Model\Product\ProductInterface; use Lc\CaracoleBundle\Model\Product\ProductInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface; use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
use Lc\CaracoleBundle\Solver\Price\PriceSolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver; use Lc\CaracoleBundle\Solver\Product\ProductSolver;


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


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


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


// @TODO : orderShop à définir où est appelé isAvailable
if ($checkCart && !$orderShop) { if ($checkCart && !$orderShop) {
throw new \Exception("Attention : définir le orderShop à l'endroit où est appelé isAvailable"); throw new \Exception("Attention : définir le orderShop à l'endroit où est appelé isAvailable");
} }
if (!$quantityOrder) { if (!$quantityOrder) {
$quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product, true); $quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product, true);
} else { } else {
$quantityAsked = ($product->getQuantityInherited() / $product->getUnitInherited()->getCoefficient()) * $quantityOrder;
$quantityAsked = ($this->productSolver->getQuantityInherited(
$product
) / $this->productSolver->getUnitInherited($product)->getCoefficient(
)) * $quantityOrder;
} }


if ($checkCart) { if ($checkCart) {


if (($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY 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) { if (!$quantityOrder) {
$quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product); $quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product);
} }
} }
} }


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


public function isOrderProductAvailableAddCart(OrderProductInterface $orderProduct, OrderShopInterface $orderShop)
{
return $this->isProductAvailable(
$orderProduct->getProduct(),
$orderProduct->getQuantityOrder(),
true,
$orderShop
);
}

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


public function getTotalRemainingToBePaid(OrderShopInterface $orderShop): float
{
return $this->priceSolver->getTotalWithTax($orderShop) - $this->getTotalOrderPayments($orderShop);
}

public function getOrderStatusHistory(OrderShopInterface $orderShop, OrderStatusInterface $status) public function getOrderStatusHistory(OrderShopInterface $orderShop, OrderStatusInterface $status)
{ {
$orderStatusHistories = $orderShop->getOrderStatusHistories(); $orderStatusHistories = $orderShop->getOrderStatusHistories();


public function isComplementaryOrderShop(OrderShopInterface $orderShop): bool public function isComplementaryOrderShop(OrderShopInterface $orderShop): bool
{ {
return (bool) $orderShop->getMainOrderShop();
return (bool)$orderShop->getMainOrderShop();
} }


public function mergeComplentaryOrderShops( public function mergeComplentaryOrderShops(
} }





public function hasOrderProductAlreadyInCart( public function hasOrderProductAlreadyInCart(
OrderShopInterface $orderShop, OrderShopInterface $orderShop,
OrderProductInterface $orderProductTest OrderProductInterface $orderProductTest
return false; return false;
} }


// isOrderShopPositiveAmount
public function isPositiveAmount(OrderShopInterface $orderShop): bool
public function isCartAllowToBeOrder(OrderShopInterface $orderShop): bool
{ {
return $this->priceSolver->getTotalWithTax($orderShop) >= 0;
return true;
} }


public function isPaid(OrderShopInterface $orderShop, $mergeComplementaryOrderShop = false): bool
// getProductQuantityMaxAddCart
public function getProductQuantityMaxAddCart(ProductInterface $product, OrderShopInterface $orderShop)
{ {
$totalOrderPayments = $this->getTotalOrderPayments($orderShop, $mergeComplementaryOrderShop);
$totalOrder = $this->priceSolver->getTotalWithTax($orderShop);
$productFamily = $product->getProductFamily();


if ((abs($totalOrderPayments - $totalOrder) < 0.00001
|| $totalOrderPayments >= $totalOrder)
&& $totalOrder > 0) {
return true;
} else {
return false;
$byWeight = false;
if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
$byWeight = true;
} }
}


// isOrderShopPositiveAmountRemainingToBePaid
public function isPositiveAmountRemainingToBePaid(OrderShopInterface $orderShop): bool
{
return $this->getTotalRemainingToBePaid($orderShop) > 0;
}

public function isCartAllowToBeOrder(OrderShopInterface $orderShop): bool
{
return true;
return $this->productSolver->getAvailableQuantityInherited($product) - $this->getQuantityOrderByProduct(
$orderShop,
$product,
$byWeight
);
} }
} }

+ 14
- 5
Solver/Price/OrderProductPriceSolver.php View File

namespace Lc\CaracoleBundle\Solver\Price; namespace Lc\CaracoleBundle\Solver\Price;


use Lc\CaracoleBundle\Model\Order\OrderProductInterface; use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver;


class OrderProductPriceSolver class OrderProductPriceSolver
{ {
use PriceSolverTrait; use PriceSolverTrait;


protected $productPriceResolver;

public function __construct(ProductPriceSolver $ProductPriceResolver)
{
$this->productPriceResolver = $ProductPriceResolver;
protected ProductSolver $productSolver;
protected ProductFamilySolver $productFamilySolver;
protected ProductPriceSolver $productPriceSolver;

public function __construct(
ProductPriceSolver $productPriceSolver,
ProductSolver $productSolver,
ProductFamilySolver $productFamilySolver
) {
$this->productPriceSolver = $productPriceSolver;
$this->productSolver = $productSolver;
$this->productFamilySolver = $productFamilySolver;
} }


public function getPrice(OrderProductInterface $orderProduct, $round = false) public function getPrice(OrderProductInterface $orderProduct, $round = false)

+ 11
- 3
Solver/Price/OrderShopPriceSolver.php View File

use Lc\CaracoleBundle\Model\Order\OrderReductionCreditInterface; use Lc\CaracoleBundle\Model\Order\OrderReductionCreditInterface;
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Model\Reduction\ReductionCartModel; use Lc\CaracoleBundle\Model\Reduction\ReductionCartModel;
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditModel;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver;


class OrderShopPriceSolver class OrderShopPriceSolver
{ {
use PriceSolverTrait; use PriceSolverTrait;


protected OrderProductPriceSolver $orderProductPriceResolver; protected OrderProductPriceSolver $orderProductPriceResolver;
protected ProductSolver $productSolver;
protected ProductFamilySolver $productFamilySolver;


public function __construct(OrderProductPriceSolver $orderProductPriceResolver)
{
public function __construct(
OrderProductPriceSolver $orderProductPriceResolver,
ProductSolver $productSolver,
ProductFamilySolver $productFamilySolver
) {
$this->orderProductPriceResolver = $orderProductPriceResolver; $this->orderProductPriceResolver = $orderProductPriceResolver;
$this->productSolver = $productSolver;
$this->productFamilySolver = $productFamilySolver;
} }


//Inclus les ReductionCatalog des OrderProducts //Inclus les ReductionCatalog des OrderProducts

+ 2
- 2
Solver/Price/PriceSolver.php View File

} }
} else { } else {
if (!strlen($service)) { if (!strlen($service)) {
throw new \ErrorException("PriceResolver : le type d'entité n'est pas géré");
throw new \ErrorException("PriceSolver : le type d'entité n'est pas géré");
} else { } else {
if (!method_exists($this->$service, $name)) { if (!method_exists($this->$service, $name)) {
throw new \ErrorException( throw new \ErrorException(
"PriceResolver : la méthode " . $name . " du service " . $service . " n'existe pas."
"PriceSolver : la méthode " . $name . " du service " . $service . " n'existe pas."
); );
} }
} }

+ 13
- 7
Solver/Price/PriceSolverTrait.php View File



use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface; use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface;
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Model\Product\ProductInterface;


trait PriceSolverTrait trait PriceSolverTrait
{ {
$reductionCatalogUnit = $reductionCatalog->getUnit(); $reductionCatalogUnit = $reductionCatalog->getUnit();
$reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate(); $reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate();
} else { } else {
if ($entity instanceof ProductPropertyInterface) {
$reductionCatalog = $entity->getReductionCatalogInherited();
if ($entity instanceof ProductInterface) {
$reductionCatalog = $this->productSolver->getReductionCatalogInherited($entity);
}


if ($reductionCatalog) {
$reductionCatalogValue = $reductionCatalog->getValue();
$reductionCatalogUnit = $reductionCatalog->getUnit();
$reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate();
}
if ($entity instanceof ProductFamilyInterface) {
$reductionCatalog = $this->productFamilySolver->getReductionCatalogInherited($entity);
}

if ($reductionCatalog) {
$reductionCatalogValue = $reductionCatalog->getValue();
$reductionCatalogUnit = $reductionCatalog->getUnit();
$reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate();
} }


if ($entity instanceof OrderProductInterface) { if ($entity instanceof OrderProductInterface) {

+ 52
- 22
Solver/Price/ProductPriceSolver.php View File

namespace Lc\CaracoleBundle\Solver\Price; namespace Lc\CaracoleBundle\Solver\Price;


use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface; use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Model\Product\ProductInterface;
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver;
use Lc\CaracoleBundle\Solver\Product\ProductSolver;


class ProductPriceSolver class ProductPriceSolver
{ {
use PriceSolverTrait; use PriceSolverTrait;


protected ProductSolver $productSolver;
protected ProductFamilySolver $productFamilySolver;

public function __construct(ProductSolver $productSolver, ProductFamilySolver $productFamilySolver)
{
$this->productSolver = $productSolver;
$this->productFamilySolver = $productFamilySolver;
}

public function getSolver(ProductPropertyInterface $product)
{
if($product instanceof ProductFamilyInterface) {
return $this->productFamilySolver;
}

if($product instanceof ProductInterface) {
return $this->productSolver;
}
}

public function getPrice(ProductPropertyInterface $product) public function getPrice(ProductPropertyInterface $product)
{ {
if ($product->getBehaviorPriceInherited() == 'by-piece') {
return $product->getPriceInherited();
} elseif ($product->getBehaviorPriceInherited() == 'by-reference-unit') {
if ($product->getQuantityInherited() > 0) {
return $product->getPriceByRefUnitInherited() * ($product->getQuantityInherited(
) / $product->getUnitInherited()->getCoefficient());
$solver = $this->getSolver($product);

if ($solver->getBehaviorPriceInherited($product) == 'by-piece') {
return $solver->getPriceInherited($product);
} elseif ($solver->getBehaviorPriceInherited($product) == 'by-reference-unit') {
if ($solver->getQuantityInherited($product) > 0) {
return $solver->getPriceByRefUnitInherited($product) * ($solver->getQuantityInherited($product
) / $solver->getUnitInherited($product)->getCoefficient());
} else { } else {
return 0; return 0;
} }
{ {
return $this->applyTax( return $this->applyTax(
$this->getPrice($product), $this->getPrice($product),
$product->getTaxRateInherited()->getValue()
$this->productFamilySolver->getTaxRateInherited($product)->getValue()
); );
} }




public function getPriceByRefUnit(ProductPropertyInterface $product) public function getPriceByRefUnit(ProductPropertyInterface $product)
{ {
if ($product->getBehaviorPriceInherited() == 'by-piece') {
return ($this->getPrice($product) * $product->getUnitInherited()->getCoefficient(
)) / $product->getQuantityInherited();
} elseif ($product->getBehaviorPriceInherited() == 'by-reference-unit') {
return $product->getPriceByRefUnitInherited();
$solver = $this->getSolver($product);

if ($solver->getBehaviorPriceInherited($product) == 'by-piece') {
return ($this->getPrice($product) * $solver->getUnitInherited($product)->getCoefficient(
)) / $solver->getQuantityInherited($product);
} elseif ($solver->getBehaviorPriceInherited($product) == 'by-reference-unit') {
return $solver->getPriceByRefUnitInherited($product);
} }
} }


{ {
return $this->applyTax( return $this->applyTax(
$this->getPriceByRefUnit($product), $this->getPriceByRefUnit($product),
$product->getTaxRateInherited()->getValue()
$this->productFamilySolver->getTaxRateInherited($product)->getValue()
); );
} }




public function getBuyingPrice(ProductPropertyInterface $product) public function getBuyingPrice(ProductPropertyInterface $product)
{ {
if ($product->getBehaviorPriceInherited() == 'by-piece') {
return $product->getBuyingPriceInherited();
} elseif ($product->getBehaviorPriceInherited() == 'by-reference-unit') {
if ($product->getQuantityInherited() > 0) {
return $product->getBuyingPriceByRefUnitInherited() * ($product->getQuantityInherited(
) / $product->getUnitInherited()->getCoefficient());
$solver = $this->getSolver($product);

if ($solver->getBehaviorPriceInherited($product) == 'by-piece') {
return $solver->getBuyingPriceInherited($product);
} elseif ($solver->getBehaviorPriceInherited($product) == 'by-reference-unit') {
if ($solver->getQuantityInherited($product) > 0) {
return $solver->getBuyingPriceByRefUnitInherited($product) * ($solver->getQuantityInherited($product
) / $solver->getUnitInherited($product)->getCoefficient());
} else { } else {
return 0; return 0;
} }
{ {
return $this->applyTax( return $this->applyTax(
$this->getBuyingPrice($product), $this->getBuyingPrice($product),
$product->getTaxRateInherited()->getValue()
$this->productFamilySolver->getTaxRateInherited($product)->getValue()
); );
} }


public function getBuyingPriceByRefUnit(ProductPropertyInterface $product) public function getBuyingPriceByRefUnit(ProductPropertyInterface $product)
{ {
return $product->getBuyingPriceByRefUnitInherited();
return $this->getSolver($product)->getBuyingPriceByRefUnitInherited($product);
} }


public function getBuyingPriceByRefUnitWithTax(ProductPropertyInterface $product) public function getBuyingPriceByRefUnitWithTax(ProductPropertyInterface $product)
{ {
return $this->applyTax( return $this->applyTax(
$this->getBuyingPriceByRefUnit($product), $this->getBuyingPriceByRefUnit($product),
$product->getTaxRateInherited()->getValue()
$this->productFamilySolver->getTaxRateInherited($product)->getValue()
); );
} }



+ 35
- 99
Solver/Product/ProductFamilySolver.php View File



use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyModel; use Lc\CaracoleBundle\Model\Product\ProductFamilyModel;
use Lc\CaracoleBundle\Model\Product\ProductInterface; use Lc\CaracoleBundle\Model\Product\ProductInterface;


class ProductFamilySolver class ProductFamilySolver
{ {
protected PriceSolver $priceSolver;


public function __construct(PriceSolver $priceSolver)
{
$this->priceSolver = $priceSolver;
}

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

public function getCheapestProduct(ProductFamilyInterface $productFamily)
{
$priceSolver = $this->priceSolver;

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

public function getCheapestProductByRefUnit(ProductFamilyInterface $productFamily)
{
$priceSolver = $this->priceSolver;

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


public function getMostExpensiveProductByRefUnit(ProductFamilyInterface $productFamily)
public function __construct(ProductSolver $productSolver)
{ {
$priceSolver = $this->priceSolver;

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

private function getCheapestOrMostExpensiveProduct(
ProductFamilyInterface $productFamily,
$comparisonFunction,
$returnSelfIfNotActiveProducts
) {
if ($productFamily->getActiveProducts()) {
$products = $this->getProductsOnline($productFamily)->getValues();
if (count($products) > 0) {
usort($products, $comparisonFunction);
return $products[0];
}
} else {
return $this->getOriginProduct($productFamily);
}
if ($returnSelfIfNotActiveProducts) {
return $productFamily;
} else {
return false;
}
$this->productSolver = $productSolver;
} }



public function getAvailableQuantityInherited(ProductFamilyInterface $productFamily) public function getAvailableQuantityInherited(ProductFamilyInterface $productFamily)
{ {
$availableQuantity = 0; $availableQuantity = 0;
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT : case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :


foreach ($this->getProductsOnline($productFamily) as $product) { foreach ($this->getProductsOnline($productFamily) as $product) {
$availableQuantity += $product->getAvailableQuantityInherited();
$availableQuantity += $this->productSolver->getAvailableQuantityInherited($product);
} }
break; break;


return $availableQuantity; return $availableQuantity;
} }



public function getTaxRateInherited(ProductFamilyInterface $productFamily)
public function getTaxRateInherited(ProductPropertyInterface $productFamily)
{ {
if($productFamily instanceof ProductInterface) {
$productFamily = $productFamily->getProductFamily();
}

if ($productFamily->getTaxRate()) { if ($productFamily->getTaxRate()) {
return $productFamily->getTaxRate(); return $productFamily->getTaxRate();
} else { } else {
} }
} }



public function getProductsOnline(ProductFamilyInterface $productFamily): Collection public function getProductsOnline(ProductFamilyInterface $productFamily): Collection
{ {
$products = $productFamily->getProducts(); $products = $productFamily->getProducts();
return $arrayProductsGroupByTitle; return $arrayProductsGroupByTitle;
} }



public function getOriginProduct(ProductFamilyInterface $productFamily): ?ProductInterface public function getOriginProduct(ProductFamilyInterface $productFamily): ?ProductInterface
{ {
$products = $productFamily->getProducts(); $products = $productFamily->getProducts();
return null; return null;
} }



public function getOriginProductOnline(ProductFamilyInterface $productFamily): ?ProductInterface public function getOriginProductOnline(ProductFamilyInterface $productFamily): ?ProductInterface
{ {
$originProduct = $this->getOriginProduct($productFamily); $originProduct = $this->getOriginProduct($productFamily);
} }
} }



public function hasOneProductOnline(ProductFamilyInterface $productFamily) public function hasOneProductOnline(ProductFamilyInterface $productFamily)
{ {
if (($productFamily->getActiveProducts() && count($this->getProductsOnline($productFamily)) > 0) if (($productFamily->getActiveProducts() && count($this->getProductsOnline($productFamily)) > 0)
return false; return false;
} }



public function getFieldBuyingPrice(ProductFamilyInterface $productFamily): string public function getFieldBuyingPrice(ProductFamilyInterface $productFamily): string
{ {
if ($productFamily->getBehaviorPrice() === ProductFamilyModel::BEHAVIOR_PRICE_BY_PIECE) { if ($productFamily->getBehaviorPrice() === ProductFamilyModel::BEHAVIOR_PRICE_BY_PIECE) {
} }
} }



public function getFieldPrice(ProductFamilyInterface $productFamily): string public function getFieldPrice(ProductFamilyInterface $productFamily): string
{ {
if ($productFamily->getBehaviorPrice() === ProductFamilyModel::BEHAVIOR_PRICE_BY_PIECE) { if ($productFamily->getBehaviorPrice() === ProductFamilyModel::BEHAVIOR_PRICE_BY_PIECE) {
]; ];
} }


public function getBuyingPriceByRefUnitInherited(ProductFamilyInterface $productFamily): ?float
{
return $productFamily->getBuyingPriceByRefUnit();
}

public function getPriceByRefUnitInherited(ProductFamilyInterface $productFamily): ?float
{
return $productFamily->getPriceByRefUnit();
}

public function getQuantityInherited(ProductFamilyInterface $productFamily): ?float
{
return $productFamily->getQuantity();
}

public function getUnitInherited(ProductFamilyInterface $productFamily)
{
return $productFamily->getUnit();
}

public function getPriceInherited(ProductFamilyInterface $productFamily)
{
return $productFamily->getPrice();
}

} }



+ 148
- 0
Solver/Product/ProductSolver.php View File



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


return true; return true;
} }


// getProductQuantity
public function getProductQuantity(ProductInterface $product)
{
$productFamily = $product->getProductFamily();

if ($productFamily->getBehaviorCountStock() == ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
return $this->getQuantityInherited($product) / $this->getUnitInherited($product)->getCoefficient();
} else {
return 1;
}
}

public function getBuyingPriceInherited(ProductInterface $product)
{
if ($product->getBuyingPrice()) {
return $product->getBuyingPrice();
} else {
return $product->getProductFamily()->getBuyingPrice();
}
}

public function getBuyingPriceByRefUnitInherited(ProductInterface $product)
{
if ($product->getBuyingPriceByRefUnit()) {
return $product->getBuyingPriceByRefUnit();
} else {
return $product->getProductFamily()->getBuyingPriceByRefUnit();
}
}

public function getPriceInherited(ProductInterface $product)
{
if ($product->getPrice()) {
return $product->getPrice();
} else {
return $product->getProductFamily()->getPrice();
}
}

public function getPriceByRefUnitInherited(ProductInterface $product)
{
if ($product->getPriceByRefUnit()) {
return $product->getPriceByRefUnit();
} else {
return $product->getProductFamily()->getPriceByRefUnit();
}
}

public function getBehaviorPriceInherited(ProductInterface $product)
{
return $product->getProductFamily()->getBehaviorPrice();
}

public function getReductionCatalogInherited(ProductInterface $product)
{
return $product->getProductFamily()->getReductionCatalog();
}

public function getUnitInherited(ProductInterface $product)
{
if ($product->getUnit()) {
return $product->getUnit();
} else {
return $product->getProductFamily()->getUnit();
}
}


public function getTitleInherited(ProductInterface $product)
{
if ($product->getTitle()) {
return $product->getTitle();
} else {
return $product->getProductFamily()->getTitle();
}
}

public function getQuantityInherited(ProductInterface $product)
{
if ($product->getQuantity()) {
return $product->getQuantity();
} else {
return $product->getProductFamily()->getQuantity();
}
}

public function getQuantityLabelInherited(ProductInterface $product)
{
$quantity = $product->getQuantityInherited();
$unit = $product->getUnitInherited();
return $quantity . $unit->getWordingShort();
}

// @TODO : si besoin, à remettre en place
/*public function getQuantityTitle(ProductInterface $product, ProductFamilyInterface $productFamily)
{
$title = $product->getQuantityLabelInherited();
if ($this->productFamilySolver->hasProductsWithVariousWeight($productFamily)) {
$title .= ', ' . $product->getTitleInherited();
}
return $title;
}*/

public function getAvailableQuantityInherited(ProductInterface $product)
{
switch ($product->getProductFamily()->getBehaviorCountStock()) {
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE :
return $product->getProductFamily()->getAvailableQuantity();
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :
return $product->getAvailableQuantity();
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_UNLIMITED :
return false;
}
}

/*public function getTaxRateInherited(ProductInterface $product)
{
return $product->getProductFamily()->getTaxRateInherited();
}*/

public function getExportTitleInherited(ProductInterface $product): ?string
{
$exportTitle = $product->getExportTitle();
if ($exportTitle && strlen($exportTitle)) {
return $exportTitle;
} else {
$productFamily = $product->getProductFamily();
if ($productFamily) {
return $productFamily->getExportTitle();
}
}


return null;
}

public function getExportNoteInherited(ProductInterface $product): ?string
{
$exportNote = $product->getExportNote();
if ($exportNote && strlen($exportNote)) {
return $exportNote;
} else {
$productFamily = $product->getProductFamily();
if ($productFamily) {
return $productFamily->getExportNote();
}
}

return null;
}
} }

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

namespace Lc\CaracoleBundle\Transformer\Order; namespace Lc\CaracoleBundle\Transformer\Order;


use Lc\CaracoleBundle\Model\Order\OrderShopInterface; use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
use Lc\CaracoleBundle\Resolver\OrderShopResolver;
use Lc\CaracoleBundle\Resolver\ReductionResolver; use Lc\CaracoleBundle\Resolver\ReductionResolver;
use Lc\CaracoleBundle\Solver\Order\OrderShopSolver; use Lc\CaracoleBundle\Solver\Order\OrderShopSolver;
use Lc\CaracoleBundle\Solver\Price\PriceSolver; use Lc\CaracoleBundle\Solver\Price\PriceSolver;
{ {
protected PriceSolver $priceSolver; protected PriceSolver $priceSolver;
protected OrderShopSolver $orderShopSolver; protected OrderShopSolver $orderShopSolver;
protected OrderShopResolver $orderShopResolver;
public function __construct(PriceSolver $priceSolver, OrderShopSolver $orderShopSolver)
public function __construct(PriceSolver $priceSolver, OrderShopSolver $orderShopSolver, OrderShopResolver $orderShopResolver)
{ {
$this->priceSolver = $priceSolver; $this->priceSolver = $priceSolver;
$this->orderShopSolver = $orderShopSolver; $this->orderShopSolver = $orderShopSolver;
$this->orderShopResolver = $orderShopResolver;
} }


// getOrderDatas // getOrderDatas
$data['count'] = $this->orderShopSolver->countQuantities($orderShop); $data['count'] = $this->orderShopSolver->countQuantities($orderShop);
$data['total_with_tax'] = $this->priceSolver->getTotalWithTax($orderShop); $data['total_with_tax'] = $this->priceSolver->getTotalWithTax($orderShop);
$data['order_products_by_category'] = $this->orderShopSolver->getOrderProductsByParentCategory($orderShop); $data['order_products_by_category'] = $this->orderShopSolver->getOrderProductsByParentCategory($orderShop);
$data['total_remaining_to_be_paid'] = $this->orderShopSolver->getTotalRemainingToBePaid($orderShop);
$data['total_remaining_to_be_paid'] = $this->orderShopResolver->getTotalRemainingToBePaid($orderShop);
} }
return $data; return $data;
} }

Loading…
Cancel
Save