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 = null): OrderProductInterface | |||||
{ | |||||
if(!$orderProduct->getOrderProductReductionCatalog()) { | |||||
if (is_null($productFamily)) { | |||||
$productFamily = $orderProduct->getProduct()->getProductFamily(); | |||||
} | |||||
$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\Resolver\OpeningResolver; | 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; | ||||
protected CreditHistoryBuilder $creditHistoryBuilder; | protected CreditHistoryBuilder $creditHistoryBuilder; | ||||
protected FlashBagTranslator $flashBagTranslator; | protected FlashBagTranslator $flashBagTranslator; | ||||
protected OrderShopFactory $orderShopFactory; | protected OrderShopFactory $orderShopFactory; | ||||
protected OrderProductSolver $orderProductSolver; | |||||
public function __construct( | public function __construct( | ||||
EntityManagerInterface $entityManager, | EntityManagerInterface $entityManager, | ||||
MerchantResolver $merchantResolver, | MerchantResolver $merchantResolver, | ||||
CreditHistoryBuilder $creditHistoryBuilder, | CreditHistoryBuilder $creditHistoryBuilder, | ||||
FlashBagTranslator $flashBagTranslator, | FlashBagTranslator $flashBagTranslator, | ||||
OrderShopFactory $orderShopFactory | |||||
OrderShopFactory $orderShopFactory, | |||||
OrderProductSolver $orderProductSolver | |||||
) { | ) { | ||||
$this->entityManager = $entityManager; | $this->entityManager = $entityManager; | ||||
$this->orderShopStore = $orderShopStore; | $this->orderShopStore = $orderShopStore; | ||||
$this->creditHistoryBuilder = $creditHistoryBuilder; | $this->creditHistoryBuilder = $creditHistoryBuilder; | ||||
$this->flashBagTranslator = $flashBagTranslator; | $this->flashBagTranslator = $flashBagTranslator; | ||||
$this->orderShopFactory = $orderShopFactory; | $this->orderShopFactory = $orderShopFactory; | ||||
$this->orderProductSolver = $orderProductSolver; | |||||
} | } | ||||
public function create( | public function create( | ||||
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); | |||||
$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); | |||||
} | |||||
} | |||||
$this->orderProductBuilder->init($orderProductAdd); | |||||
$this->orderProductBuilder->initReductionCatalog($orderShop->getSection(), $orderProductAdd); | |||||
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) | ||||
{ | { | ||||
$debug = ''; | $debug = ''; |
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; | ||||
$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->addOrderProductApply($orderShop, $orderProduct); | |||||
} | |||||
public function addOrderProductApply(OrderShopInterface $orderShop, OrderProductInterface $orderProduct): void | |||||
{ | |||||
if ($orderProduct->getQuantityOrder() > 0) { | |||||
$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") | ||||
*/ | */ |
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); | |||||
} | |||||
} | |||||
}*/ | |||||
} | |||||
} |
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 $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 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 ??? | |||||
dump($query->find()); | |||||
return $query->find(); | return $query->find(); | ||||
} | } | ||||
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; | ||||
} | } | ||||
return $query; | return $query; | ||||
} | } | ||||
public function isReductionCatalogDisplayed(ProductFamilyInterface $productFamily): bool | |||||
{ | |||||
$reductionCatalog = $this->reductionCatalogStore->setMerchant($this->merchant) | |||||
->getByProductFamily($productFamily); | |||||
return $this->hasReductionCatalog($productFamily) && $reductionCatalog->isDisplayed(); | |||||
} | |||||
public function hasReductionCatalog(ProductFamilyInterface $productFamily): bool | |||||
{ | |||||
$reductionCatalog = $this->reductionCatalogStore->setMerchant($this->merchant) | |||||
->getByProductFamily($productFamily); | |||||
return (bool)$reductionCatalog; | |||||
} | |||||
public function getByParentCategory( | public function getByParentCategory( | ||||
ProductCategoryInterface $parentCategory, | ProductCategoryInterface $parentCategory, | ||||
$user = null, | $user = null, |
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 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); |
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()); | ||||
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) { | ||||
$total += $this->orderProductPriceResolver->getTotalWithTaxAndReduction($orderProduct); | |||||
$total += $this->orderProductPriceResolver->getTotalWithTaxAndReduction($orderProduct, false); | |||||
} | } | ||||
return $this->round($total); | return $this->round($total); |
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; | |||||
} | |||||
} | } | ||||
} | } | ||||
$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 |
{ | { | ||||
$countsOrderedByCyclesAndProducts = $orderShopStore->countValidOrderProductsOfDistributionsByProducts( | $countsOrderedByCyclesAndProducts = $orderShopStore->countValidOrderProductsOfDistributionsByProducts( | ||||
$this->distributionList, | $this->distributionList, | ||||
$this->productIds | |||||
$this->productIds, | |||||
$this->productFamily | |||||
); | ); | ||||
foreach ($countsOrderedByCyclesAndProducts as $result) { | foreach ($countsOrderedByCyclesAndProducts as $result) { |