namespace Lc\CaracoleBundle\Builder\Order; | namespace Lc\CaracoleBundle\Builder\Order; | ||||
use Doctrine\ORM\EntityManagerInterface; | use Doctrine\ORM\EntityManagerInterface; | ||||
use Lc\CaracoleBundle\Factory\Order\OrderProductReductionCatalogFactory; | |||||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | ||||
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | |||||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||||
use Lc\CaracoleBundle\Repository\Order\OrderProductStore; | use Lc\CaracoleBundle\Repository\Order\OrderProductStore; | ||||
use Lc\CaracoleBundle\Resolver\Price\PriceResolver; | |||||
use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore; | |||||
use Lc\CaracoleBundle\Solver\Order\OrderProductSolver; | 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\ProductFamilySolver; | ||||
protected ProductSolver $productSolver; | protected ProductSolver $productSolver; | ||||
protected ProductFamilySolver $productFamilySolver; | protected ProductFamilySolver $productFamilySolver; | ||||
protected OrderProductSolver $orderProductSolver; | protected OrderProductSolver $orderProductSolver; | ||||
protected OrderProductReductionCatalogFactory $orderProductReductionCatalogFactory; | |||||
protected ProductFamilyStore $productFamilyStore; | |||||
public function __construct( | public function __construct( | ||||
EntityManagerInterface $entityManager, | EntityManagerInterface $entityManager, | ||||
OrderProductStore $orderProductStore, | OrderProductStore $orderProductStore, | ||||
ProductSolver $productSolver, | ProductSolver $productSolver, | ||||
OrderProductSolver $orderProductSolver, | OrderProductSolver $orderProductSolver, | ||||
ProductFamilySolver $productFamilySolver | |||||
ProductFamilySolver $productFamilySolver, | |||||
OrderProductReductionCatalogFactory $orderProductReductionCatalogFactory, | |||||
ProductFamilyStore $productFamilyStore | |||||
) { | ) { | ||||
$this->entityManager = $entityManager; | $this->entityManager = $entityManager; | ||||
$this->priceSolver = $priceSolver; | $this->priceSolver = $priceSolver; | ||||
$this->productSolver = $productSolver; | $this->productSolver = $productSolver; | ||||
$this->orderProductSolver = $orderProductSolver; | $this->orderProductSolver = $orderProductSolver; | ||||
$this->productFamilySolver = $productFamilySolver; | $this->productFamilySolver = $productFamilySolver; | ||||
$this->orderProductReductionCatalogFactory = $orderProductReductionCatalogFactory; | |||||
$this->productFamilyStore = $productFamilyStore; | |||||
} | } | ||||
public function init(OrderProductInterface $orderProduct) :OrderProductInterface | public function init(OrderProductInterface $orderProduct) :OrderProductInterface | ||||
return $orderProduct; | return $orderProduct; | ||||
} | } | ||||
public function initReductionCatalog(SectionInterface $section, OrderProductInterface $orderProduct, ProductFamilyInterface $productFamily): OrderProductInterface | |||||
{ | |||||
if(!$orderProduct->getOrderProductReductionCatalog()) { | |||||
$reductionCatalog = $productFamily->getReductionCatalog(); | |||||
if ($reductionCatalog && $reductionCatalog->getStatus()) { | |||||
$orderProductReductionCatalog = $this->orderProductReductionCatalogFactory->create( | |||||
$reductionCatalog->getTitle(), | |||||
$reductionCatalog->getValue(), | |||||
$reductionCatalog->getUnit(), | |||||
$reductionCatalog->getBehaviorTaxRate() | |||||
); | |||||
$orderProduct->setOrderProductReductionCatalog($orderProductReductionCatalog); | |||||
} | |||||
} | |||||
return $orderProduct; | |||||
} | |||||
} | } |
use Lc\CaracoleBundle\Model\Order\OrderStatusModel; | use Lc\CaracoleBundle\Model\Order\OrderStatusModel; | ||||
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\Reduction\ReductionCartInterface; | use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface; | ||||
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface; | use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface; | ||||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | use Lc\CaracoleBundle\Model\Section\SectionInterface; | ||||
use Lc\CaracoleBundle\Repository\Order\OrderStatusStore; | use Lc\CaracoleBundle\Repository\Order\OrderStatusStore; | ||||
use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore; | use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore; | ||||
use Lc\CaracoleBundle\Resolver\MerchantResolver; | use Lc\CaracoleBundle\Resolver\MerchantResolver; | ||||
use Lc\CaracoleBundle\Resolver\OpeningResolver; | |||||
use Lc\CaracoleBundle\Resolver\OrderShopResolver; | use Lc\CaracoleBundle\Resolver\OrderShopResolver; | ||||
use Lc\CaracoleBundle\Solver\Order\OrderProductReductionCatalogSolver; | use Lc\CaracoleBundle\Solver\Order\OrderProductReductionCatalogSolver; | ||||
use Lc\CaracoleBundle\Solver\Order\OrderProductSolver; | |||||
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\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 Lc\SovBundle\Translation\FlashBagTranslator; | |||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | use Symfony\Component\EventDispatcher\EventDispatcherInterface; | ||||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; | use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; | ||||
protected DocumentBuilder $documentBuilder; | protected DocumentBuilder $documentBuilder; | ||||
protected EventDispatcherInterface $eventDispatcher; | protected EventDispatcherInterface $eventDispatcher; | ||||
protected FlashBagInterface $flashBag; | protected FlashBagInterface $flashBag; | ||||
protected OpeningResolver $openingResolver; | |||||
protected ProductSolver $productSolver; | protected ProductSolver $productSolver; | ||||
protected OrderShopResolver $orderShopResolver; | protected OrderShopResolver $orderShopResolver; | ||||
protected OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver; | protected OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver; | ||||
protected DistributionBuilder $distributionBuilder; | protected DistributionBuilder $distributionBuilder; | ||||
protected MerchantResolver $merchantResolver; | protected MerchantResolver $merchantResolver; | ||||
protected CreditHistoryBuilder $creditHistoryBuilder; | protected CreditHistoryBuilder $creditHistoryBuilder; | ||||
protected FlashBagTranslator $flashBagTranslator; | |||||
protected OrderShopFactory $orderShopFactory; | protected OrderShopFactory $orderShopFactory; | ||||
protected OrderProductSolver $orderProductSolver; | |||||
public function __construct( | public function __construct( | ||||
EntityManagerInterface $entityManager, | EntityManagerInterface $entityManager, | ||||
PriceSolver $priceSolver, | PriceSolver $priceSolver, | ||||
EventDispatcherInterface $eventDispatcher, | EventDispatcherInterface $eventDispatcher, | ||||
FlashBagInterface $flashBag, | FlashBagInterface $flashBag, | ||||
OpeningResolver $openingResolver, | |||||
ProductSolver $productSolver, | ProductSolver $productSolver, | ||||
OrderShopResolver $orderShopResolver, | OrderShopResolver $orderShopResolver, | ||||
OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver, | OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver, | ||||
DistributionBuilder $distributionBuilder, | DistributionBuilder $distributionBuilder, | ||||
MerchantResolver $merchantResolver, | MerchantResolver $merchantResolver, | ||||
CreditHistoryBuilder $creditHistoryBuilder, | CreditHistoryBuilder $creditHistoryBuilder, | ||||
FlashBagTranslator $flashBagTranslator, | |||||
OrderShopFactory $orderShopFactory | |||||
OrderShopFactory $orderShopFactory, | |||||
OrderProductSolver $orderProductSolver | |||||
) { | ) { | ||||
$this->entityManager = $entityManager; | $this->entityManager = $entityManager; | ||||
$this->orderShopStore = $orderShopStore; | $this->orderShopStore = $orderShopStore; | ||||
$this->priceSolver = $priceSolver; | $this->priceSolver = $priceSolver; | ||||
$this->eventDispatcher = $eventDispatcher; | $this->eventDispatcher = $eventDispatcher; | ||||
$this->flashBag = $flashBag; | $this->flashBag = $flashBag; | ||||
$this->openingResolver = $openingResolver; | |||||
$this->productSolver = $productSolver; | $this->productSolver = $productSolver; | ||||
$this->orderShopResolver = $orderShopResolver; | $this->orderShopResolver = $orderShopResolver; | ||||
$this->orderProductReductionCatalogSolver = $orderProductReductionCatalogSolver; | $this->orderProductReductionCatalogSolver = $orderProductReductionCatalogSolver; | ||||
$this->distributionBuilder = $distributionBuilder; | $this->distributionBuilder = $distributionBuilder; | ||||
$this->merchantResolver = $merchantResolver; | $this->merchantResolver = $merchantResolver; | ||||
$this->creditHistoryBuilder = $creditHistoryBuilder; | $this->creditHistoryBuilder = $creditHistoryBuilder; | ||||
$this->flashBagTranslator = $flashBagTranslator; | |||||
$this->orderShopFactory = $orderShopFactory; | $this->orderShopFactory = $orderShopFactory; | ||||
$this->orderProductSolver = $orderProductSolver; | |||||
} | } | ||||
public function create( | public function create( | ||||
): bool { | ): bool { | ||||
$return = false; | $return = false; | ||||
$orderProductAdd->setOrderShop($orderShop); | |||||
if ($this->orderShopSolver->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); | ||||
$productFamily = $this->productFamilyStore->setSection($orderShop->getSection())->getOneBySlug( | |||||
$orderProductAdd->getProduct()->getProductFamily()->getSlug() | |||||
); | |||||
if ($productFamily) { | |||||
$reductionCatalog = $productFamily->getReductionCatalog(); | |||||
if ($reductionCatalog && $reductionCatalog->getStatus()) { | |||||
$orderProductReductionCatalogFactory = new OrderProductReductionCatalogFactory(); | |||||
$orderProductReductionCatalog = $orderProductReductionCatalogFactory->create( | |||||
$reductionCatalog->getTitle(), | |||||
$reductionCatalog->getValue(), | |||||
$reductionCatalog->getUnit(), | |||||
$reductionCatalog->getBehaviorTaxRate() | |||||
); | |||||
$orderProductAdd->setOrderProductReductionCatalog($orderProductReductionCatalog); | |||||
//TODO vérifier ma modif ici | |||||
if(is_null($orderProductAdd->getOrderProductReductionCatalog())) { | |||||
// on hydrate $productFamily avec réduction | |||||
$productFamily = $this->productFamilyStore->setSection($orderShop->getSection())->getOneBySlug( | |||||
$orderProductAdd->getProduct()->getProductFamily()->getSlug() | |||||
); | |||||
if($productFamily) { | |||||
$this->orderProductBuilder->initReductionCatalog($orderShop->getSection(), $orderProductAdd, $productFamily); | |||||
} | } | ||||
} | } | ||||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | foreach ($orderShop->getOrderProducts() as $orderProduct) { | ||||
if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId() | |||||
&& $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery() | |||||
&& (string)$this->priceSolver->getPrice($orderProduct) | |||||
== (string)$this->priceSolver->getPrice($orderProductAdd) | |||||
&& $this->orderProductReductionCatalogSolver->compare( | |||||
$orderProduct->getOrderProductReductionCatalog(), | |||||
$orderProductAdd->getOrderProductReductionCatalog() | |||||
)) { | |||||
if ($this->orderProductSolver->compare($orderProduct, $orderProductAdd)) { | |||||
$orderProduct->setQuantityOrder( | $orderProduct->setQuantityOrder( | ||||
$orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder() | $orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder() | ||||
); | ); | ||||
OrderShopInterface $orderShop2, | OrderShopInterface $orderShop2, | ||||
$persist = true | $persist = true | ||||
): OrderShopInterface { | ): OrderShopInterface { | ||||
//TODO essayer de comprendre prk on doit faire un refresh ici ??? | |||||
// TODO essayer de comprendre pourquoi on doit faire un refresh ici | |||||
$this->entityManager->refresh($orderShop1); | $this->entityManager->refresh($orderShop1); | ||||
$this->entityManager->refresh($orderShop2); | $this->entityManager->refresh($orderShop2); | ||||
if ($orderShop1 && $orderShop2) { | |||||
foreach ($orderShop2->getOrderProducts() as $orderProduct) { | |||||
$orderProductAlreadyInCart = $this->orderShopSolver->hasOrderProductAlreadyInCart( | |||||
$orderShop1, | |||||
$orderProduct | |||||
); | |||||
if ($orderProductAlreadyInCart) { | |||||
if ($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) { | |||||
$orderShop1->removeOrderProduct($orderProductAlreadyInCart); | |||||
$this->addOrderProduct($orderShop1, $orderProduct); | |||||
} | |||||
} else { | |||||
$this->addOrderProduct($orderShop1, $orderProduct); | |||||
} | |||||
if ($persist) { | |||||
$this->entityManager->delete($orderProduct); | |||||
foreach ($orderShop2->getOrderProducts() as $orderProduct) { | |||||
$orderProductAlreadyInCart = $this->orderShopSolver->hasOrderProductAlreadyInCart( | |||||
$orderShop1, | |||||
$orderProduct | |||||
); | |||||
if ($orderProductAlreadyInCart) { | |||||
if ($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) { | |||||
$orderShop1->removeOrderProduct($orderProductAlreadyInCart); | |||||
$this->addOrderProduct($orderShop1, $orderProduct); | |||||
} | } | ||||
} else { | |||||
$this->addOrderProduct($orderShop1, $orderProduct); | |||||
} | } | ||||
if ($persist) { | if ($persist) { | ||||
$this->entityManager->delete($orderShop2); | |||||
$this->entityManager->update($orderShop1); | |||||
$this->entityManager->flush(); | |||||
$this->entityManager->delete($orderProduct); | |||||
} | } | ||||
} | |||||
return $orderShop1; | |||||
if ($persist) { | |||||
$this->entityManager->delete($orderShop2); | |||||
$this->entityManager->update($orderShop1); | |||||
$this->entityManager->flush(); | |||||
} | } | ||||
return $orderShop1; | |||||
} | } | ||||
public function addPayment(OrderShopInterface $orderShop, string $meanPayment, float $amount): OrderShopInterface | public function addPayment(OrderShopInterface $orderShop, string $meanPayment, float $amount): OrderShopInterface | ||||
public function deductAvailabilityProduct(OrderShopInterface $orderShop): void | public function deductAvailabilityProduct(OrderShopInterface $orderShop): void | ||||
{ | { | ||||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | foreach ($orderShop->getOrderProducts() as $orderProduct) { | ||||
$this->applyDeductAvailabilityProduct($orderShop, $orderProduct); | |||||
$this->applyDeductAvailabilityProduct($orderShop, $orderProduct->getProduct(), $orderProduct->getQuantityOrder()); | |||||
} | } | ||||
} | } | ||||
public function applyDeductAvailabilityProduct( | public function applyDeductAvailabilityProduct( | ||||
OrderShopInterface $orderShop, | OrderShopInterface $orderShop, | ||||
OrderProductInterface $orderProduct | |||||
ProductInterface $product, | |||||
int $quantityOrder | |||||
): void { | ): void { | ||||
switch ($orderProduct->getProduct()->getProductFamily()->getBehaviorCountStock()) { | |||||
switch ($product->getProductFamily()->getBehaviorCountStock()) { | |||||
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 = $this->productSolver->getAvailableQuantityInherited($orderProduct->getProduct()); | |||||
$newAvailability = $oldAvailability - ($orderProduct->getQuantityOrder( | |||||
) * ($orderProduct->getQuantityProduct() / $orderProduct->getUnit()->getCoefficient())); | |||||
$oldAvailability = $this->productSolver->getAvailableQuantityInherited($product); | |||||
$newAvailability = $oldAvailability - ($quantityOrder * ($this->productSolver->getQuantityInherited( | |||||
$product | |||||
) / $this->productSolver->getUnitInherited($product)->getCoefficient())); | |||||
$productFamily = $orderProduct->getProduct()->getProductFamily(); | |||||
$productFamily = $product->getProductFamily(); | |||||
$productFamily->setAvailableQuantity($newAvailability); | $productFamily->setAvailableQuantity($newAvailability); | ||||
$productFamily->setUpdatedBy($orderShop->getUser()); | $productFamily->setUpdatedBy($orderShop->getUser()); | ||||
break; | break; | ||||
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY : | case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY : | ||||
$oldAvailability = $this->productSolver->getAvailableQuantityInherited($orderProduct->getProduct()); | |||||
$newAvailability = $oldAvailability - $orderProduct->getQuantityOrder(); | |||||
$oldAvailability = $this->productSolver->getAvailableQuantityInherited($product); | |||||
$newAvailability = $oldAvailability - $quantityOrder; | |||||
$productFamily = $orderProduct->getProduct()->getProductFamily(); | |||||
$productFamily = $product->getProductFamily(); | |||||
$productFamily->setAvailableQuantity($newAvailability); | $productFamily->setAvailableQuantity($newAvailability); | ||||
$productFamily->setUpdatedBy($orderShop->getUser()); | $productFamily->setUpdatedBy($orderShop->getUser()); | ||||
break; | break; | ||||
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT : | case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT : | ||||
$oldAvailability = $this->productSolver->getAvailableQuantityInherited($orderProduct->getProduct()); | |||||
$newAvailability = $oldAvailability - $orderProduct->getQuantityOrder(); | |||||
$oldAvailability = $this->productSolver->getAvailableQuantityInherited($product); | |||||
$newAvailability = $oldAvailability - $quantityOrder; | |||||
$product = $orderProduct->getProduct(); | |||||
$product->setAvailableQuantity($newAvailability); | $product->setAvailableQuantity($newAvailability); | ||||
$product->setUpdatedBy($orderShop->getUser()); | $product->setUpdatedBy($orderShop->getUser()); | ||||
break; | break; | ||||
} | } | ||||
$this->entityManager->flush(); | $this->entityManager->flush(); | ||||
} | } | ||||
public function updatePriceByProductFamily(ProductFamilyInterface $productFamily) | |||||
public function updatePriceByProductFamily(ProductFamilyInterface $productFamily, SectionInterface $section) | |||||
{ | { | ||||
$debug = ''; | |||||
foreach ($this->merchantResolver->getCurrent()->getSections() as $section) { | |||||
// @TODO : faire la vérification isOpenSale depuis la méthode appelante | |||||
if (!$this->openingResolver->isOpenSale($section)) { | |||||
$countOrderProductUpdated = 0; | |||||
foreach ($productFamily->getProducts() as $product) { | |||||
$orderProducts = $this->orderProductStore->resetContext()->setSection( | |||||
$section | |||||
)->getInCartsByProduct($product); | |||||
$countOrderProductUpdated = 0; | |||||
foreach ($orderProducts as $orderProduct) { | |||||
$quantityOrder = $orderProduct->getQuantityOrder(); | |||||
$orderShop = $orderProduct->getOrderShop(); | |||||
foreach ($productFamily->getProducts() as $product) { | |||||
$orderProducts = $this->orderProductStore->resetContext()->setSection( | |||||
$section | |||||
)->getInCartsByProduct($product); | |||||
$orderShop->removeOrderProduct($orderProduct); | |||||
$this->entityManager->delete($orderProduct); | |||||
$this->entityManager->flush(); | |||||
$this->entityManager->refresh($orderShop); | |||||
foreach ($orderProducts as $orderProduct) { | |||||
$quantityOrder = $orderProduct->getQuantityOrder(); | |||||
$orderShop = $orderProduct->getOrderShop(); | |||||
$orderProductFactory = new OrderProductFactory(); | |||||
$addOrderProduct = $orderProductFactory->create($product, $quantityOrder); | |||||
$this->addOrderProduct($orderShop, $addOrderProduct); | |||||
$orderShop->removeOrderProduct($orderProduct); | |||||
$this->entityManager->delete($orderProduct); | |||||
$this->entityManager->flush(); | |||||
$this->entityManager->refresh($orderShop); | |||||
$countOrderProductUpdated++; | |||||
} | |||||
} | |||||
if ($countOrderProductUpdated) { | |||||
$this->flashBagTranslator->add( | |||||
'success', | |||||
'orderProductUpdated', | |||||
'OrderShop', | |||||
//array('%count%' => $countOrderProductUpdated) | |||||
['%count' => $debug] | |||||
); | |||||
$orderProductFactory = new OrderProductFactory(); | |||||
$addOrderProduct = $orderProductFactory->create($product, $quantityOrder); | |||||
$this->addOrderProduct($orderShop, $addOrderProduct); | |||||
$this->entityManager->flush(); | |||||
} | |||||
return $countOrderProductUpdated; | |||||
$countOrderProductUpdated++; | |||||
} | } | ||||
} | } | ||||
if ($countOrderProductUpdated) { | |||||
$this->entityManager->flush(); | |||||
} | |||||
return $countOrderProductUpdated; | |||||
} | } | ||||
use Lc\CaracoleBundle\Factory\Reduction\ReductionCatalogFactory; | use Lc\CaracoleBundle\Factory\Reduction\ReductionCatalogFactory; | ||||
use Lc\CaracoleBundle\Repository\Reduction\ReductionCatalogRepositoryQuery; | use Lc\CaracoleBundle\Repository\Reduction\ReductionCatalogRepositoryQuery; | ||||
use Lc\CaracoleBundle\Repository\Reduction\ReductionCatalogStore; | use Lc\CaracoleBundle\Repository\Reduction\ReductionCatalogStore; | ||||
use Lc\CaracoleBundle\Solver\Reduction\ReductionCatalogSolver; | |||||
class ReductionCatalogContainer | class ReductionCatalogContainer | ||||
{ | { | ||||
$this->fieldDefinition = $fieldDefinition; | $this->fieldDefinition = $fieldDefinition; | ||||
} | } | ||||
public static function getEntityFqcn() | public static function getEntityFqcn() | ||||
{ | { | ||||
return ReductionCatalog::class; | return ReductionCatalog::class; | ||||
return $this->fieldDefinition; | return $this->fieldDefinition; | ||||
} | } | ||||
// public function getSolver(): ReductionCatalogSolver | |||||
// { | |||||
// return $this->solver; | |||||
// } | |||||
} | } |
use Lc\CaracoleBundle\Controller\AbstractController; | use Lc\CaracoleBundle\Controller\AbstractController; | ||||
use Lc\CaracoleBundle\Form\Order\OrderProductsType; | use Lc\CaracoleBundle\Form\Order\OrderProductsType; | ||||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | ||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||||
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | ||||
use Symfony\Component\HttpFoundation\JsonResponse; | use Symfony\Component\HttpFoundation\JsonResponse; | ||||
use Symfony\Component\HttpFoundation\RedirectResponse; | use Symfony\Component\HttpFoundation\RedirectResponse; | ||||
class CartController extends AbstractController | class CartController extends AbstractController | ||||
{ | { | ||||
protected ProductFamilyInterface $productFamily; | protected ProductFamilyInterface $productFamily; | ||||
protected int $quantityOrder = 1; | |||||
protected array $orderProducts = []; | protected array $orderProducts = []; | ||||
public function addProductFamily(Request $request): JsonResponse | public function addProductFamily(Request $request): JsonResponse | ||||
$data = $form->getData(); | $data = $form->getData(); | ||||
foreach ($data as $orderProduct) { | foreach ($data as $orderProduct) { | ||||
if ($orderProduct instanceof OrderProductInterface) { | if ($orderProduct instanceof OrderProductInterface) { | ||||
if ($orderProduct->getQuantityOrder() > 0) { | |||||
$addOrderProduct = $this->getOrderShopContainer()->getBuilder()->addOrderProduct( | |||||
$orderShop, | |||||
$orderProduct | |||||
); | |||||
} | |||||
if (isset($addOrderProduct) && $addOrderProduct && $orderProduct->getQuantityOrder() > 0) { | |||||
$this->orderProducts[] = $orderProduct; | |||||
} | |||||
$this->addOrderProduct($orderShop, $orderProduct); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
return new JsonResponse($return); | return new JsonResponse($return); | ||||
} | } | ||||
public function addOrderProduct(OrderShopInterface $orderShop, OrderProductInterface $orderProduct): void | |||||
{ | |||||
$this->quantityOrder = $orderProduct->getQuantityOrder(); | |||||
$addOrderProduct = $this->getOrderShopContainer()->getBuilder()->addOrderProduct( | |||||
$orderShop, | |||||
$orderProduct | |||||
); | |||||
if (isset($addOrderProduct) && $addOrderProduct && $orderProduct->getQuantityOrder() > 0) { | |||||
$this->orderProducts[] = $orderProduct; | |||||
} | |||||
} | |||||
/** | /** | ||||
* @Route("/order-reduction-cart/delete/{id}", name="delete_reduction_cart") | * @Route("/order-reduction-cart/delete/{id}", name="delete_reduction_cart") | ||||
*/ | */ |
return $responseParameters; | return $responseParameters; | ||||
} | } | ||||
public function showSalesStatistic(AdminContext $context) | |||||
{ | |||||
$productFamily = $context->getEntity()->getInstance(); | |||||
$currentSection = $this->get(SectionResolver::class)->getCurrent(); | |||||
$productsSalesStatistic = $this->get(OrderShopContainer::class)->getBuilder()->getProductsSalesStatistic($currentSection, $productFamily, 16); | |||||
$parameters = array( | |||||
'productFamily' => $productFamily, | |||||
'productsSalesStatistic' => $productsSalesStatistic | |||||
); | |||||
//TODO flashMessages ??? | |||||
$response['flashMessages'] = [];//$this->utils->getFlashMessages(); | |||||
$response['data'] = $this->render('@LcCaracole/admin/product/modal/show_products_sales_statistic.html.twig', $parameters)->getContent(); | |||||
$response['statistics'] = $productsSalesStatistic; | |||||
return new Response(json_encode($response)); | |||||
} | |||||
} | } |
namespace Lc\CaracoleBundle\Definition\Field\Reduction; | namespace Lc\CaracoleBundle\Definition\Field\Reduction; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | ||||
use Lc\CaracoleBundle\Definition\Field\AbstractFieldDefinition; | |||||
use Lc\CaracoleBundle\Repository\Section\SectionStore; | |||||
use Lc\CaracoleBundle\Context\MerchantContextTrait; | |||||
use Lc\SovBundle\Definition\Field\AbstractFieldDefinition; | |||||
use Lc\CaracoleBundle\Field\AssociationField; | |||||
use Lc\CaracoleBundle\Model\Config\TaxRateModel; | |||||
use Lc\CaracoleBundle\Model\Config\UnitModel; | |||||
use Lc\CaracoleBundle\Repository\Product\ProductCategoryStore; | |||||
use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore; | |||||
use Lc\CaracoleBundle\Repository\User\GroupUserStore; | |||||
use Lc\CaracoleBundle\Repository\User\UserStore; | |||||
use Lc\SovBundle\Field\BooleanField; | |||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
class ReductionCatalogFieldDefinition extends AbstractFieldDefinition | class ReductionCatalogFieldDefinition extends AbstractFieldDefinition | ||||
{ | { | ||||
protected SectionStore $sectionStore; | |||||
use MerchantContextTrait; | |||||
public function __construct(TranslatorAdmin $translatorAdmin, SectionStore $sectionStore) | |||||
protected GroupUserStore $groupUserStore; | |||||
protected UserStore $userStore; | |||||
protected ProductFamilyStore $productFamilyStore; | |||||
protected ProductCategoryStore $productCategoryStore; | |||||
public function __construct( | |||||
TranslatorAdmin $translatorAdmin, | |||||
GroupUserStore $groupUserStore, | |||||
UserStore $userStore, | |||||
ProductFamilyStore $productFamilyStore, | |||||
ProductCategoryStore $productCategoryStore | |||||
) | |||||
{ | { | ||||
parent::__construct($translatorAdmin); | parent::__construct($translatorAdmin); | ||||
$this->sectionStore = $sectionStore; | |||||
$this->groupUserStore = $groupUserStore; | |||||
$this->userStore = $userStore; | |||||
$this->productFamilyStore = $productFamilyStore; | |||||
$this->productCategoryStore = $productCategoryStore; | |||||
} | |||||
public function configureIndex(): array | |||||
{ | |||||
return [ | |||||
'id', | |||||
'title', | |||||
'value', | |||||
'status', | |||||
'isDisplayed' | |||||
]; | |||||
} | |||||
public function configureForm(): array | |||||
{ | |||||
return [ | |||||
'title', | |||||
'behaviorTaxRate', | |||||
'unit', | |||||
'value', | |||||
'permanent', | |||||
'dateStart', | |||||
'dateEnd', | |||||
'usersActive', | |||||
'users', | |||||
'groupUsersActive', | |||||
'groupUsers', | |||||
'productCategoriesActive', | |||||
'productCategories', | |||||
'productFamiliesActive', | |||||
'productFamilies', | |||||
'status', | |||||
'isDisplayed' | |||||
]; | |||||
} | } | ||||
public function configureFields(): array | public function configureFields(): array | ||||
{ | { | ||||
$groupUserArray = $this->groupUserStore->setMerchant($this->merchant)->get(); | |||||
$usersArray = $this->userStore->setMerchant($this->merchant)->getJoinGroupUsers(); | |||||
$productFamilyArray = $this->productFamilyStore->setMerchant($this->merchant)->get(); | |||||
$productCategoryArray = $this->productCategoryStore->setMerchant($this->merchant)->get(); | |||||
return [ | return [ | ||||
'title' => TextField::new('title')->setSortable(true) | |||||
// @TODO : à faire | |||||
'title' => TextField::new('title')->setSortable(true), | |||||
'behaviorTaxRate' => ChoiceField::new('behaviorTaxRate') | |||||
->setFormTypeOption('required', true) | |||||
->setFormTypeOption('empty_data', TaxRateModel::BEHAVIOR_TAX_RATE_INCLUDED) | |||||
->setChoices( | |||||
$this->translatorAdmin->transChoices( | |||||
TaxRateModel::getBehaviorTaxRateChoices(), | |||||
'TaxRate', | |||||
'behaviorTaxRate' | |||||
) | |||||
), | |||||
'unit' => ChoiceField::new('unit') | |||||
->setFormTypeOption('expanded', true) | |||||
->setFormTypeOption('required', true) | |||||
->setChoices( | |||||
$this->translatorAdmin->transChoices( | |||||
UnitModel::getUnitAmountChoices(), | |||||
'Unit', | |||||
'unit' | |||||
) | |||||
), | |||||
'value' => NumberField::new('value')->setTemplatePath('@LcCaracole/admin/reduction/field/amount.html.twig'), | |||||
'permanent' => BooleanField::new('permanent'), | |||||
'dateStart' => DateTimeField::new('dateStart'), | |||||
'dateEnd' => DateTimeField::new('dateEnd'), | |||||
'isDisplayed'=> BooleanField::new('isDisplayed'), | |||||
'groupUsersActive' => BooleanField::new('groupUsersActive')->setFormTypeOption('mapped', false), | |||||
'groupUsers' => AssociationField::new('groupUsers') | |||||
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig') | |||||
->setFormTypeOption('choices', $groupUserArray), | |||||
'usersActive' => BooleanField::new('usersActive')->setFormTypeOption('mapped', false), | |||||
'users' => AssociationField::new('users') | |||||
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig') | |||||
->setFormTypeOption('choices', $usersArray) | |||||
->setFormTypeOption( | |||||
'choice_attr', | |||||
function ($choice, $key, $value) { | |||||
$data = array(); | |||||
foreach ($choice->getGroupUsers() as $groupUser) { | |||||
$data[] = '_' . $groupUser->getId() . '_'; | |||||
} | |||||
return ['data-group-users' => json_encode($data)]; | |||||
}, | |||||
), | |||||
'productCategoriesActive' => BooleanField::new('productCategoriesActive')->setFormTypeOption('mapped', false), | |||||
'productCategories' => AssociationField::new('productCategories') | |||||
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig') | |||||
->setFormTypeOption('choice_label', | |||||
// @TODO : attention, code dupliqué de ProductCategoriesFilter | |||||
function ($category) { | |||||
$isOffline = ''; | |||||
if ($category->getStatus() != 1) { | |||||
$isOffline = " [Hors ligne]"; | |||||
} | |||||
$section = ' [' . $category->getSection()->getTitle() . ']';; | |||||
return $category . $section . $isOffline; | |||||
}) | |||||
->setFormTypeOption('choices', $productCategoryArray), | |||||
'productFamiliesActive' => BooleanField::new('productFamiliesActive')->setFormTypeOption('mapped', false), | |||||
'productFamilies' => AssociationField::new('productFamilies') | |||||
->setTemplatePath('@LcSov/adminlte/crud/field/association_many.html.twig') | |||||
->setFormTypeOption('choices', $productFamilyArray) | |||||
->setFormTypeOption( | |||||
'choice_attr', | |||||
function ($choice, $key, $value) { | |||||
$data = array(); | |||||
foreach ($choice->getProductCategories() as $category) { | |||||
$data[] = '_' . $category->getId() . '_'; | |||||
} | |||||
return [ | |||||
'data-product-categories' => json_encode($data), | |||||
'data-supplier' => $choice->getSupplier()->getId() | |||||
]; | |||||
} | |||||
), | |||||
'productFamily' => AssociationField::new('productFamily') | |||||
->setFormTypeOption('choices', $productFamilyArray) | |||||
]; | ]; | ||||
} | } | ||||
} | } |
<?php | |||||
namespace Lc\CaracoleBundle\EventSubscriber\Product; | |||||
use Doctrine\ORM\EntityManagerInterface; | |||||
use Lc\CaracoleBundle\Model\Address\AddressInterface; | |||||
use Lc\CaracoleBundle\Model\Product\ProductInterface; | |||||
use Lc\SovBundle\Doctrine\EntityInterface; | |||||
use Lc\SovBundle\Doctrine\Extension\SluggableInterface; | |||||
use Lc\SovBundle\Doctrine\Extension\SortableInterface; | |||||
use Lc\SovBundle\Doctrine\Extension\StatusInterface; | |||||
use Lc\SovBundle\Doctrine\Extension\TreeInterface; | |||||
use Lc\SovBundle\Event\EntityComponentEvent; | |||||
use Lc\SovBundle\Event\EntityManager\EntityManagerEvent; | |||||
use Lc\SovBundle\Repository\AbstractRepositoryInterface; | |||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |||||
class DuplicateProductfamilyEventSubscriber implements EventSubscriberInterface | |||||
{ | |||||
protected $em; | |||||
protected $adminUrlGenerator; | |||||
public function __construct(EntityManagerInterface $entityManager) | |||||
{ | |||||
$this->em = $entityManager; | |||||
} | |||||
public static function getSubscribedEvents() | |||||
{ | |||||
return [ | |||||
EntityComponentEvent::DUPLICATE_EVENT => ['duplicateProductOnDuplicateEvent'], | |||||
]; | |||||
} | |||||
public function duplicateProductOnDuplicateEvent(EntityComponentEvent $event) | |||||
{ | |||||
$entity = $event->getEntity(); | |||||
$classMetadata = $this->em->getClassMetadata(get_class($entity)); | |||||
/*foreach ($classMetadata->getAssociationMappings() as $associationMapping){ | |||||
if(in_array(ProductInterface::class, class_implements($associationMapping['targetEntity']))){ | |||||
/*foreach ($productFamily->getProducts() as $i => $product) { | |||||
$newProduct = clone $product; | |||||
$newProduct->setProductFamily($productFamily); | |||||
$this->em->persist($newProduct); | |||||
$productFamily->addProduct($newProduct); | |||||
} | |||||
$methodGet = 'get'.ucfirst($associationMapping['fieldName']); | |||||
$methodSet = 'set'.ucfirst($associationMapping['fieldName']); | |||||
if(method_exists($entity, $methodGet) && method_exists($entity, $methodSet)){ | |||||
$newAddress = clone $entity->$methodGet(); | |||||
$entity->$methodSet($newAddress); | |||||
$this->em->persist($newAddress); | |||||
} | |||||
} | |||||
}*/ | |||||
} | |||||
} |
namespace Lc\CaracoleBundle\EventSubscriber\Product; | namespace Lc\CaracoleBundle\EventSubscriber\Product; | ||||
use Doctrine\ORM\EntityManagerInterface; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent; | use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent; | ||||
use Lc\CaracoleBundle\Builder\Order\OrderShopBuilder; | use Lc\CaracoleBundle\Builder\Order\OrderShopBuilder; | ||||
use Lc\CaracoleBundle\Container\Product\ProductContainer; | |||||
use Lc\CaracoleBundle\Container\Product\ProductFamilyContainer; | |||||
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | ||||
use Lc\CaracoleBundle\Model\Product\ProductInterface; | |||||
use Lc\CaracoleBundle\Model\Reduction\ReductionCatalogInterface; | |||||
use Lc\SovBundle\Event\EntityManager\EntityManagerEvent; | |||||
use Lc\CaracoleBundle\Resolver\MerchantResolver; | |||||
use Lc\CaracoleBundle\Resolver\OpeningResolver; | |||||
use Lc\SovBundle\Translation\FlashBagTranslator; | |||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||||
class UpdateProductfamilyAfterFlushEventSubscriber implements EventSubscriberInterface | class UpdateProductfamilyAfterFlushEventSubscriber implements EventSubscriberInterface | ||||
{ | { | ||||
protected EntityManagerInterface $em; | |||||
protected ProductFamilyContainer $productFamilyContainer; | |||||
protected ProductContainer $productContainer; | |||||
protected OrderShopBuilder $orderShopBuilder; | protected OrderShopBuilder $orderShopBuilder; | ||||
protected OpeningResolver $openingResolver; | |||||
protected FlashBagTranslator $flashBagTranslator; | |||||
public function __construct(EntityManagerInterface $entityManager, ProductFamilyContainer $productFamilyContainer, ProductContainer $productContainer, OrderShopBuilder $orderShopBuilder) | |||||
public function __construct( | |||||
OrderShopBuilder $orderShopBuilder, | |||||
OpeningResolver $openingResolver, | |||||
FlashBagTranslator $flashBagTranslator | |||||
) | |||||
{ | { | ||||
$this->em = $entityManager; | |||||
$this->productFamilyContainer = $productFamilyContainer; | |||||
$this->productContainer = $productContainer; | |||||
$this->orderShopBuilder = $orderShopBuilder; | $this->orderShopBuilder = $orderShopBuilder; | ||||
$this->openingResolver = $openingResolver; | |||||
$this->flashBagTranslator = $flashBagTranslator; | |||||
} | } | ||||
public static function getSubscribedEvents() | public static function getSubscribedEvents() | ||||
public function processAfterFlushProductFamily(AfterEntityUpdatedEvent $event) | public function processAfterFlushProductFamily(AfterEntityUpdatedEvent $event) | ||||
{ | { | ||||
$entity = $event->getEntityInstance(); | |||||
if ($entity instanceof ProductFamilyInterface) { | |||||
$this->orderShopBuilder->updatePriceByProductFamily($entity); | |||||
$productFamily = $event->getEntityInstance(); | |||||
if ($productFamily instanceof ProductFamilyInterface) { | |||||
foreach ($productFamily->getProductFamilySectionProperties() as $productFamilySectionProperty) { | |||||
$section = $productFamilySectionProperty->getSection(); | |||||
if (!$this->openingResolver->isOpenSale($section)) { | |||||
$countOrderProductUpdated = $this->orderShopBuilder->updatePriceByProductFamily($productFamily, $section); | |||||
if ($countOrderProductUpdated) { | |||||
$this->flashBagTranslator->add( | |||||
'success', | |||||
'orderProductUpdated', | |||||
'OrderShop', | |||||
array( | |||||
'%count%' => $countOrderProductUpdated, | |||||
'%section%' => $section->getTitle() | |||||
) | |||||
); | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
protected function processProducts($entity) | protected function processProducts($entity) | ||||
{ | { | ||||
if($entity->getId()) { | |||||
if ($entity->getId()) { | |||||
//Récupère le product origin | //Récupère le product origin | ||||
$originProducts = $this->productContainer->getStore()->getOriginByProductFamily($entity); | $originProducts = $this->productContainer->getStore()->getOriginByProductFamily($entity); | ||||
if (count($originProducts) > 1) { | |||||
throw new \ErrorException('Plusieurs OriginProduct pour un même produit... Contacter fab'); | |||||
// Case Nouveau product family | |||||
} else { | |||||
if (count($originProducts) == 0) { | |||||
$entityClassName = $this->em->getEntityName(ProductInterface::class); | |||||
$originProduct = new $entityClassName(); | |||||
$originProduct->setProductFamily($entity); | |||||
$originProduct->setOriginProduct(true); | |||||
$entity->addProduct($originProduct); | |||||
} else { | |||||
$originProduct = $originProducts[0]; | |||||
} | |||||
} | |||||
if ($entity->getActiveProducts()) { | |||||
$originProduct->setStatus(-1); | |||||
} else { | |||||
//CAse de création d'un produit | |||||
$originProducts = array(); | |||||
} | |||||
if (count($originProducts) > 1) { | |||||
throw new \ErrorException('Plusieurs OriginProduct pour un même produit... Contacter fab'); | |||||
// Case Nouveau product family | |||||
} else { | |||||
if (count($originProducts) == 0) { | |||||
$entityClassName = $this->em->getEntityName(ProductInterface::class); | |||||
$originProduct = new $entityClassName(); | |||||
$originProduct->setProductFamily($entity); | |||||
$originProduct->setOriginProduct(true); | |||||
$entity->addProduct($originProduct); | |||||
} else { | } else { | ||||
$originProduct->setStatus(1); | |||||
$originProduct = $originProducts[0]; | |||||
} | } | ||||
} | |||||
//Enregistrement | |||||
$entity->addProduct($originProduct); | |||||
if ($entity->getActiveProducts()) { | |||||
$originProduct->setStatus(-1); | |||||
} else { | |||||
$originProduct->setStatus(1); | |||||
} | |||||
foreach ($entity->getProducts() as $product) { | |||||
$product->setProductFamily($entity); | |||||
//Enregistrement | |||||
$entity->addProduct($originProduct); | |||||
if ($entity->getProductsQuantityAsTitle() && $product->getStatus() >= 1) { | |||||
$product->setTitle( | |||||
str_replace('.', ',', $this->productContainer->getSolver()->getQuantityInherited($product)) . $this->productContainer->getSolver()->getUnitInherited($product)->getWording() | |||||
); | |||||
} | |||||
foreach ($entity->getProducts() as $product) { | |||||
$product->setProductFamily($entity); | |||||
$this->em->persist($product); | |||||
$entity->addProduct($product); | |||||
if ($entity->getProductsQuantityAsTitle() && $product->getStatus() >= 1) { | |||||
$product->setTitle( | |||||
str_replace('.', ',', $this->productContainer->getSolver()->getQuantityInherited($product)) . $this->productContainer->getSolver()->getUnitInherited($product)->getWording() | |||||
); | |||||
} | } | ||||
$this->em->persist($product); | |||||
$entity->addProduct($product); | |||||
} | } | ||||
} | |||||
/* protected function processCategories(ProductFamilyInterface $entity) | |||||
{ | |||||
$productCategoryRepository = $this->em->getRepository(ProductCategoryInterface::class); | |||||
$productCategories = $entity->getProductCategories(); | |||||
$entity->initProductCategories(); | |||||
foreach ($productCategories as $key => $bool) { | |||||
if (is_bool($bool) && $bool) { | |||||
if (strpos($key, 'category_children_') !== false) { | |||||
$idCategory = (int)str_replace('category_children_', '', $key); | |||||
} else { | |||||
$idCategory = (int)str_replace('category_', '', $key); | |||||
} | |||||
$category = $productCategoryRepository->find($idCategory); | |||||
$entity->addProductCategory($category); | |||||
} | |||||
} | |||||
}*/ | |||||
} | |||||
} | } |
$class = ReductionCatalogContainer::getEntityFqcn(); | $class = ReductionCatalogContainer::getEntityFqcn(); | ||||
$reductionCatalog = new $class; | $reductionCatalog = new $class; | ||||
$reductionCatalog->setIsDisplayed(true); | |||||
$reductionCatalog->setMerchant($merchant); | $reductionCatalog->setMerchant($merchant); | ||||
$reductionCatalog->setStatus($status); | $reductionCatalog->setStatus($status); | ||||
protected $image; | protected $image; | ||||
/** | /** | ||||
* @ORM\ManyToMany(targetEntity="Lc\CaracoleBundle\Model\Product\QualityLabelInterface", fetch="EAGER") | |||||
* @ORM\ManyToMany(targetEntity="Lc\CaracoleBundle\Model\Product\QualityLabelInterface", fetch="LAZY") | |||||
*/ | */ | ||||
protected $qualityLabels; | protected $qualityLabels; | ||||
*/ | */ | ||||
protected $productCategories; | protected $productCategories; | ||||
/** | |||||
* @ORM\Column(type="boolean", nullable=false) | |||||
*/ | |||||
protected $isDisplayed; | |||||
public function __construct() | public function __construct() | ||||
{ | { | ||||
$this->__reductionPropertyConstruct(); | $this->__reductionPropertyConstruct(); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getIsDisplayed(): bool | |||||
{ | |||||
return $this->isDisplayed; | |||||
} | |||||
public function isDisplayed(): bool | |||||
{ | |||||
return $this->isDisplayed; | |||||
} | |||||
public function setIsDisplayed(bool $isDisplayed): self | |||||
{ | |||||
$this->isDisplayed = $isDisplayed; | |||||
return $this; | |||||
} | |||||
} | } |
public function addFilterByMerchantViaSectionRequired(RepositoryQueryInterface $query): StoreInterface | public function addFilterByMerchantViaSectionRequired(RepositoryQueryInterface $query): StoreInterface | ||||
{ | { | ||||
$this->addFilterByMerchantOptionnal($query); | |||||
$this->addFilterByMerchantViaSectionOptionnal($query); | |||||
if(!$this->isMerchantDefined()) { | if(!$this->isMerchantDefined()) { | ||||
throw new \ErrorException('Le Merchant doit être définie dans '.get_class($this)); | throw new \ErrorException('Le Merchant doit être définie dans '.get_class($this)); |
); | ); | ||||
} | } | ||||
public function selectSum(): self | public function selectSum(): self | ||||
{ | { | ||||
$this->joinProduct(); | $this->joinProduct(); |
use Lc\CaracoleBundle\Model\Distribution\DistributionInterface; | use Lc\CaracoleBundle\Model\Distribution\DistributionInterface; | ||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | ||||
use Lc\CaracoleBundle\Model\Order\OrderStatusModel; | use Lc\CaracoleBundle\Model\Order\OrderStatusModel; | ||||
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | |||||
use Lc\CaracoleBundle\Model\Product\ProductInterface; | use Lc\CaracoleBundle\Model\Product\ProductInterface; | ||||
use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface; | use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface; | ||||
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface; | use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface; | ||||
public function countValidOrderProductsOfDistributionsByProducts( | public function countValidOrderProductsOfDistributionsByProducts( | ||||
array $distributions, | array $distributions, | ||||
array $products, | array $products, | ||||
ProductFamilyInterface $productFamily, | |||||
$query = null | $query = null | ||||
): array { | ): array { | ||||
$query = $this->createDefaultQuery($query); | $query = $this->createDefaultQuery($query); | ||||
->selectSum() | ->selectSum() | ||||
->groupBy('distribution.cycleNumber, product.id'); | ->groupBy('distribution.cycleNumber, product.id'); | ||||
//TODO vérifier ou est utilisé cette fonction ??? | |||||
return $query->find(); | return $query->find(); | ||||
} | } | ||||
DistributionInterface $distribution, | DistributionInterface $distribution, | ||||
ProductInterface $product, | ProductInterface $product, | ||||
$query = null | $query = null | ||||
): ?string { | |||||
): float { | |||||
//TODO attention à vérifier | //TODO attention à vérifier | ||||
$query = $this->createQuery($query); | $query = $this->createQuery($query); | ||||
if ($result) { | if ($result) { | ||||
return $result['quantity']; | return $result['quantity']; | ||||
} | } | ||||
return null; | |||||
return 0; | |||||
} | } | ||||
public function isReductionCreditAllowAddToOrder( | public function isReductionCreditAllowAddToOrder( |
protected ProductFamilyRepositoryQuery $query; | protected ProductFamilyRepositoryQuery $query; | ||||
protected PriceSolver $priceSolver; | protected PriceSolver $priceSolver; | ||||
public function __construct(ProductFamilyRepositoryQuery $query, PriceSolver $priceSolver) | |||||
{ | |||||
public function __construct( | |||||
ProductFamilyRepositoryQuery $query, | |||||
PriceSolver $priceSolver | |||||
) { | |||||
$this->query = $query; | $this->query = $query; | ||||
$this->priceSolver = $priceSolver; | $this->priceSolver = $priceSolver; | ||||
} | } |
class ProductRepositoryQuery extends AbstractRepositoryQuery | class ProductRepositoryQuery extends AbstractRepositoryQuery | ||||
{ | { | ||||
protected bool $isJoinProductFamily =false; | |||||
protected bool $isJoinSections =false; | |||||
protected bool $isJoinProductFamilySectionProperties =false; | |||||
protected bool $isJoinProductFamily = false; | |||||
protected bool $isJoinSections = false; | |||||
protected bool $isJoinProductFamilySectionProperties = false; | |||||
public function __construct(ProductRepository $repository, PaginatorInterface $paginator) | public function __construct(ProductRepository $repository, PaginatorInterface $paginator) | ||||
{ | { | ||||
parent::__construct($repository, 'product', $paginator); | parent::__construct($repository, 'product', $paginator); | ||||
} | } | ||||
public function orderByDefault(): \Lc\SovBundle\Repository\AbstractRepositoryQuery | public function orderByDefault(): \Lc\SovBundle\Repository\AbstractRepositoryQuery | ||||
{ | { | ||||
return $this->orderBy('position', 'ASC'); | return $this->orderBy('position', 'ASC'); | ||||
} | } | ||||
public function joinProductFamily():self | |||||
public function joinProductFamily(): self | |||||
{ | { | ||||
if (!$this->isJoinProductFamily) { | if (!$this->isJoinProductFamily) { | ||||
$this->isJoinProductFamily = true; | $this->isJoinProductFamily = true; | ||||
return $this | return $this | ||||
->innerJoin('.productFamily', 'productFamily') | |||||
->addSelect('productFamily'); | |||||
->innerJoin('.productFamily', 'productFamily') | |||||
->addSelect('productFamily'); | |||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterBySection(SectionInterface $section):self | |||||
public function filterBySection(SectionInterface $section): self | |||||
{ | { | ||||
$this->joinProductFamilySectionProperties(false); | $this->joinProductFamilySectionProperties(false); | ||||
$this->andWhereSection('productFamilySectionProperties', $section); | $this->andWhereSection('productFamilySectionProperties', $section); | ||||
} | } | ||||
public function filterIsOnline():self | |||||
public function filterIsOnline(): self | |||||
{ | { | ||||
$this->joinProductFamily(); | $this->joinProductFamily(); | ||||
$this->andWhereStatus('productFamily', 1); | $this->andWhereStatus('productFamily', 1); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterIsOnlineAndOffline(): self | |||||
{ | |||||
$this->joinProductFamily(); | |||||
$this->andWhere('productFamily.status >= 0'); | |||||
$this->andWhere('.status >=0'); | |||||
return $this; | |||||
} | |||||
public function filterIsOnSale(): self | |||||
{ | |||||
$this->joinProductFamily(); | |||||
$this->andWhere('productFamily.saleStatus = 1'); | |||||
return $this; | |||||
} | |||||
public function filterIsOriginProduct():self | |||||
public function filterIsOriginProduct(): self | |||||
{ | { | ||||
$this->andWhere('.originProduct = 1'); | $this->andWhere('.originProduct = 1'); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterIsNotAvailableQuantitySupplierUnlimited():self | |||||
public function filterIsNotAvailableQuantitySupplierUnlimited(): self | |||||
{ | { | ||||
$this->andWhere('productFamily.availableQuantitySupplierUnlimited != 1'); | $this->andWhere('productFamily.availableQuantitySupplierUnlimited != 1'); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterAvailableQuantityNegative() :self | |||||
public function filterAvailableQuantityNegative(): self | |||||
{ | { | ||||
$this->andWhere( | $this->andWhere( | ||||
$this->query->expr()->orX( | |||||
$this->query->expr()->andX( | |||||
$this->query->expr()->orX( | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByProductFamily', | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByMeasure' | |||||
), | |||||
'productFamily.availableQuantity < 0 ' | |||||
), | |||||
$this->query->expr()->andX( | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByProduct', | |||||
'product.availableQuantity < 0 ' | |||||
) | |||||
$this->query->expr()->orX( | |||||
$this->query->expr()->andX( | |||||
$this->query->expr()->orX( | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByProductFamily', | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByMeasure' | |||||
), | |||||
'productFamily.availableQuantity < 0 ' | |||||
), | |||||
$this->query->expr()->andX( | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByProduct', | |||||
'product.availableQuantity < 0 ' | |||||
) | ) | ||||
) | |||||
); | ); | ||||
$this->setParameter( | $this->setParameter( | ||||
'behaviorCountStockByProductFamily', | |||||
ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY | |||||
'behaviorCountStockByProductFamily', | |||||
ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY | |||||
); | ); | ||||
$this->setParameter('behaviorCountStockByMeasure', ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE); | $this->setParameter('behaviorCountStockByMeasure', ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE); | ||||
$this->setParameter('behaviorCountStockByProduct', ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT); | $this->setParameter('behaviorCountStockByProduct', ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterAvailableQuantitySupplierNegative() :self | |||||
public function filterAvailableQuantitySupplierNegative(): self | |||||
{ | { | ||||
$this->andWhere( | $this->andWhere( | ||||
$this->query->expr()->orX( | |||||
$this->query->expr()->andX( | |||||
$this->query->expr()->orX( | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByProductFamily', | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByMeasure' | |||||
), | |||||
'productFamily.availableQuantitySupplier < 0 ' | |||||
), | |||||
$this->query->expr()->andX( | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByProduct', | |||||
'product.availableQuantitySupplier < 0 ' | |||||
) | |||||
$this->query->expr()->orX( | |||||
$this->query->expr()->andX( | |||||
$this->query->expr()->orX( | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByProductFamily', | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByMeasure' | |||||
), | |||||
'productFamily.availableQuantitySupplier < 0 ' | |||||
), | |||||
$this->query->expr()->andX( | |||||
'productFamily.behaviorCountStock LIKE :behaviorCountStockByProduct', | |||||
'product.availableQuantitySupplier < 0 ' | |||||
) | ) | ||||
) | |||||
); | ); | ||||
$this->setParameter( | $this->setParameter( | ||||
'behaviorCountStockByProductFamily', | |||||
ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY | |||||
'behaviorCountStockByProductFamily', | |||||
ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY | |||||
); | ); | ||||
$this->setParameter('behaviorCountStockByMeasure', ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE); | $this->setParameter('behaviorCountStockByMeasure', ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE); | ||||
$this->setParameter('behaviorCountStockByProduct', ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT); | $this->setParameter('behaviorCountStockByProduct', ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_PRODUCT); |
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
} | } |
{# @var field \EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto #} | |||||
{% import '@LcCaracole/admin/product/macro/product_family_macro.html.twig' as pfm %} | |||||
{% set section_current = section_container.resolver.getCurrent() %} | |||||
{% if section_current %} | |||||
{{ pfm.product_family_sales_statistic(order_shop_container.builder.getProductsSalesStatistic(section_current, entity.instance, 2), entity.instance) }} | |||||
{% endif %} |
{% extends '@LcCaracole/admin/product/macro/product_family_macro.html.twig' %} | |||||
{% macro product_family_sales_statistic(productsSalesStatistic, productFamily) %} | |||||
{% if productsSalesStatistic and productsSalesStatistic|length %} | |||||
<button type="button" data-product-family="{{ productFamily.id }}" | |||||
class="lc-show-products-sales-statistic btn btn-sm" | |||||
data-toggle="tooltip" title="{{ 'showHistorySales'|sov_trans_admin_action }}" | |||||
data-url="{{ ea_url({crudAction : 'showSalesStatistic', entityId: productFamily.id }) }}"> | |||||
{% for key, weekNumberQuantity in productsSalesStatistic['data']['total_sales']['data'] %} | |||||
<span class="text-success"> | |||||
<i class="fa fa-calendar"></i> | |||||
{{ productsSalesStatistic['label'][key] }}</span> | |||||
<span class="text-info"><i class="fa fa-shopping-basket"></i> | |||||
<strong> | |||||
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity }} | |||||
{% if productFamily and (productFamily.behaviorDisplaySale== constant('App\\Entity\\Product\\ProductFamily::BEHAVIOR_DISPLAY_SALE_BY_MEASURE')) %} | |||||
{{ productFamily.unit.unitReference }} | |||||
{% endif %} | |||||
</strong> | |||||
</span> | |||||
<br/> | |||||
{% endfor %} | |||||
</button> | |||||
{% endif %} | |||||
{% endmacro product_family_sales_statistic %} | |||||
{% macro autoresize_field(field) %} | {% macro autoresize_field(field) %} | ||||
<tr> | <tr> |
{% embed "@LcSov/adminlte/embed/modal.twig" %} | |||||
{% import '@LcCaracole/admin/product/macro/product_family_macro.html.twig' as pfm %} | |||||
{% block size %}modal-xl{% endblock %} | |||||
{% block id %}modal-products-sales-statistic{% endblock %} | |||||
{% block title %}Total ventes/semaines : {{ productFamily.title }}{% endblock %} | |||||
{% block body %} | |||||
<div class="row"> | |||||
<div class="col-10"> | |||||
{{ _self.btn_pss(productsSalesStatistic, productFamily, 'Global', 'total_sales') }} | |||||
{% if productFamily.activeProducts %} | |||||
{% for product in productFamily.products %} | |||||
{% if product.status >= 0 %} | |||||
{{ _self.btn_pss(productsSalesStatistic, productFamily, product.title , product.id ) }} | |||||
{% endif %} | |||||
{% endfor %} | |||||
{% endif %} | |||||
</div> | |||||
<div class="col-2"> | |||||
<h5>Stock actuel</h5> | |||||
{% include 'admin/product/field/product_family_available_quantity.html.twig' with {item:productFamily, value: productFamily.availableQuantity} %} | |||||
</div> | |||||
<div class="col-12"> | |||||
{{ _self.table_pss(productsSalesStatistic, productFamily, 'total_sales') }} | |||||
{% for product in productFamily.products %} | |||||
{% if product.status >= 0 %} | |||||
{{ _self.table_pss(productsSalesStatistic, productFamily, product.id) }} | |||||
{% endif %} | |||||
{% endfor %} | |||||
</div> | |||||
<div class="col-12"> | |||||
<canvas id="chart"></canvas> | |||||
</div> | |||||
</div> | |||||
{% endblock %} | |||||
{% block footer %}{% endblock %} | |||||
{% macro btn_pss(productsSalesStatistic,productFamily, label, propertyName) %} | |||||
<button style="margin-bottom: 10px;" type="button" data-property-name="{{ propertyName }}" | |||||
class="btn btn-sm btn-primary btn-products-sales-statistic"> | |||||
{{ label }} <br/> | |||||
{{ productsSalesStatistic['data'][propertyName]['average_period'] }} | |||||
{% if propertyName== 'total_sales' and productFamily and (productFamily.behaviorDisplaySale== constant('Lc\\CaracoleBundle\\Model\\Product\\ProductFamilyModel::BEHAVIOR_DISPLAY_SALE_BY_MEASURE')) %} | |||||
{{ productFamily.unit.unitReference }} | |||||
{% endif %} | |||||
<br/> | |||||
<small>(en moyenne)</small> | |||||
</button> | |||||
{% endmacro btn_pss %} | |||||
{% macro table_pss(productsSalesStatistic, productFamily, propertyName) %} | |||||
<div style="margin:20px 0;" class="table-products-sales-statistic" id="table-products-sales-statistic-{{ propertyName }}"> | |||||
<table class="table table-bordered table-striped"> | |||||
<tbody> | |||||
<tr> | |||||
<th class="text-success"> | |||||
<i class="fa fa-calendar"></i> Semaine | |||||
</th> | |||||
{% for weekNumber, weekNumberQuantity in productsSalesStatistic['data'][propertyName]['data'] %} | |||||
<td class="text-success align-right"> | |||||
{{ weekNumber }} | |||||
</td> | |||||
{% endfor %} | |||||
</tr> | |||||
<tr> | |||||
<th class="text-info"> | |||||
<i class="fa fa-shopping-basket"></i> Commandés | |||||
</th> | |||||
{% for weekNumber, weekNumberQuantity in productsSalesStatistic['data'][propertyName]['data'] %} | |||||
<td class="text-info align-right"> | |||||
<strong> | |||||
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity }} | |||||
{% if propertyName== 'total_sales' and productFamily and (productFamily.behaviorDisplaySale== constant('Lc\\CaracoleBundle\\Model\\Product\\ProductFamilyModel::BEHAVIOR_DISPLAY_SALE_BY_MEASURE')) %} | |||||
{{ productFamily.unit.unitReference }} | |||||
{% endif %} | |||||
</strong> | |||||
</td> | |||||
{% endfor %} | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
{% endmacro table_pss %} | |||||
{% endembed %} | |||||
$text = ''; | $text = ''; | ||||
if ($orderProductReductionCatalog->getUnit() == 'amount') { | if ($orderProductReductionCatalog->getUnit() == 'amount') { | ||||
$text .= '- ' . $orderProductReductionCatalog->getValue() . ' €'; | |||||
$text .= '- ' . number_format($orderProductReductionCatalog->getValue(),2) . ' €'; | |||||
} | } | ||||
if ($orderProductReductionCatalog->getUnit() == 'percent') { | if ($orderProductReductionCatalog->getUnit() == 'percent') { | ||||
$text .= '- ' . $orderProductReductionCatalog->getValue() . ' %'; | |||||
$text .= '- ' . number_format($orderProductReductionCatalog->getValue(),2) . ' %'; | |||||
} | } | ||||
return $text; | return $text; |
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | ||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | ||||
use Lc\CaracoleBundle\Solver\Price\PriceSolver; | |||||
use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver; | use Lc\CaracoleBundle\Solver\Product\ProductFamilySolver; | ||||
use Lc\CaracoleBundle\Solver\Product\ProductSolver; | use Lc\CaracoleBundle\Solver\Product\ProductSolver; | ||||
{ | { | ||||
protected ProductSolver $productSolver; | protected ProductSolver $productSolver; | ||||
protected ProductFamilySolver $productFamilySolver; | protected ProductFamilySolver $productFamilySolver; | ||||
public function __construct(ProductSolver $productSolver, ProductFamilySolver $productFamilySolver) | |||||
{ | |||||
protected OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver; | |||||
protected PriceSolver $priceSolver; | |||||
public function __construct( | |||||
ProductSolver $productSolver, | |||||
ProductFamilySolver $productFamilySolver, | |||||
OrderProductReductionCatalogSolver $orderProductReductionCatalogSolver, | |||||
PriceSolver $priceSolver | |||||
) { | |||||
$this->productSolver = $productSolver; | $this->productSolver = $productSolver; | ||||
$this->productFamilySolver = $productFamilySolver; | $this->productFamilySolver = $productFamilySolver; | ||||
$this->orderProductReductionCatalogSolver = $orderProductReductionCatalogSolver; | |||||
$this->priceSolver = $priceSolver; | |||||
} | |||||
public function compare(OrderProductInterface $orderProduct1, OrderProductInterface $orderProduct2) | |||||
{ | |||||
return $orderProduct1->getProduct()->getId() == $orderProduct2->getProduct()->getId() | |||||
&& $orderProduct1->getRedelivery() == $orderProduct2->getRedelivery() | |||||
&& (string)$this->priceSolver->getPrice($orderProduct1) | |||||
== (string)$this->priceSolver->getPrice($orderProduct2) | |||||
&& $this->orderProductReductionCatalogSolver->compare( | |||||
$orderProduct1->getOrderProductReductionCatalog(), | |||||
$orderProduct2->getOrderProductReductionCatalog() | |||||
); | |||||
} | } | ||||
// groupOrderProductsByProductFamily | // groupOrderProductsByProductFamily | ||||
// simple | // simple | ||||
if ($productFamily->getBehaviorAddToCart() == 'simple') { | if ($productFamily->getBehaviorAddToCart() == 'simple') { | ||||
if ($productFamily->getActiveProducts()) { | |||||
$title .= $titleProduct; | |||||
if ($this->productFamilySolver->hasProductsWithVariousWeight($productFamily)) { | |||||
$title .= ' - ' . $this->productSolver->getQuantityLabelInherited($product); | |||||
if($orderProduct->getOrderPackProduct()) { | |||||
$title .= $this->productFamilySolver->getTitleProduct($product); | |||||
} | |||||
else { | |||||
if ($productFamily->getActiveProducts()) { | |||||
$title .= $titleProduct; | |||||
if ($this->productFamilySolver->hasProductsWithVariousWeight($productFamily)) { | |||||
$title .= ' - ' . $this->productSolver->getQuantityLabelInherited($product); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
]; | ]; | ||||
} | } | ||||
public function isEmpty(OrderShopInterface $orderShop): bool | |||||
{ | |||||
return $orderShop->getOrderProducts()->isEmpty(); | |||||
} | |||||
public function countQuantities(OrderShopInterface $orderShop): int | public function countQuantities(OrderShopInterface $orderShop): int | ||||
{ | { | ||||
return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts()); | return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts()); | ||||
OrderShopInterface $orderShop, | OrderShopInterface $orderShop, | ||||
ProductInterface $product, | ProductInterface $product, | ||||
$byWeight = false | $byWeight = false | ||||
): int { | |||||
): float { | |||||
$quantity = 0; | $quantity = 0; | ||||
$productFamily = $product->getProductFamily(); | $productFamily = $product->getProductFamily(); | ||||
$behaviorCountStock = $productFamily->getBehaviorCountStock(); | $behaviorCountStock = $productFamily->getBehaviorCountStock(); | ||||
return false; | return false; | ||||
} | } | ||||
$productFamily = $product->getProductFamily(); | $productFamily = $product->getProductFamily(); | ||||
$quantityAsked = $quantityOrder; | $quantityAsked = $quantityOrder; | ||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
public function getTotalWithReduction(OrderProductInterface $orderProduct) | |||||
public function getTotalWithReduction(OrderProductInterface $orderProduct, bool $round = true) | |||||
{ | { | ||||
return $this->applyReductionCatalog( | return $this->applyReductionCatalog( | ||||
$orderProduct, | $orderProduct, | ||||
$this->getTotal($orderProduct), | $this->getTotal($orderProduct), | ||||
$this->getTotalWithTax($orderProduct), | |||||
$this->getTotalWithTax($orderProduct, $round), | |||||
$orderProduct->getQuantityOrder(), | $orderProduct->getQuantityOrder(), | ||||
null, | null, | ||||
false | |||||
false, | |||||
$round | |||||
); | ); | ||||
} | } | ||||
public function getTotalWithTax(OrderProductInterface $orderProduct) | |||||
public function getTotalWithTax(OrderProductInterface $orderProduct, $round = true) | |||||
{ | { | ||||
return $this->applyTax( | return $this->applyTax( | ||||
$this->getTotal($orderProduct), | $this->getTotal($orderProduct), | ||||
$orderProduct->getTaxRate()->getValue() | |||||
$orderProduct->getTaxRate()->getValue(), | |||||
$round | |||||
); | ); | ||||
} | } | ||||
public function getTotalWithTaxAndReduction(OrderProductInterface $orderProduct) | |||||
public function getTotalWithTaxAndReduction(OrderProductInterface $orderProduct, bool $round = true) | |||||
{ | { | ||||
return $this->applyReductionCatalog( | return $this->applyReductionCatalog( | ||||
$orderProduct, | $orderProduct, | ||||
$this->getTotal($orderProduct), | $this->getTotal($orderProduct), | ||||
$this->getTotalWithTax($orderProduct), | |||||
$orderProduct->getQuantityOrder() | |||||
$this->getTotalWithTax($orderProduct, $round), | |||||
$orderProduct->getQuantityOrder(), | |||||
null, | |||||
true, | |||||
$round | |||||
); | ); | ||||
} | } | ||||
$total = 0; | $total = 0; | ||||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | foreach ($orderShop->getOrderProducts() as $orderProduct) { | ||||
$total += $this->orderProductPriceResolver->getTotalWithReduction($orderProduct); | |||||
$total += $this->orderProductPriceResolver->getTotalWithReduction($orderProduct, false); | |||||
} | } | ||||
return $this->round($total); | return $this->round($total); | ||||
} | } | ||||
{ | { | ||||
$total = 0; | $total = 0; | ||||
foreach ($orderProducts as $orderProduct) { | foreach ($orderProducts as $orderProduct) { | ||||
//TODO : ici c'est pas possibble d'arrondir sinon ça fou une merde du tonnerre de de dieu !!!! | |||||
$total += $this->orderProductPriceResolver->getTotalWithTaxAndReduction($orderProduct); | $total += $this->orderProductPriceResolver->getTotalWithTaxAndReduction($orderProduct); | ||||
} | } | ||||
trait PriceSolverTrait | trait PriceSolverTrait | ||||
{ | { | ||||
public function applyTax($price, $taxRateValue) | |||||
public function applyTax($price, $taxRateValue, $round = true) | |||||
{ | { | ||||
return $this->round($this->applyPercent($price, $taxRateValue)); | |||||
$price = $this->applyPercent($price, $taxRateValue); | |||||
if($round) { | |||||
return $this->round($price); | |||||
} | |||||
return $price; | |||||
} | } | ||||
public function applyReductionPercent($price, $percentage) | public function applyReductionPercent($price, $percentage) |
public function getSolver(ProductPropertyInterface $product) | public function getSolver(ProductPropertyInterface $product) | ||||
{ | { | ||||
if($product instanceof ProductFamilyInterface) { | |||||
if ($product instanceof ProductFamilyInterface) { | |||||
return $this->productFamilySolver; | return $this->productFamilySolver; | ||||
} | } | ||||
if($product instanceof ProductInterface) { | |||||
if ($product instanceof ProductInterface) { | |||||
return $this->productSolver; | return $this->productSolver; | ||||
} | } | ||||
} | } | ||||
return $solver->getPriceInherited($product); | return $solver->getPriceInherited($product); | ||||
} elseif ($solver->getBehaviorPriceInherited($product) == 'by-reference-unit') { | } elseif ($solver->getBehaviorPriceInherited($product) == 'by-reference-unit') { | ||||
if ($solver->getQuantityInherited($product) > 0) { | if ($solver->getQuantityInherited($product) > 0) { | ||||
return $solver->getPriceByRefUnitInherited($product) * ($solver->getQuantityInherited($product | |||||
return $solver->getPriceByRefUnitInherited($product) * ($solver->getQuantityInherited( | |||||
$product | |||||
) / $solver->getUnitInherited($product)->getCoefficient()); | ) / $solver->getUnitInherited($product)->getCoefficient()); | ||||
} else { | } else { | ||||
return 0; | return 0; | ||||
); | ); | ||||
} | } | ||||
public function getPriceByRefUnit(ProductPropertyInterface $product) | public function getPriceByRefUnit(ProductPropertyInterface $product) | ||||
{ | { | ||||
$solver = $this->getSolver($product); | $solver = $this->getSolver($product); | ||||
); | ); | ||||
} | } | ||||
public function getPriceWithTaxAndReduction(ProductPropertyInterface $product) | public function getPriceWithTaxAndReduction(ProductPropertyInterface $product) | ||||
{ | { | ||||
//TODO voir différence entre prix ici et dans tableau décli | |||||
return $this->applyReductionCatalog( | return $this->applyReductionCatalog( | ||||
$product, | $product, | ||||
$this->getPrice($product), | $this->getPrice($product), | ||||
} | } | ||||
//Bridge pour applyReductionCatalog qui ne peut pas être appeler à cause du call | //Bridge pour applyReductionCatalog qui ne peut pas être appeler à cause du call | ||||
public function getPriceWithTaxByReduction(ProductPropertyInterface $product, ReductionCatalogInterface $reductionCatalog) | |||||
{ | |||||
public function getPriceWithTaxByReduction( | |||||
ProductPropertyInterface $product, | |||||
ReductionCatalogInterface $reductionCatalog | |||||
) { | |||||
return $this->applyReductionCatalog( | return $this->applyReductionCatalog( | ||||
$product, | |||||
$this->getPrice($product), | |||||
$this->getPriceWithTax($product), | |||||
1, | |||||
$reductionCatalog | |||||
$product, | |||||
$this->getPrice($product), | |||||
$this->getPriceWithTax($product), | |||||
1, | |||||
$reductionCatalog | |||||
); | ); | ||||
} | } | ||||
public function getPriceByRefUnitWithTaxAndReduction(ProductPropertyInterface $product) | public function getPriceByRefUnitWithTaxAndReduction(ProductPropertyInterface $product) | ||||
{ | { | ||||
return ($this->getPriceByRefUnitWithTax($product) * $this->getPriceWithTaxAndReduction($product)) | |||||
/ $this->getPriceWithTax($product); | |||||
} | |||||
$priceWithTax = $this->getPriceWithTax($product); | |||||
if ($priceWithTax) { | |||||
return $this->round( | |||||
($this->getPriceByRefUnitWithTax($product) * $this->getPriceWithTaxAndReduction($product)) | |||||
/ $priceWithTax | |||||
); | |||||
} | |||||
return 0; | |||||
} | |||||
public function getBuyingPrice(ProductPropertyInterface $product) | public function getBuyingPrice(ProductPropertyInterface $product) | ||||
{ | { | ||||
return $solver->getBuyingPriceInherited($product); | return $solver->getBuyingPriceInherited($product); | ||||
} elseif ($solver->getBehaviorPriceInherited($product) == 'by-reference-unit') { | } elseif ($solver->getBehaviorPriceInherited($product) == 'by-reference-unit') { | ||||
if ($solver->getQuantityInherited($product) > 0) { | if ($solver->getQuantityInherited($product) > 0) { | ||||
return $solver->getBuyingPriceByRefUnitInherited($product) * ($solver->getQuantityInherited($product | |||||
return $solver->getBuyingPriceByRefUnitInherited($product) * ($solver->getQuantityInherited( | |||||
$product | |||||
) / $solver->getUnitInherited($product)->getCoefficient()); | ) / $solver->getUnitInherited($product)->getCoefficient()); | ||||
} else { | } else { | ||||
return 0; | return 0; | ||||
{ | { | ||||
return $this->round($this->getPriceWithTax($product) / $this->getBuyingPrice($product)); | return $this->round($this->getPriceWithTax($product) / $this->getBuyingPrice($product)); | ||||
} | } | ||||
} | } | ||||
use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface; | 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\ProductFamilySectionPropertyInterface; | |||||
use Lc\CaracoleBundle\Model\Product\ProductInterface; | use Lc\CaracoleBundle\Model\Product\ProductInterface; | ||||
use Lc\CaracoleBundle\Model\Reduction\ReductionCatalogInterface; | use Lc\CaracoleBundle\Model\Reduction\ReductionCatalogInterface; | ||||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | use Lc\CaracoleBundle\Model\Section\SectionInterface; | ||||
protected ProductFamilySectionPropertySolver $productFamilySectionPropertySolver; | protected ProductFamilySectionPropertySolver $productFamilySectionPropertySolver; | ||||
protected ProductCategorySolver $productCategorySolver; | protected ProductCategorySolver $productCategorySolver; | ||||
public function __construct(ProductSolver $productSolver, ProductFamilySectionPropertySolver $productFamilySectionPropertySolver, ProductCategorySolver $productCategorySolver) | |||||
{ | |||||
public function __construct( | |||||
ProductSolver $productSolver, | |||||
ProductFamilySectionPropertySolver $productFamilySectionPropertySolver, | |||||
ProductCategorySolver $productCategorySolver | |||||
) { | |||||
$this->productSolver = $productSolver; | $this->productSolver = $productSolver; | ||||
$this->productFamilySectionPropertySolver = $productFamilySectionPropertySolver; | $this->productFamilySectionPropertySolver = $productFamilySectionPropertySolver; | ||||
$this->productCategorySolver = $productCategorySolver; | $this->productCategorySolver = $productCategorySolver; | ||||
]; | ]; | ||||
} | } | ||||
public function countProductFamiliesOrganizedByParentCategory(array $categories): int | public function countProductFamiliesOrganizedByParentCategory(array $categories): int | ||||
{ | { | ||||
$count = 0; | $count = 0; | ||||
$productCategories = $productFamily->getProductCategories(); | $productCategories = $productFamily->getProductCategories(); | ||||
if (count($productCategories) > 0) { | if (count($productCategories) > 0) { | ||||
foreach ($productCategories as $productCategory) { | foreach ($productCategories as $productCategory) { | ||||
if($productCategory->getSection()->getId() == $section->getId() | |||||
if ($productCategory->getSection()->getId() == $section->getId() | |||||
&& $productCategory->getParent() !== null) { | && $productCategory->getParent() !== null) { | ||||
return $productCategory->getParent(); | return $productCategory->getParent(); | ||||
} | } | ||||
} | } | ||||
public function getQuantityInherited(ProductFamilyInterface $productFamily): ?float | public function getQuantityInherited(ProductFamilyInterface $productFamily): ?float | ||||
{ | { | ||||
if($productFamily->getQuantity()){ | |||||
if ($productFamily->getQuantity()) { | |||||
return $productFamily->getQuantity(); | return $productFamily->getQuantity(); | ||||
}else{ | |||||
} else { | |||||
return 1; | return 1; | ||||
} | } | ||||
} | } | ||||
$strLabels = ''; | $strLabels = ''; | ||||
$qualityLabelArray = $productFamily->getQualityLabels()->toArray(); | $qualityLabelArray = $productFamily->getQualityLabels()->toArray(); | ||||
foreach($qualityLabelArray as $index => $qualityLabel) { | |||||
foreach ($qualityLabelArray as $index => $qualityLabel) { | |||||
$strLabels .= $qualityLabel->getTitle(); | $strLabels .= $qualityLabel->getTitle(); | ||||
if ($index !== array_key_last($qualityLabelArray)) { | if ($index !== array_key_last($qualityLabelArray)) { | ||||
} | } | ||||
public function isCategoriesOnlineInSection(ProductFamilyInterface $productFamily, SectionInterface $section):bool | |||||
public function isCategoriesOnlineInSection(ProductFamilyInterface $productFamily, SectionInterface $section): bool | |||||
{ | { | ||||
$isCategoriesOnlineInSection =false; | |||||
foreach ($productFamily->getProductCategories() as $productCatgory){ | |||||
if($productCatgory->getSection() === $section && $this->productCategorySolver->isOnline($productCatgory)){ | |||||
$isCategoriesOnlineInSection = false; | |||||
foreach ($productFamily->getProductCategories() as $productCatgory) { | |||||
if ($productCatgory->getSection() === $section && $this->productCategorySolver->isOnline($productCatgory)) { | |||||
$isCategoriesOnlineInSection = true; | $isCategoriesOnlineInSection = true; | ||||
} | } | ||||
} | } | ||||
return $isCategoriesOnlineInSection; | return $isCategoriesOnlineInSection; | ||||
} | } | ||||
public function getTitleProduct(ProductInterface $product) | |||||
{ | |||||
$productFamily = $product->getProductFamily(); | |||||
$title = $product->getProductFamily()->getTitle(); | |||||
if ($product->getTitle() && strlen($product->getTitle())) { | |||||
$title .= ' - ' . $product->getTitle(); | |||||
} | |||||
if ($this->hasProductsWithVariousWeight($productFamily)) { | |||||
$title .= ' - ' . $this->productSolver->getQuantityLabelInherited($product); | |||||
} | |||||
return $title; | |||||
} | |||||
public function isReductionCatalogDisplayed(ProductFamilyInterface $productFamily): bool | |||||
{ | |||||
return $this->hasReductionCatalog($productFamily) && $productFamily->getReductionCatalog()->isDisplayed(); | |||||
} | |||||
public function hasReductionCatalog(ProductFamilyInterface $productFamily): bool | |||||
{ | |||||
return (bool)$productFamily->getReductionCatalog(); | |||||
} | |||||
} | } | ||||
} | } | ||||
$allCategoriesSalesOff = true; | $allCategoriesSalesOff = true; | ||||
$unavailableSpecificDay = false; | |||||
foreach ($product->getProductFamily()->getProductCategories() as $category) { | foreach ($product->getProductFamily()->getProductCategories() as $category) { | ||||
if ($category->getParent()) { | if ($category->getParent()) { | ||||
$allCategoriesSalesOff = false; | $allCategoriesSalesOff = false; | ||||
} | } | ||||
} | } | ||||
// specific day | |||||
// @TODO : spécifique pdl ? | |||||
$displaySpecificDay = $category->getDisplaySpecificDay(); | |||||
if ($displaySpecificDay && $displaySpecificDay != date('N')) { | |||||
$unavailableSpecificDay = true; | |||||
} | |||||
} | } | ||||
if ($allCategoriesSalesOff) { | if ($allCategoriesSalesOff) { | ||||
return false; | return false; | ||||
} | } | ||||
if ($unavailableSpecificDay) { | |||||
return false; | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
public function getFullTitle(ProductInterface $product) | |||||
{ | |||||
if ($product->getTitle()) { | |||||
$endOfTitle = $product->getTitle(); | |||||
} else { | |||||
$endOfTitle = $this->getQuantityInherited($product).' '.$this->getUnitInherited($product)->getWordingShort(); | |||||
} | |||||
return $product->getProductFamily()->getTitle(). ' - '. $endOfTitle; | |||||
} | |||||
public function getQuantityInherited(ProductInterface $product) | public function getQuantityInherited(ProductInterface $product) | ||||
{ | { | ||||
if ($product->getQuantity()) { | if ($product->getQuantity()) { |
{ | { | ||||
public function getTypeChoices($context = 'backend'): array | public function getTypeChoices($context = 'backend'): array | ||||
{ | { | ||||
$choices = parent::getTypeChoices(); | |||||
$choices = parent::getTypeChoices($context); | |||||
$choicesProduct = [ | $choicesProduct = [ | ||||
TicketModel::TYPE_PRODUCT_UNAVAILABLE, | TicketModel::TYPE_PRODUCT_UNAVAILABLE, | ||||
TicketModel::TYPE_PRODUCT_ERROR | TicketModel::TYPE_PRODUCT_ERROR |
'label' => 'Total ventes' | 'label' => 'Total ventes' | ||||
] | ] | ||||
); | ); | ||||
foreach ($this->productFamily->getProducts() as $product) { | foreach ($this->productFamily->getProducts() as $product) { | ||||
$this->productIds[$product->getId()] = $product; | |||||
$this->addProperty( | |||||
$product->getId(), | |||||
[ | |||||
'label' => $product->getTitle() | |||||
] | |||||
); | |||||
if($product->getId()) { | |||||
$this->productIds[$product->getId()] = $product; | |||||
$this->addProperty( | |||||
$product->getId(), | |||||
[ | |||||
'label' => $product->getTitle() | |||||
] | |||||
); | |||||
} | |||||
} | } | ||||
} | } | ||||
{ | { | ||||
$countsOrderedByCyclesAndProducts = $orderShopStore->countValidOrderProductsOfDistributionsByProducts( | $countsOrderedByCyclesAndProducts = $orderShopStore->countValidOrderProductsOfDistributionsByProducts( | ||||
$this->distributionList, | $this->distributionList, | ||||
$this->productIds | |||||
$this->productIds, | |||||
$this->productFamily | |||||
); | ); | ||||
foreach ($countsOrderedByCyclesAndProducts as $result) { | foreach ($countsOrderedByCyclesAndProducts as $result) { |