@@ -4,15 +4,15 @@ namespace Lc\CaracoleBundle\Builder\File; | |||
use Lc\CaracoleBundle\Model\File\DocumentInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||
use Lc\CaracoleBundle\Resolver\Reference\DocumentReferenceResolver; | |||
use Lc\CaracoleBundle\Generator\Reference\DocumentReferenceGenerator; | |||
class DocumentBuilder | |||
{ | |||
protected DocumentReferenceResolver $documentReferenceResolver; | |||
protected DocumentReferenceGenerator $documentReferenceGenerator; | |||
public function __construct(DocumentReferenceResolver $documentReferenceResolver) | |||
public function __construct(DocumentReferenceGenerator $documentReferenceGenerator) | |||
{ | |||
$this->documentReferenceResolver = $documentReferenceResolver; | |||
$this->documentReferenceGenerator = $documentReferenceGenerator; | |||
} | |||
public function initFromOrderShop(DocumentInterface $document, OrderShopInterface $orderShop) | |||
@@ -20,7 +20,7 @@ class DocumentBuilder | |||
$merchantAddress = $orderShop->getMerchant()->getAddress(); | |||
$buyerAddress = $orderShop->getInvoiceAddress(); | |||
$document->setReference($this->documentReferenceResolver->buildReference($orderShop->getMerchant())) ; | |||
$document->setReference($this->documentReferenceGenerator->buildReference($orderShop->getMerchant())) ; | |||
$document->setMerchantAddress($merchantAddress); | |||
$document->setBuyerAddress($buyerAddress); | |||
$document->setMerchantAddressText($merchantAddress->getSummary()); |
@@ -2,16 +2,25 @@ | |||
namespace Lc\CaracoleBundle\Builder\Order; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | |||
use Lc\CaracoleBundle\Repository\Order\OrderProductStore; | |||
use Lc\CaracoleBundle\Resolver\Price\PriceResolver; | |||
class OrderProductBuilder | |||
{ | |||
protected EntityManagerInterface $entityManager; | |||
protected PriceResolver $priceResolver; | |||
protected OrderProductStore $orderProductStore; | |||
public function __construct(PriceResolver $priceResolver) | |||
{ | |||
public function __construct( | |||
EntityManagerInterface $entityManager, | |||
PriceResolver $priceResolver, | |||
OrderProductStore $orderProductStore | |||
) { | |||
$this->entityManager = $entityManager; | |||
$this->priceResolver = $priceResolver; | |||
$this->orderProductStore = $orderProductStore; | |||
} | |||
public function init(OrderProductInterface $orderProduct) |
@@ -15,6 +15,7 @@ use Lc\CaracoleBundle\Factory\Order\OrderStatusHistoryFactory; | |||
use Lc\CaracoleBundle\Model\File\DocumentModel; | |||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderStatusInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderStatusModel; | |||
use Lc\CaracoleBundle\Model\Product\ProductFamilyModel; | |||
use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface; | |||
@@ -27,6 +28,8 @@ use Lc\CaracoleBundle\Repository\Order\OrderStatusStore; | |||
use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore; | |||
use Lc\CaracoleBundle\Resolver\Price\PriceResolver; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; | |||
class OrderShopBuilder | |||
{ | |||
@@ -37,6 +40,8 @@ class OrderShopBuilder | |||
protected PriceResolver $priceResolver; | |||
protected OrderProductBuilder $orderProductBuilder; | |||
protected DocumentBuilder $documentBuilder; | |||
protected EventDispatcherInterface $eventDispatcher; | |||
protected FlashBagInterface $flashBag; | |||
public function __construct( | |||
EntityManagerInterface $entityManager, | |||
@@ -46,7 +51,9 @@ class OrderShopBuilder | |||
ProductFamilyStore $productFamilyStore, | |||
OrderProductBuilder $orderProductBuilder, | |||
DocumentBuilder $documentBuilder, | |||
PriceResolver $priceResolver | |||
PriceResolver $priceResolver, | |||
EventDispatcherInterface $eventDispatcher, | |||
FlashBagInterface $flashBag | |||
) { | |||
$this->entityManager = $entityManager; | |||
$this->orderShopStore = $orderShopStore; | |||
@@ -56,6 +63,8 @@ class OrderShopBuilder | |||
$this->orderProductBuilder = $orderProductBuilder; | |||
$this->documentBuilder = $documentBuilder; | |||
$this->priceResolver = $priceResolver; | |||
$this->eventDispatcher = $eventDispatcher; | |||
$this->flashBag = $flashBag; | |||
} | |||
public function create( | |||
@@ -91,28 +100,46 @@ class OrderShopBuilder | |||
return $cart; | |||
} | |||
public function changeOrderStatus(OrderShopInterface $orderShop, string $alias) | |||
public function changeOrderStatus(OrderShopInterface $orderShop, string $alias, bool $forceByAdmin = false) | |||
{ | |||
$orderStatus = $this->orderStatusStore->getRepositoryQuery()->findOneByAlias($alias); | |||
if ($orderShop->getOrderStatus() === null | |||
|| $orderShop->getOrderStatus()->getNextStatusAllowed()->contains($orderStatus)) { | |||
$this->eventDispatcher->dispatch( | |||
new OrderShopChangeStatusEvent($orderShop, $orderStatus), | |||
OrderShopChangeStatusEvent::PRE_CHANGE_STATUS | |||
); | |||
if ($orderStatus) { | |||
if ($orderShop->getOrderStatus() === null | |||
|| $orderShop->getOrderStatus()->getNextStatusAllowed()->contains($orderStatus)) { | |||
$orderShop->setOrderStatusProtected($orderStatus); | |||
$orderStatusHistoryFactory = new OrderStatusHistoryFactory(); | |||
$orderStatusHistory = $orderStatusHistoryFactory->create($orderShop, $orderStatus); | |||
$orderShop->addOrderStatusHistory($orderStatusHistory); | |||
$this->applyChangeOrderStatus($orderShop, $orderStatus, $forceByAdmin); | |||
} | |||
} else { | |||
throw new \ErrorException('La statut demandé n\'existe pas.'); | |||
} | |||
return $orderShop; | |||
} | |||
public function applyChangeOrderStatus( | |||
OrderShopInterface $orderShop, | |||
OrderStatusInterface $orderStatus, | |||
bool $forceByAdmin = false | |||
) { | |||
$this->eventDispatcher->dispatch( | |||
new OrderShopChangeStatusEvent($orderShop, $orderStatus, $forceByAdmin), | |||
OrderShopChangeStatusEvent::PRE_CHANGE_STATUS | |||
); | |||
$orderShop->setOrderStatusProtected($orderStatus); | |||
$orderStatusHistoryFactory = new OrderStatusHistoryFactory(); | |||
$orderStatusHistory = $orderStatusHistoryFactory->create($orderShop, $orderStatus); | |||
$orderShop->addOrderStatusHistory($orderStatusHistory); | |||
$this->eventDispatcher->dispatch( | |||
new OrderShopChangeStatusEvent($orderShop, $orderStatus, $forceByAdmin), | |||
OrderShopChangeStatusEvent::POST_CHANGE_STATUS | |||
); | |||
} | |||
public function addOrderProduct( | |||
OrderShopInterface $orderShop, | |||
OrderProductInterface $orderProductAdd, | |||
@@ -282,18 +309,16 @@ class OrderShopBuilder | |||
$orderReductionCartFactory = new OrderReductionCartFactory(); | |||
$orderReductionCart = $orderReductionCartFactory->create($orderShop, $reductionCart); | |||
$orderShop->addOrderReductionCart($orderReductionCart) ; | |||
$orderShop->addOrderReductionCart($orderReductionCart); | |||
if($this->orderShopStore->isPositiveAmount($orderShop) | |||
if ($this->orderShopStore->isPositiveAmount($orderShop) | |||
&& $this->isPositiveAmountRemainingToBePaid($orderShop)) { | |||
$this->entityManager->persist($orderReductionCart); | |||
$this->entityManager->flush(); | |||
return $orderReductionCart ; | |||
} | |||
else { | |||
$orderShop->removeOrderReductionCart($orderReductionCart) ; | |||
return $orderReductionCart; | |||
} else { | |||
$orderShop->removeOrderReductionCart($orderReductionCart); | |||
return false; | |||
} | |||
} | |||
@@ -304,18 +329,16 @@ class OrderShopBuilder | |||
$orderReductionCreditFactory = new OrderReductionCreditFactory(); | |||
$orderReductionCredit = $orderReductionCreditFactory->create($orderShop, $reductionCredit); | |||
$orderShop->addOrderReductionCredit($orderReductionCredit) ; | |||
$orderShop->addOrderReductionCredit($orderReductionCredit); | |||
if($this->isOrderShopPositiveAmount($orderShop) | |||
if ($this->isOrderShopPositiveAmount($orderShop) | |||
&& $this->isOrderShopPositiveAmountRemainingToBePaid($orderShop)) { | |||
$this->entityManager->persist($orderReductionCredit); | |||
$this->entityManager->flush(); | |||
return $orderReductionCredit; | |||
} | |||
else { | |||
$orderShop->removeOrderReductionCredit($orderReductionCredit) ; | |||
} else { | |||
$orderShop->removeOrderReductionCredit($orderReductionCredit); | |||
return false; | |||
} | |||
@@ -326,13 +349,17 @@ class OrderShopBuilder | |||
// @TODO : à refactorer en plaçant dans src tout ce qui est spécifique à PDL | |||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||
//Si ce n'esrt pas une relivraison OU si c'est une relivraison + relivraison + ce n'est pas une erruer producteur | |||
if (!$orderProduct->isRedelivery() || ($orderProduct->isRedelivery() && $orderProduct->isRedeliverySupplierOrder() && !$orderProduct->isRedeliverySupplierMistake())) { | |||
if (!$orderProduct->isRedelivery() || ($orderProduct->isRedelivery( | |||
) && $orderProduct->isRedeliverySupplierOrder( | |||
) && !$orderProduct->isRedeliverySupplierMistake())) { | |||
switch ($orderProduct->getProduct()->getProductFamily()->getBehaviorCountStock()) { | |||
case ProductFamilyModel::BEHAVIOR_COUNT_STOCK_BY_MEASURE : | |||
//Disponibilité par unité de référence | |||
$oldAvailability = $orderProduct->getProduct()->getAvailableQuantityInherited(); | |||
$newAvailability = $oldAvailability - ($orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $orderProduct->getUnit()->getCoefficient())); | |||
$newAvailability = $oldAvailability - ($orderProduct->getQuantityOrder( | |||
) * ($orderProduct->getQuantityProduct() / $orderProduct->getUnit( | |||
)->getCoefficient())); | |||
$productFamily = $orderProduct->getProduct()->getProductFamily(); | |||
$productFamily->setAvailableQuantity($newAvailability); |
@@ -21,6 +21,7 @@ use Lc\CaracoleBundle\Doctrine\Extension\FilterSectionInterface; | |||
use Lc\CaracoleBundle\Factory\User\UserMerchantFactory; | |||
use Lc\CaracoleBundle\Form\Merchant\DuplicateToOtherMerchantFormType; | |||
use Lc\CaracoleBundle\Form\Section\DuplicateToOtherSectionFormType; | |||
use Lc\CaracoleBundle\Repository\Reduction\ReductionCatalogStore; | |||
use Lc\CaracoleBundle\Resolver\MerchantResolver; | |||
use Lc\CaracoleBundle\Resolver\SectionResolver; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | |||
@@ -43,6 +44,7 @@ trait AdminControllerTrait | |||
'section_resolver' => SectionResolver::class, | |||
'user_factory' => UserFactory::class, | |||
'user_merchant_factory' => UserMerchantFactory::class, | |||
ReductionCatalogStore::class => ReductionCatalogStore::class, | |||
] | |||
); | |||
} |
@@ -209,7 +209,7 @@ abstract class UserMerchantAdminController extends AbstractAdminController | |||
} | |||
return $this->render( | |||
'@LcCaracole/admin/user/usermerchant_edit.html.twig', | |||
'@LcCaracole/admin/user/edit_usermerchant.html.twig', | |||
[ | |||
'form' => $form->createView(), | |||
] | |||
@@ -233,8 +233,6 @@ abstract class UserMerchantAdminController extends AbstractAdminController | |||
if (!$context->getEntity()->isAccessible()) { | |||
throw new InsufficientEntityPermissionException($context); | |||
} | |||
dump($context->getCrud()->getControllerFqcn()); | |||
$options['action'] = $adminUrlGenerator | |||
->setController($context->getCrud()->getControllerFqcn()) |
@@ -22,11 +22,6 @@ trait ReductionPropertyTrait | |||
*/ | |||
protected $groupUsers; | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Merchant\MerchantInterface", inversedBy="productFamilies") | |||
* @ORM\JoinColumn(nullable=false) | |||
*/ | |||
protected $merchant; | |||
/** | |||
* @ORM\Column(type="datetime", nullable=true) | |||
@@ -50,18 +45,6 @@ trait ReductionPropertyTrait | |||
$this->groupUsers = new ArrayCollection(); | |||
} | |||
public function getMerchant(): ?MerchantInterface | |||
{ | |||
return $this->merchant; | |||
} | |||
public function setMerchant(?MerchantInterface $merchant): self | |||
{ | |||
$this->merchant = $merchant; | |||
return $this; | |||
} | |||
/** | |||
* @return Collection|UserInterface[] | |||
*/ |
@@ -0,0 +1,25 @@ | |||
<?php | |||
namespace Lc\CaracoleBundle\Event\Order; | |||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderStatusInterface; | |||
use Symfony\Contracts\EventDispatcher\Event; | |||
class CartChangeEvent extends Event | |||
{ | |||
const PRE_UPDATE = 'cart_event.pre_update'; | |||
const POST_UPDATE = 'cart_event.post_update'; | |||
protected OrderShopInterface $orderShop; | |||
public function __construct(OrderShopInterface $orderShop, OrderStatusInterface $orderStatus, bool $forceByAdmin) | |||
{ | |||
$this->orderShop = $orderShop; | |||
} | |||
public function getOrderShop() | |||
{ | |||
return $this->orderShop; | |||
} | |||
} |
@@ -2,29 +2,38 @@ | |||
namespace Lc\CaracoleBundle\Event\Order; | |||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderStatusInterface; | |||
use Symfony\Contracts\EventDispatcher\Event; | |||
class OrderShopChangeStatusEvent extends Event | |||
{ | |||
const PRE_CHANGE_STATUS = 'order_shop_event.pre_change_status'; | |||
const POST_CHANGE_STATUS = 'order_shop_event.post_change_status'; | |||
protected $orderShop; | |||
protected $orderStatus; | |||
public function __construct($orderShop, $orderStatus) | |||
{ | |||
$this->orderShop = $orderShop; | |||
$this->orderStatus = $orderStatus; | |||
} | |||
public function getOrderShop() | |||
{ | |||
return $this->orderShop; | |||
} | |||
public function getOrderStatus() | |||
{ | |||
return $this->orderStatus; | |||
} | |||
const PRE_CHANGE_STATUS = 'order_shop_event.pre_change_status'; | |||
const POST_CHANGE_STATUS = 'order_shop_event.post_change_status'; | |||
protected OrderShopInterface $orderShop; | |||
protected OrderStatusInterface $orderStatus; | |||
protected bool $forceByAdmin; | |||
public function __construct(OrderShopInterface $orderShop, OrderStatusInterface $orderStatus, bool $forceByAdmin) | |||
{ | |||
$this->orderShop = $orderShop; | |||
$this->orderStatus = $orderStatus; | |||
$this->forceByAdmin = $forceByAdmin; | |||
} | |||
public function getOrderShop() | |||
{ | |||
return $this->orderShop; | |||
} | |||
public function getOrderStatus() | |||
{ | |||
return $this->orderStatus; | |||
} | |||
public function getForceByAdmin() | |||
{ | |||
return $this->forceByAdmin; | |||
} | |||
} |
@@ -16,7 +16,7 @@ use Lc\SovBundle\Event\EntityManager\EntityManagerEvent; | |||
use Lc\SovBundle\Repository\AbstractRepositoryInterface; | |||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |||
class DuplicateProductEventSubscriber implements EventSubscriberInterface | |||
class DuplicateProductfamilyEventSubscriber implements EventSubscriberInterface | |||
{ | |||
protected $em; | |||
protected $adminUrlGenerator; |
@@ -0,0 +1,144 @@ | |||
<?php | |||
namespace Lc\CaracoleBundle\EventSubscriber\Product; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
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 Symfony\Component\EventDispatcher\EventSubscriberInterface; | |||
class UpdateProductfamilyEventSubscriber implements EventSubscriberInterface | |||
{ | |||
protected $em; | |||
protected $adminUrlGenerator; | |||
public function __construct(EntityManagerInterface $entityManager) | |||
{ | |||
$this->em = $entityManager; | |||
} | |||
public static function getSubscribedEvents() | |||
{ | |||
return [ | |||
EntityManagerEvent::PRE_UPDATE_EVENT => ['processBeforePersistProductFamily'], | |||
EntityManagerEvent::PRE_CREATE_EVENT => ['processBeforePersistProductFamily'], | |||
]; | |||
} | |||
public function processBeforePersistProductFamily(EntityManagerEvent $event) | |||
{ | |||
$entity = $event->getEntity(); | |||
if($entity instanceof ProductFamilyInterface) { | |||
$this->processProducts($entity); | |||
$this->processPrice($entity); | |||
$this->processReductionCatalog($entity); | |||
} | |||
//TODO updatePriceByProductFamily | |||
} | |||
protected function processReductionCatalog($entity) | |||
{ | |||
$reductionCatalog = $entity->getReductionCatalog(); | |||
if ($reductionCatalog instanceof ReductionCatalogInterface) { | |||
if ($reductionCatalog->getValue() && $reductionCatalog->getBehaviorTaxRate() && $reductionCatalog->getUnit()) { | |||
//$reductionCatalog->setSection($entity->getSection()); | |||
$reductionCatalog->setProductFamily($entity); | |||
if(is_null($reductionCatalog->getId())) { | |||
$this->em->create($reductionCatalog); | |||
}else { | |||
$this->em->update($reductionCatalog); | |||
} | |||
} | |||
} | |||
} | |||
protected function processPrice($entity) | |||
{ | |||
if ($entity->getBehaviorPrice() == 'by-piece') { | |||
$entity->setPriceByRefUnit(null); | |||
$entity->setBuyingPriceByRefUnit(null); | |||
} else { | |||
if ($entity->getBehaviorPrice() == 'by-reference-unit') { | |||
$entity->setPrice(null); | |||
$entity->setBuyingPrice(null); | |||
} | |||
} | |||
} | |||
protected function processProducts($entity) | |||
{ | |||
//Récupère le product origin | |||
$originProducts = $this->em->getRepository(ProductInterface::class) | |||
->findBy( | |||
array( | |||
'productFamily' => $entity->getId(), | |||
'originProduct' => true, | |||
) | |||
); | |||
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 { | |||
$originProduct->setStatus(1); | |||
} | |||
//Enregistrement | |||
$entity->addProduct($originProduct); | |||
foreach ($entity->getProducts() as $product) { | |||
$product->setProductFamily($entity); | |||
if ($entity->getProductsQuantityAsTitle() && $product->getStatus() >= 1) { | |||
$product->setTitle( | |||
str_replace('.', ',', $product->getQuantityInherited()).$product->getUnitInherited( | |||
)->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); | |||
} | |||
} | |||
}*/ | |||
} |
@@ -4,14 +4,18 @@ namespace Lc\CaracoleBundle\Factory\Order; | |||
use App\Entity\Order\OrderProduct; | |||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductInterface; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
class OrderProductFactory extends AbstractFactory | |||
{ | |||
public function create(): OrderProductInterface | |||
public function create(ProductInterface $product, int $quantityOrder): OrderProductInterface | |||
{ | |||
$orderProduct = new OrderProduct(); | |||
$orderProduct->setProduct($product); | |||
$orderProduct->setQuantityOrder($quantityOrder); | |||
return $orderProduct; | |||
} | |||
@@ -1,6 +1,6 @@ | |||
<?php | |||
namespace Lc\CaracoleBundle\Resolver\Reference; | |||
namespace Lc\CaracoleBundle\Generator\Reference; | |||
use Lc\CaracoleBundle\Definition\SectionSettingDefinition; | |||
use Lc\CaracoleBundle\Model\File\DocumentModel; | |||
@@ -9,7 +9,7 @@ use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||
use Lc\CaracoleBundle\Model\Section\SectionModel; | |||
use Lc\CaracoleBundle\Repository\File\DocumentStore; | |||
class DocumentReferenceResolver | |||
class DocumentReferenceGenerator | |||
{ | |||
protected DocumentStore $documentStore; |
@@ -1,12 +1,12 @@ | |||
<?php | |||
namespace Lc\CaracoleBundle\Resolver\Reference; | |||
namespace Lc\CaracoleBundle\Generator\Reference; | |||
use Lc\CaracoleBundle\Definition\SectionSettingDefinition; | |||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||
use Lc\CaracoleBundle\Model\Section\SectionModel; | |||
class OrderReferenceResolver | |||
class OrderReferenceGenerator | |||
{ | |||
public function buildReference(OrderShopInterface $orderShop, \DateTime $distributionDate = null): string |
@@ -121,6 +121,7 @@ abstract class AddressModel extends AbstractLightEntity implements StatusInterfa | |||
return $this->getTitle() . ' - ' . $this->getZip() . ' ' . $this->getCity(); | |||
} | |||
// getAddressSummary | |||
public function getSummaryShort() | |||
{ | |||
return $this->getAddress() . ' - ' . $this->getZip() . ' ' . $this->getCity(); |
@@ -6,6 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection; | |||
use Doctrine\Common\Collections\Collection; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\CaracoleBundle\Doctrine\Extension\FilterMerchantInterface; | |||
use Lc\CaracoleBundle\Doctrine\Extension\FilterSectionInterface; | |||
use Lc\CaracoleBundle\Doctrine\Extension\OrderAmountMinInterface; | |||
use Lc\CaracoleBundle\Doctrine\Extension\OrderAmountMinTrait; | |||
use Lc\CaracoleBundle\Doctrine\Extension\ReductionCartPropertyInterface; | |||
@@ -16,6 +17,7 @@ use Lc\CaracoleBundle\Doctrine\Extension\ReductionTrait; | |||
use Lc\CaracoleBundle\Doctrine\Extension\ReductionPropertyInterface; | |||
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface; | |||
use Lc\CaracoleBundle\Model\PointSale\PointSaleInterface; | |||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusTrait; | |||
use Lc\SovBundle\Doctrine\Pattern\AbstractLightEntity; | |||
@@ -26,7 +28,7 @@ use Lc\SovBundle\Model\User\UserInterface; | |||
*/ | |||
abstract class ReductionCartModel extends AbstractLightEntity implements ReductionPropertyInterface, ReductionInterface, | |||
ReductionCartPropertyInterface, | |||
FilterMerchantInterface, | |||
FilterSectionInterface, | |||
OrderAmountMinInterface, StatusInterface | |||
{ | |||
@@ -47,11 +49,12 @@ abstract class ReductionCartModel extends AbstractLightEntity implements Reducti | |||
*/ | |||
protected $title; | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Merchant\MerchantInterface") | |||
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Section\SectionInterface") | |||
* @ORM\JoinColumn(nullable=false) | |||
*/ | |||
protected $merchant; | |||
protected $section; | |||
/** | |||
* @ORM\Column(type="array", nullable=true) | |||
@@ -148,14 +151,14 @@ abstract class ReductionCartModel extends AbstractLightEntity implements Reducti | |||
return $this; | |||
} | |||
public function getMerchant(): ?MerchantInterface | |||
public function getSection(): SectionInterface | |||
{ | |||
return $this->merchant; | |||
return $this->section; | |||
} | |||
public function setMerchant(?MerchantInterface $merchant): self | |||
public function setSection(SectionInterface $section): self | |||
{ | |||
$this->merchant = $merchant; | |||
$this->section = $section; | |||
return $this; | |||
} |
@@ -5,13 +5,14 @@ namespace Lc\CaracoleBundle\Model\Reduction; | |||
use Doctrine\Common\Collections\ArrayCollection; | |||
use Doctrine\Common\Collections\Collection; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\CaracoleBundle\Doctrine\Extension\FilterMerchantInterface; | |||
use Lc\CaracoleBundle\Doctrine\Extension\FilterSectionInterface; | |||
use Lc\CaracoleBundle\Doctrine\Extension\ReductionPropertyTrait; | |||
use Lc\CaracoleBundle\Doctrine\Extension\ReductionTrait; | |||
use Lc\CaracoleBundle\Doctrine\Extension\ReductionPropertyInterface; | |||
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductCategoryInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductFamilyModel; | |||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusTrait; | |||
use Lc\SovBundle\Doctrine\Pattern\AbstractLightEntity; | |||
@@ -21,7 +22,7 @@ use Lc\SovBundle\Doctrine\Pattern\AbstractLightEntity; | |||
*/ | |||
abstract class ReductionCatalogModel extends AbstractLightEntity implements ReductionCatalogInterface, | |||
ReductionPropertyInterface, | |||
FilterMerchantInterface, StatusInterface | |||
FilterSectionInterface, StatusInterface | |||
{ | |||
use StatusTrait; | |||
use ReductionTrait; | |||
@@ -34,11 +35,12 @@ abstract class ReductionCatalogModel extends AbstractLightEntity implements Redu | |||
*/ | |||
protected $title; | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Merchant\MerchantInterface") | |||
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Section\SectionInterface") | |||
* @ORM\JoinColumn(nullable=false) | |||
*/ | |||
protected $merchant; | |||
protected $section; | |||
/** | |||
* @ORM\ManyToMany(targetEntity="Lc\CaracoleBundle\Model\Product\ProductFamilyInterface") | |||
@@ -76,14 +78,14 @@ abstract class ReductionCatalogModel extends AbstractLightEntity implements Redu | |||
} | |||
public function getMerchant(): ?MerchantInterface | |||
public function getSection(): SectionInterface | |||
{ | |||
return $this->merchant; | |||
return $this->section; | |||
} | |||
public function setMerchant(?MerchantInterface $merchant): self | |||
public function setSection(SectionInterface $section): self | |||
{ | |||
$this->merchant = $merchant; | |||
$this->section = $section; | |||
return $this; | |||
} | |||
@@ -116,12 +118,12 @@ abstract class ReductionCatalogModel extends AbstractLightEntity implements Redu | |||
} | |||
public function getProductFamily(): ?ProductFamily | |||
public function getProductFamily(): ?ProductFamilyModel | |||
{ | |||
return $this->productFamily; | |||
} | |||
public function setProductFamily(?ProductFamily $productFamily): self | |||
public function setProductFamily(?ProductFamilyModel $productFamily): self | |||
{ | |||
$this->productFamily = $productFamily; | |||
@@ -6,9 +6,11 @@ use Doctrine\Common\Collections\ArrayCollection; | |||
use Doctrine\Common\Collections\Collection; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\CaracoleBundle\Doctrine\Extension\FilterMerchantInterface; | |||
use Lc\CaracoleBundle\Doctrine\Extension\FilterSectionInterface; | |||
use Lc\CaracoleBundle\Doctrine\Extension\ReductionInterface; | |||
use Lc\CaracoleBundle\Doctrine\Extension\ReductionTrait; | |||
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface; | |||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusTrait; | |||
use Lc\SovBundle\Doctrine\Pattern\AbstractLightEntity; | |||
@@ -17,7 +19,7 @@ use Lc\SovBundle\Model\User\UserInterface; | |||
/** | |||
* @ORM\MappedSuperclass() | |||
*/ | |||
abstract class ReductionCreditModel extends AbstractLightEntity implements ReductionInterface, FilterMerchantInterface, | |||
abstract class ReductionCreditModel extends AbstractLightEntity implements ReductionInterface, FilterSectionInterface, | |||
StatusInterface | |||
{ | |||
const TYPE_CREDIT = 'credit'; | |||
@@ -38,12 +40,11 @@ abstract class ReductionCreditModel extends AbstractLightEntity implements Reduc | |||
*/ | |||
protected $users; | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Merchant\MerchantInterface") | |||
* @ORM\ManyToOne(targetEntity="Lc\CaracoleBundle\Model\Section\SectionInterface") | |||
* @ORM\JoinColumn(nullable=false) | |||
*/ | |||
protected $merchant; | |||
protected $section; | |||
/** | |||
* @ORM\Column(type="string", length=255) | |||
@@ -84,14 +85,14 @@ abstract class ReductionCreditModel extends AbstractLightEntity implements Reduc | |||
} | |||
public function getMerchant(): ?MerchantInterface | |||
public function getSection(): SectionInterface | |||
{ | |||
return $this->merchant; | |||
return $this->section; | |||
} | |||
public function setMerchant(?MerchantInterface $merchant): self | |||
public function setSection(SectionInterface $section): self | |||
{ | |||
$this->merchant = $merchant; | |||
$this->section = $section; | |||
return $this; | |||
} |
@@ -14,4 +14,33 @@ class OrderProductStore extends AbstractStore | |||
{ | |||
$this->query = $query; | |||
} | |||
// getOrderProductsFormOrderShopsGroupByStorageOrder | |||
public function getByOrderShopsGroupByStorageOrder(array $orderShops): array | |||
{ | |||
$orderProductsByStorageOrder = []; | |||
foreach ($orderShops as $orderShop) { | |||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||
if ($orderProduct->getProduct() && $orderProduct->getProduct()->getProductFamily()) { | |||
$storageOrder = 0; | |||
if ($orderProduct->getProduct()->getProductFamily()->getStorageOrder()) $storageOrder = $productFamily->getStorageOrder(); | |||
if (!isset($orderProductsByStorageOrder[$storageOrder])) { | |||
$orderProductsByStorageOrder[$productFamily->getId()] = [ | |||
'order_products' => [], | |||
'total_quantity_weight' => 0, | |||
]; | |||
} | |||
$orderProductsByStorageOrder[$storageOrder]['order_products'][] = $orderProduct; | |||
$orderProductsByStorageOrder[$storageOrder]['total_quantity_weight'] += ($orderProduct->getQuantityProduct() / $orderProduct->getUnit()->getCoefficient()) * $orderProduct->getQuantityOrder(); | |||
} | |||
} | |||
} | |||
return $orderProductsByStorageOrder; | |||
} | |||
} |
@@ -5,46 +5,157 @@ namespace Lc\CaracoleBundle\Repository\Order; | |||
use App\Entity\Delivery\DeliveryAvailabilityPointSale; | |||
use App\Entity\Delivery\DeliveryAvailabilityZone; | |||
use App\Entity\Order\OrderStatus; | |||
use App\Entity\Section\Section; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\CaracoleBundle\Builder\File\DocumentBuilder; | |||
use Lc\CaracoleBundle\Factory\File\DocumentFactory; | |||
use Lc\CaracoleBundle\Model\File\DocumentModel; | |||
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderReductionCartInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderReductionCreditInterface; | |||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||
use Lc\CaracoleBundle\Repository\Merchant\MerchantStore; | |||
use Lc\CaracoleBundle\Repository\Reduction\ReductionCreditStore; | |||
use Lc\CaracoleBundle\Repository\Section\SectionStore; | |||
use Lc\CaracoleBundle\Resolver\OpeningResolver; | |||
use Lc\CaracoleBundle\Repository\SectionStoreTrait; | |||
use Lc\CaracoleBundle\Resolver\Price\PriceResolver; | |||
use Lc\CaracoleBundle\Resolver\Reference\DocumentReferenceResolver; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Repository\AbstractStore; | |||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; | |||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |||
class OrderShopStore extends AbstractStore | |||
{ | |||
use SectionStoreTrait; | |||
protected OrderShopRepositoryQuery $query; | |||
protected EntityManagerInterface $entityManager; | |||
protected PriceResolver $priceResolver; | |||
protected DocumentReferenceResolver $documentReferenceResolver; | |||
protected DocumentBuilder $documentBuilder; | |||
protected ReductionCreditStore $reductionCreditStore; | |||
protected SectionStore $sectionStore; | |||
protected OrderProductStore $orderProductStore; | |||
protected MerchantStore $merchantStore; | |||
protected FlashBagInterface $flashBag; | |||
protected OpeningResolver $openingResolver; | |||
protected ParameterBagInterface $parameterBag; | |||
protected UrlGeneratorInterface $router; | |||
public function __construct( | |||
OrderShopRepositoryQuery $query, | |||
EntityManagerInterface $entityManager, | |||
PriceResolver $priceResolver, | |||
DocumentReferenceResolver $documentReferenceResolver, | |||
DocumentBuilder $documentBuilder | |||
DocumentBuilder $documentBuilder, | |||
ReductionCreditStore $reductionCreditStore, | |||
SectionStore $sectionStore, | |||
OrderProductStore $orderProductStore, | |||
MerchantStore $merchantStore, | |||
FlashBagInterface $flashBag, | |||
OpeningResolver $openingResolver, | |||
ParameterBagInterface $parameterBag, | |||
UrlGeneratorInterface $router | |||
) { | |||
$this->query = $query; | |||
$this->entityManager = $entityManager; | |||
$this->priceResolver = $priceResolver; | |||
$this->documentReferenceResolver = $documentReferenceResolver; | |||
$this->documentBuilder = $documentBuilder; | |||
$this->reductionCreditStore = $reductionCreditStore; | |||
$this->sectionStore = $sectionStore; | |||
$this->orderProductStore = $orderProductStore; | |||
$this->merchantStore = $merchantStore; | |||
$this->flashBag = $flashBag; | |||
$this->openingResolver = $openingResolver; | |||
$this->parameterBag = $parameterBag; | |||
$this->router = $router; | |||
} | |||
public function getDatas(OrderShopInterface $orderShop = null): array | |||
// getOrderShopsOfWeek | |||
public function getByCycle(SectionInterface $section, $params = []) | |||
{ | |||
$data = []; | |||
$orderShops = $this->getBy( | |||
array_merge( | |||
[ | |||
'section' => $section, | |||
'cycleNumber' => $this->getCycleNumberCurrentOrder($section), | |||
'isValid' => true, | |||
], | |||
$params | |||
) | |||
); | |||
return $orderShops; | |||
} | |||
// getOrderShopsOfWeekByUser | |||
public function getByCycleAndUser(SectionInterface $section, UserInterface $user, array $params = []) | |||
{ | |||
return $this->getByCycle( | |||
$section, | |||
array_merge( | |||
[ | |||
'user' => $user, | |||
'weekNumber' => $this->getCycleNumberCurrentOrder($section), | |||
'excludeComplementaryOrderShops' => true | |||
], | |||
$params | |||
) | |||
); | |||
} | |||
//public $countOrderShopsOfWeek = null; | |||
public function countByCycle(SectionInterface $section, bool $excludeComplementaryOrderShops = true) | |||
{ | |||
return $this->getByCycle( | |||
$section, | |||
[ | |||
'count' => true, | |||
'excludeComplementaryOrderShops' => $excludeComplementaryOrderShops | |||
] | |||
); | |||
// @TODO : optimisation à remettre en place | |||
/*if (is_null($this->countOrderShopsOfWeek)) { | |||
$this->countOrderShopsOfWeek = $this->getByCycle( | |||
$section, | |||
[ | |||
'count' => true, | |||
'excludeComplementaryOrderShops' => $excludeComplementaryOrderShops | |||
if (is_null($orderShop)) { | |||
$orderShop = $this->getCartCurrent(); | |||
] | |||
); | |||
} | |||
return $this->countOrderShopsOfWeek;*/ | |||
} | |||
// getNextWeekId | |||
public function getNextCycleId(SectionInterface $section, int $cycleNumber): int | |||
{ | |||
$lastOrder = $this->getOneLastOrderValidOfCycle($section, $cycleNumber); | |||
if ($lastOrder) { | |||
return intval($lastOrder->getCycleId() + 1); | |||
} else { | |||
return 1; | |||
} | |||
} | |||
public function getNextIdValidOrder(Section $section) | |||
{ | |||
$lastOrder = $this->getOneLastOrderValid($section); | |||
if ($lastOrder) { | |||
return intval($lastOrder->getIdValidOrder() + 1); | |||
} else { | |||
return 1; | |||
} | |||
} | |||
// getOrderDatas | |||
public function getDatas(OrderShopInterface $orderShop, UserInterface $user = null): array | |||
{ | |||
$data = []; | |||
$data['order'] = $orderShop; | |||
@@ -114,7 +225,7 @@ class OrderShopStore extends AbstractStore | |||
return $orderProductsByProductFamily; | |||
} | |||
// isOrderShopPositiveAmount | |||
// isOrderShopPositiveAmount | |||
public function isPositiveAmount(OrderShopInterface $orderShop) | |||
{ | |||
return $this->priceResolver->getTotalWithTax($orderShop) >= 0; | |||
@@ -150,12 +261,14 @@ class OrderShopStore extends AbstractStore | |||
return $totalAmount; | |||
} | |||
public function getTotalRemainingToBePaid(OrderShopInterface $orderShop): float | |||
{ | |||
public | |||
function getTotalRemainingToBePaid( | |||
OrderShopInterface $orderShop | |||
): float { | |||
return $this->priceResolver->getTotalWithTax($orderShop) - $this->getTotalOrderPayments($orderShop); | |||
} | |||
// isOrderShopPositiveAmountRemainingToBePaid | |||
// isOrderShopPositiveAmountRemainingToBePaid | |||
public function isPositiveAmountRemainingToBePaid(OrderShopInterface $orderShop): bool | |||
{ | |||
return $this->getTotalRemainingToBePaid($orderShop) > 0; | |||
@@ -181,6 +294,31 @@ class OrderShopStore extends AbstractStore | |||
return true; | |||
} | |||
// countValidOrderShopByUserAllMerchant | |||
public function countValidByUserAllMerchant($user) | |||
{ | |||
$totalOrder = 0; | |||
foreach ($this->merchantStore->getRepositoryQuery()->findAll() as $merchant) { | |||
$totalOrder += $this->countValidByUser($user, $merchant); | |||
} | |||
return $totalOrder; | |||
} | |||
public function countValidByUser(UserInterface $user, MerchantInterface $merchant = null) | |||
{ | |||
return $this->getBy( | |||
[ | |||
'user' => $user, | |||
'isValid' => true, | |||
'merchant' => $merchant, | |||
'excludeComplementaryOrderShops' => true, | |||
'count' => true | |||
] | |||
); | |||
} | |||
/* | |||
public function getCartCurrent(SectionInterface $section, UserInterface $user = null, VisitorInterface $visitor = null) | |||
{ | |||
@@ -253,8 +391,9 @@ class OrderShopStore extends AbstractStore | |||
return $query->count(); | |||
} | |||
public function countValidOrderWithReductionCart(OrderReductionCartInterface $reductionCart): string | |||
{ | |||
public function countValidOrderWithReductionCart( | |||
OrderReductionCartInterface $reductionCart | |||
): string { | |||
$query = $this->query->create(); | |||
$query | |||
@@ -339,7 +478,7 @@ class OrderShopStore extends AbstractStore | |||
return $query->findOne(); | |||
} | |||
//TODO Fonction à tester | |||
//TODO Fonction à tester | |||
// findAllBy | |||
public function getAllBy(array $params = []) |
@@ -2,22 +2,32 @@ | |||
namespace Lc\CaracoleBundle\Repository\Reduction; | |||
use App\Entity\Order\OrderShop; | |||
use App\Entity\Reduction\ReductionCart; | |||
use App\Resolver\Price\PriceResolver; | |||
use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface; | |||
use Lc\CaracoleBundle\Repository\Order\OrderShopStore; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Repository\AbstractStore; | |||
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; | |||
class ReductionCartStore extends AbstractStore | |||
{ | |||
protected ReductionCartRepositoryQuery $query; | |||
protected OrderShopStore $orderShopStore; | |||
protected PriceResolver $priceResolver; | |||
protected FlashBagInterface $flashBag; | |||
public function __construct( | |||
ReductionCartRepositoryQuery $query, | |||
OrderShopStore $orderShopStore | |||
OrderShopStore $orderShopStore, | |||
PriceResolver $priceResolver, | |||
FlashBagInterface $flashBag | |||
) { | |||
$this->query = $query; | |||
$this->orderShopStore = $orderShopStore; | |||
$this->priceResolver = $priceResolver; | |||
$this->flashBag = $flashBag; | |||
} | |||
// getReductionCartByCode | |||
@@ -48,13 +58,13 @@ class ReductionCartStore extends AbstractStore | |||
// getReductionCartUsedQuantityPerUser | |||
public function getUsedQuantityByUser(ReductionCartInterface $reductionCart, UserInterface $user): float | |||
{ | |||
return $this->orderShopStore->countValidOrderWithReductionCartPerUser($reductionCart, $user); | |||
return $this->orderShopStore->countValidWithReductionCartPerUser($reductionCart, $user); | |||
} | |||
// getReductionCartUsedQuantity | |||
public function getUsedQuantity(ReductionCartInterface $reductionCart): float | |||
{ | |||
return $this->orderShopStore->countValidOrderWithReductionCart($reductionCart); | |||
return $this->orderShopStore->countValidWithReductionCartPerUser($reductionCart); | |||
} | |||
// getReductionCartRemainingQuantityPerUser | |||
@@ -62,7 +72,7 @@ class ReductionCartStore extends AbstractStore | |||
{ | |||
if ($reductionCart->getAvailableQuantityPerUser()) { | |||
return $reductionCart->getAvailableQuantityPerUser( | |||
) - $this->orderShopRepo->countValidOrderWithReductionCartPerUser($reductionCart, $user); | |||
) - $this->orderShopStore->countValidWithReductionCartPerUser($reductionCart, $user); | |||
} | |||
return false; |
@@ -12,42 +12,11 @@ use Lc\SovBundle\Repository\AbstractStore; | |||
class ReductionCreditStore extends AbstractStore | |||
{ | |||
protected ReductionCreditRepositoryQuery $query; | |||
protected OrderShopStore $orderShopStore; | |||
public function __construct( | |||
ReductionCreditRepositoryQuery $query, | |||
OrderShopStore $orderShopStore | |||
ReductionCreditRepositoryQuery $query | |||
) { | |||
$this->query = $query; | |||
$this->orderShopStore = $orderShopStore; | |||
} | |||
// isReductionCreditAllowAddToOrder | |||
public function isAllowAddToOrder(OrderShopInterface $orderShop, ReductionCreditInterface $reductionCredit) | |||
{ | |||
$user = $orderShop->getUser(); | |||
// appartient à l'utilisateur | |||
if (!$reductionCredit->getUsers()->contains($user)) { | |||
// @TODO : gérer les addFlash dans le controleur | |||
//$this->utils->addFlash('error', 'error.reductionCredit.userNotAllow'); | |||
return false; | |||
} | |||
// n'a pas été utilisé | |||
if ($reductionCredit->getType() == ReductionCredit::TYPE_CREDIT) { | |||
if ($this->orderShopStore->countValidOrderWithReductionCredit($reductionCredit, $user) > 0) { | |||
//$this->utils->addFlash('error', 'error.reductionCredit.alreadyUse'); | |||
return false; | |||
} | |||
} else { | |||
if ($this->orderShopStore->countValidOrderWithReductionCredit($reductionCredit) > 0) { | |||
//$this->utils->addFlash('error', 'error.reductionCredit.alreadyUse'); | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
// findReductionCreditsByUser |
@@ -4,6 +4,7 @@ namespace Lc\CaracoleBundle\Repository\Section; | |||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||
use Lc\CaracoleBundle\Repository\MerchantStoreTrait; | |||
use Lc\CaracoleBundle\Repository\Order\OrderShopStore; | |||
use Lc\SovBundle\Repository\AbstractStore; | |||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |||
@@ -12,6 +13,7 @@ class SectionStore extends AbstractStore | |||
use MerchantStoreTrait; | |||
protected SectionRepositoryQuery $query; | |||
protected OrderShopStore $orderShopStore; | |||
public function __construct(SectionRepositoryQuery $query) | |||
{ | |||
@@ -35,4 +37,9 @@ class SectionStore extends AbstractStore | |||
return $section; | |||
} | |||
public function countOpenDays(SectionInterface $section): int | |||
{ | |||
// @TODO : à implémenter avec le nouveau système d'ouverture des commandes | |||
} | |||
} |
@@ -2,9 +2,11 @@ | |||
namespace Lc\CaracoleBundle\Resolver; | |||
use App\Entity\Section\Section; | |||
use Lc\CaracoleBundle\Definition\SectionSettingDefinition; | |||
use Lc\CaracoleBundle\Model\Section\OpeningInterface; | |||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||
use Lc\CaracoleBundle\Repository\Order\OrderShopStore; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Symfony\Component\Security\Core\Security; | |||
@@ -13,17 +15,20 @@ class OpeningResolver | |||
protected array $messages = []; | |||
protected SectionResolver $sectionResolver; | |||
protected Security $security; | |||
//protected OrderShopStore $orderShopStore; | |||
public function __construct(SectionResolver $sectionResolver, Security $security) | |||
public function __construct(SectionResolver $sectionResolver, Security $security /*, OrderShopStore $orderShopStore*/) | |||
{ | |||
$this->sectionResolver = $sectionResolver; | |||
$this->security = $security; | |||
//$this->orderShopStore = $orderShopStore; | |||
} | |||
public function isOpenSale( | |||
SectionInterface $section = null, | |||
UserInterface $user = null, | |||
\DateTime $date = null | |||
\DateTime $date = null, | |||
string $context = null | |||
): bool { | |||
// Initialisation | |||
$this->messages = []; | |||
@@ -54,18 +59,13 @@ class OpeningResolver | |||
} | |||
// Nombre maximum de commandes par cycle (voir configuration de section) | |||
$countOrderShopCycle = 0; | |||
$orderMaximumPerCycle = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_MAXIMUM_PER_CYCLE); | |||
if ($orderMaximumPerCycle && $countOrderShopCycle >= $orderMaximumPerCycle) { | |||
if($this->isMaximumOrderCycleAchieved($section)) { | |||
$this->addMessage('Le nombre maximum de commande a été atteint.'); | |||
return false; | |||
} | |||
// Période de fermeture des commandes issue de la configuration de la section (congés) | |||
$orderClosedStart = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_CLOSED_START); | |||
$orderClosedEnd = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_CLOSED_END); | |||
if ($orderClosedStart && $orderClosedEnd && $date >= $orderClosedStart && $date <= $orderClosedEnd) { | |||
if($this->isClosingPeriod($section)) { | |||
$this->addMessage( | |||
'Les commandes sont fermées (période de fermeture des commandes dans la configuration de la section).' | |||
); | |||
@@ -89,6 +89,34 @@ class OpeningResolver | |||
return false; | |||
} | |||
// isHolidays | |||
public function isClosingPeriod(Section $section, \DateTime $date) | |||
{ | |||
$orderClosedStart = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_CLOSED_START); | |||
$orderClosedEnd = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_CLOSED_END); | |||
if ($orderClosedStart && $orderClosedEnd && $date >= $orderClosedStart && $date <= $orderClosedEnd) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
// isMaximumOrderWeekAchieved | |||
public function isMaximumOrderCycleAchieved(SectionInterface $section) | |||
{ | |||
// @TODO : countValidByCycle | |||
//$countOrderShopCycle = $this->orderShopStore->countValidByCycle($section); | |||
$countOrderShopCycle = 0 ; | |||
$orderMaximumPerCycle = $section->getSettingValue(SectionSettingDefinition::SETTING_ORDER_MAXIMUM_PER_CYCLE); | |||
if ($orderMaximumPerCycle && $countOrderShopCycle >= $orderMaximumPerCycle) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
public function isDateMatchWithOpening(\DateTime $date, OpeningInterface $opening): bool | |||
{ | |||
$day = $date->format('N'); | |||
@@ -130,7 +158,6 @@ class OpeningResolver | |||
return false; | |||
} | |||
public function getDateEndCurrentSale(SectionInterface $section, $formatDate = '', $delimiterDayTime = 'à') | |||
{ | |||
// @TODO : à réécrire |
@@ -0,0 +1,190 @@ | |||
<?php | |||
namespace Lc\CaracoleBundle\Statistic; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
class Statistic | |||
{ | |||
protected $properties = array(); | |||
protected $averageProperties = array(); | |||
protected $labels; | |||
protected $dateStart; | |||
protected $dateEnd; | |||
protected $interval; | |||
protected $em; | |||
protected $resultsSort; | |||
public function __construct( | |||
EntityManagerInterface $entityManager, | |||
?\DateTime $dateStart = null, | |||
?\DateTime $dateEnd = null, | |||
?string $interval = null | |||
) { | |||
$this->em = $entityManager; | |||
$this->dateStart = $dateStart; | |||
$this->dateEnd = $dateEnd; | |||
$this->interval = $interval; | |||
} | |||
public function addProperty(string $propertyName, array $options) | |||
{ | |||
$resolver = new OptionsResolver(); | |||
$this->configurePropertyOptions($resolver); | |||
$this->properties[$propertyName] = $resolver->resolve($options); | |||
$this->resultsSort[$propertyName] = $propertyName; | |||
} | |||
public function addAverageProperty(string $propertyName, array $options) | |||
{ | |||
$resolver = new OptionsResolver(); | |||
$this->configurePropertyOptions($resolver); | |||
$this->averageProperties[$propertyName] = $resolver->resolve($options); | |||
$this->resultsSort[$propertyName] = $propertyName; | |||
} | |||
public function setAverageData(string $propertyName, string $key, $value) | |||
{ | |||
if (isset($this->averageProperties[$propertyName])) { | |||
$this->averageProperties[$propertyName]['data'][$key] += number_format($value, 2); | |||
} else { | |||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||
} | |||
} | |||
public function setData(string $propertyName, string $key, $value) | |||
{ | |||
if (isset($this->properties[$propertyName])) { | |||
$this->properties[$propertyName]['data'][$key] += number_format($value, 2); | |||
$this->properties[$propertyName]['total_period'] += number_format($value, 2); | |||
} else { | |||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||
} | |||
} | |||
public function setAveragePropertiesData() | |||
{ | |||
foreach ($this->getLabels() as $key => $label) { | |||
foreach ($this->getAverageProperties() as $averagePropertyName => $averageProperty) { | |||
if ($this->getData($averageProperty['divider'], $key)) { | |||
$this->setAverageData( | |||
$averagePropertyName, | |||
$key, | |||
$this->getData($averageProperty['dividend'], $key) / $this->getData( | |||
$averageProperty['divider'], | |||
$key | |||
) | |||
); | |||
} | |||
if ($this->getTotalPeriod($averageProperty['divider'])) { | |||
$this->averageProperties[$averagePropertyName]['total_period'] = $this->getTotalPeriod( | |||
$averageProperty['dividend'] | |||
) / $this->getTotalPeriod($averageProperty['divider']); | |||
} | |||
} | |||
} | |||
foreach ($this->getProperties() as $propertyName => $property) { | |||
$this->properties[$propertyName]['average_period'] = number_format( | |||
$this->properties[$propertyName]['total_period'] / count($this->getLabels()), | |||
2 | |||
); | |||
} | |||
foreach ($this->getAverageProperties() as $averagePropertyName => $averageProperty) { | |||
$this->averageProperties[$averagePropertyName]['average_period'] = number_format( | |||
$this->averageProperties[$averagePropertyName]['total_period'] / count($this->getLabels()), | |||
2 | |||
); | |||
} | |||
} | |||
public function getLabels() | |||
{ | |||
return $this->labels; | |||
} | |||
public function getProperties() | |||
{ | |||
return $this->properties; | |||
} | |||
public function getData($propertyName, $key) | |||
{ | |||
if (!isset($this->properties[$propertyName])) { | |||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||
} | |||
return $this->properties[$propertyName]['data'][$key]; | |||
} | |||
public function getTotalPeriod($propertyName) | |||
{ | |||
if (!isset($this->properties[$propertyName])) { | |||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||
} | |||
return $this->properties[$propertyName]['total_period']; | |||
} | |||
public function getAverageProperties() | |||
{ | |||
return $this->averageProperties; | |||
} | |||
public function getResults() | |||
{ | |||
$results = array_replace($this->resultsSort, $this->properties, $this->averageProperties); | |||
return $results; | |||
} | |||
public function getAsArray() | |||
{ | |||
return array( | |||
'label' => $this->getLabels(), | |||
'data' => $this->getResults(), | |||
); | |||
} | |||
public function getDateRange() | |||
{ | |||
return new \DatePeriod( | |||
$this->getDateStart(), | |||
new \DateInterval('P1' . $this->getInterval()), | |||
$this->getDateEnd() | |||
); | |||
} | |||
public function getDateStart() | |||
{ | |||
return $this->dateStart; | |||
} | |||
public function getDateEnd() | |||
{ | |||
return $this->dateEnd; | |||
} | |||
public function getInterval() | |||
{ | |||
return $this->interval; | |||
} | |||
public function configurePropertyOptions(OptionsResolver $resolver) | |||
{ | |||
$resolver->setDefaults( | |||
[ | |||
'unit' => '', | |||
'label' => 'Chiffre affaire produit', | |||
'label_short' => 'CA produit', | |||
'data' => array(), | |||
'total_period' => 0, | |||
'average_period' => 0, | |||
'dividend' => null, | |||
'divider' => null, | |||
] | |||
); | |||
} | |||
} |