<?php | |||||
namespace Lc\CaracoleBundle\Builder\Order; | |||||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | |||||
use Lc\CaracoleBundle\Resolver\Price\PriceResolver; | |||||
class OrderProductBuilder | |||||
{ | |||||
protected PriceResolver $priceResolver; | |||||
public function __construct(PriceResolver $priceResolver) | |||||
{ | |||||
$this->priceResolver = $priceResolver; | |||||
} | |||||
public function init(OrderProductInterface $orderProduct) | |||||
{ | |||||
$orderProduct->setTitle($orderProduct->getTitleOrderShop()); | |||||
$orderProduct->setPrice($this->priceResolver->getPrice($orderProduct->getProduct())); | |||||
$orderProduct->setBuyingPrice($this->priceResolver->getBuyingPrice($orderProduct->getProduct())); | |||||
$orderProduct->setUnit($orderProduct->getProduct()->getUnitInherited()); | |||||
$orderProduct->setTaxRate($orderProduct->getProduct()->getTaxRateInherited()); | |||||
$orderProduct->setQuantityProduct($orderProduct->getProduct()->getQuantityInherited()); | |||||
return $orderProduct; | |||||
} | |||||
} |
<?php | |||||
namespace Lc\CaracoleBundle\Builder\Order; | |||||
use App\Entity\Order\OrderProductReductionCatalog; | |||||
use Doctrine\ORM\EntityManagerInterface; | |||||
use Lc\CaracoleBundle\Event\Order\OrderShopChangeStatusEvent; | |||||
use Lc\CaracoleBundle\Factory\Order\OrderPaymentFactory; | |||||
use Lc\CaracoleBundle\Factory\Order\OrderProductReductionCatalogFactory; | |||||
use Lc\CaracoleBundle\Factory\Order\OrderShopFactory; | |||||
use Lc\CaracoleBundle\Factory\Order\OrderStatusHistoryFactory; | |||||
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface; | |||||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | |||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||||
use Lc\CaracoleBundle\Model\Order\OrderStatusHistoryModel; | |||||
use Lc\CaracoleBundle\Model\Order\OrderStatusModel; | |||||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||||
use Lc\CaracoleBundle\Model\User\VisitorInterface; | |||||
use Lc\CaracoleBundle\Repository\Order\OrderProductStore; | |||||
use Lc\CaracoleBundle\Repository\Order\OrderStatusStore; | |||||
use Lc\CaracoleBundle\Repository\Product\ProductFamilyStore; | |||||
use Lc\CaracoleBundle\Resolver\Price\PriceResolver; | |||||
use Lc\SovBundle\Model\User\UserInterface; | |||||
class OrderShopBuilder | |||||
{ | |||||
protected EntityManagerInterface $entityManager; | |||||
protected OrderStatusStore $orderStatusStore; | |||||
protected OrderProductStore $orderProductStore; | |||||
protected ProductFamilyStore $productFamilyStore; | |||||
protected PriceResolver $priceResolver; | |||||
protected OrderProductBuilder $orderProductBuilder; | |||||
public function __construct( | |||||
EntityManagerInterface $entityManager, | |||||
OrderStatusStore $orderStatusStore, | |||||
OrderProductStore $orderProductStore, | |||||
ProductFamilyStore $productFamilyStore, | |||||
OrderProductBuilder $orderProductBuilder, | |||||
PriceResolver $priceResolver | |||||
) { | |||||
$this->entityManager = $entityManager; | |||||
$this->orderStatusStore = $orderStatusStore; | |||||
$this->orderProductStore = $orderProductStore; | |||||
$this->productFamilyStore = $productFamilyStore; | |||||
$this->orderProductBuilder = $orderProductBuilder; | |||||
$this->priceResolver = $priceResolver; | |||||
} | |||||
public function create( | |||||
MerchantInterface $merchant, | |||||
SectionInterface $section, | |||||
UserInterface $user = null, | |||||
VisitorInterface $visitor = null | |||||
) { | |||||
$orderShopFactory = new OrderShopFactory(); | |||||
$orderShop = $orderShopFactory->create($merchant, $section, $user, $visitor); | |||||
$this->changeOrderStatus($orderShop, OrderStatusModel::ALIAS_CART); | |||||
return $orderShop; | |||||
} | |||||
public function changeOrderStatus(OrderShopInterface $orderShop, string $alias) | |||||
{ | |||||
$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 | |||||
); | |||||
$orderShop->setOrderStatusProtected($orderStatus); | |||||
$orderStatusHistoryFactory = new OrderStatusHistoryFactory(); | |||||
$orderStatusHistory = $orderStatusHistoryFactory->create($orderShop, $orderStatus); | |||||
$orderShop->addOrderStatusHistory($orderStatusHistory); | |||||
} | |||||
return $orderShop; | |||||
} | |||||
public function addOrderProduct( | |||||
OrderShopInterface $orderShop, | |||||
OrderProductInterface $orderProductAdd, | |||||
bool $persist = true | |||||
) { | |||||
$return = false; | |||||
if ($this->orderProductStore->isOrderProductAvailableAddCart($orderProductAdd, $orderShop)) { | |||||
if ($orderProductAdd->getQuantityOrder() > 0) { | |||||
$updated = false; | |||||
$this->orderProductBuilder->init($orderProductAdd); | |||||
$productFamily = $this->productFamilyStore->getOneBySlug( | |||||
$orderProductAdd->getProduct()->getProductFamily()->getSlug() | |||||
); | |||||
if ($productFamily) { | |||||
$reductionCatalog = $productFamily->getReductionCatalog(); | |||||
if ($reductionCatalog) { | |||||
$orderProductReductionCatalogFactory = new OrderProductReductionCatalogFactory(); | |||||
$orderProductReductionCatalog = $orderProductReductionCatalogFactory->create( | |||||
$reductionCatalog->getTitle(), | |||||
$reductionCatalog->getValue(), | |||||
$reductionCatalog->getUnit(), | |||||
$reductionCatalog->getBehaviorTaxRate() | |||||
); | |||||
$orderProductAdd->setOrderProductReductionCatalog($orderProductReductionCatalog); | |||||
} | |||||
} | |||||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||||
if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId() | |||||
&& $orderProduct->getRedelivery() == $orderProductAdd->getRedelivery() | |||||
&& (string)$this->priceResolver->getPrice($orderProduct) | |||||
== (string)$this->priceResolver->getPrice($orderProductAdd) | |||||
&& $orderProduct->getOrderProductReductionCatalog()->compare( | |||||
$orderProductAdd->getOrderProductReductionCatalog() | |||||
)) { | |||||
$orderProduct->setQuantityOrder( | |||||
$orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder() | |||||
); | |||||
if ($persist) { | |||||
$this->entityManager->persist($orderProduct); | |||||
} | |||||
$updated = true; | |||||
$return = true; | |||||
break; | |||||
} | |||||
} | |||||
if (!$updated) { | |||||
$orderShop->addOrderProduct($orderProductAdd); | |||||
if ($persist) { | |||||
if (isset($orderProductReductionCatalog)) { | |||||
$this->entityManager->persist($orderProductReductionCatalog); | |||||
} | |||||
$this->entityManager->persist($orderProductAdd); | |||||
$this->entityManager->persist($orderShop); | |||||
} | |||||
$return = true; | |||||
} | |||||
if ($persist) { | |||||
$this->entityManager->flush(); | |||||
} | |||||
// @TODO : dispatch event cart change | |||||
//$this->eventCartChange($orderShop); | |||||
} | |||||
} else { | |||||
// @TODO : retourner le message d'erreur et faire le addFlash dans le contrôleur | |||||
/*$availableQuantity = $orderProductAdd->getProduct()->getAvailableQuantityInherited(); | |||||
$textError = "Le produit <strong>" . $orderProductAdd->getTitleOrderShop( | |||||
) . "</strong> n'est pas disponible"; | |||||
if ($availableQuantity !== false && $availableQuantity > 0) { | |||||
$unit = ''; | |||||
if ($orderProductAdd->getProduct()->getProductFamily()->getBehaviorCountStock( | |||||
) == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) { | |||||
$unit = $orderProductAdd->getProduct()->getUnitInherited()->getUnitReference()->getUnit(); | |||||
} | |||||
$textError .= ' dans cette quantité '; | |||||
$user = $this->security->getUser(); | |||||
if ($user && $user->hasRole('ROLE_USER')) { | |||||
$textError .= '<br />' . $availableQuantity . $unit . ' disponible(s) dont ' . $this->getQuantityOrderByProduct( | |||||
$orderShop, | |||||
$orderProductAdd->getProduct() | |||||
) . $unit . ' déjà dans votre panier.'; | |||||
} | |||||
} | |||||
$this->utils->addFlash('error', $textError);*/ | |||||
} | |||||
return $return; | |||||
} | |||||
public function merge(OrderShopInterface $orderShop1, OrderShopInterface $orderShop2, $persist = true) | |||||
{ | |||||
if ($orderShop1 && $orderShop2) { | |||||
foreach ($orderShop2->getOrderProducts() as $orderProduct) { | |||||
$orderProductAlreadyInCart = $orderShop1->hasOrderProductAlreadyInCart($orderProduct); | |||||
if ($orderProductAlreadyInCart) { | |||||
if ($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) { | |||||
$orderShop1->removeOrderProduct($orderProductAlreadyInCart); | |||||
$this->addOrderProduct($orderShop1, $orderProduct); | |||||
} | |||||
} else { | |||||
$this->addOrderProduct($orderShop1, $orderProduct); | |||||
} | |||||
if ($persist) { | |||||
$this->entityManager->remove($orderProduct); | |||||
} | |||||
} | |||||
if ($persist) { | |||||
$this->entityManager->remove($orderShop2); | |||||
$this->entityManager->persist($orderShop1); | |||||
$this->entityManager->flush(); | |||||
} | |||||
return $orderShop1; | |||||
} | |||||
} | |||||
public function addPayment(OrderShopInterface $orderShop, $meanPayment, $amount) | |||||
{ | |||||
$orderPaymentFactory = new OrderPaymentFactory(); | |||||
$orderPayment = $orderPaymentFactory->create($orderShop, $meanPayment, $amount); | |||||
$orderShop->addOrderPayment($orderPayment); | |||||
if ($this->isOrderPaid($orderShop)) { | |||||
$nextStatus = OrderStatusModel::ALIAS_PAID; | |||||
} else { | |||||
$nextStatus = OrderStatusModel::ALIAS_PARTIAL_PAYMENT; | |||||
} | |||||
if ($orderShop->getOrderStatus()->getAlias() != $nextStatus) { | |||||
$orderShop = $this->changeOrderStatus($orderShop, $nextStatus); | |||||
} | |||||
$this->entityManager->persist($orderPayment); | |||||
$this->entityManager->update($orderShop); | |||||
$this->entityManager->flush(); | |||||
return $orderShop; | |||||
} | |||||
} |
<?php | |||||
namespace Lc\CaracoleBundle\Event\EntityManager; | |||||
use Symfony\Contracts\EventDispatcher\Event; | |||||
class EntityManagerEvent extends Event | |||||
{ | |||||
const CREATE_EVENT = 'entity_manager_event.create'; | |||||
const UPDATE_EVENT = 'entity_manager_event.update'; | |||||
const DELETE_EVENT = 'entity_manager_event.delete'; | |||||
const PRE_CREATE_EVENT = 'entity_manager_event.pre_create'; | |||||
const PRE_UPDATE_EVENT = 'entity_manager_event.pre_update'; | |||||
const PRE_DELETE_EVENT = 'entity_manager_event.pre_delete'; | |||||
protected $entity; | |||||
public function __construct($entity) | |||||
{ | |||||
$this->entity = $entity; | |||||
} | |||||
public function getEntity() | |||||
{ | |||||
return $this->entity; | |||||
} | |||||
} |
<?php | |||||
namespace Lc\CaracoleBundle\Event\Order; | |||||
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; | |||||
} | |||||
} |
use App\Entity\Order\OrderPayment; | use App\Entity\Order\OrderPayment; | ||||
use Lc\CaracoleBundle\Model\Order\OrderPaymentInterface; | use Lc\CaracoleBundle\Model\Order\OrderPaymentInterface; | ||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||||
use Lc\SovBundle\Factory\AbstractFactory; | use Lc\SovBundle\Factory\AbstractFactory; | ||||
class OrderPaymentFactory extends AbstractFactory | class OrderPaymentFactory extends AbstractFactory | ||||
{ | { | ||||
public function create(): OrderPaymentInterface | |||||
public function create(OrderShopInterface $orderShop, string $meanPayment, float $amount): OrderPaymentInterface | |||||
{ | { | ||||
$orderPayment = new OrderPayment(); | $orderPayment = new OrderPayment(); | ||||
$orderPayment->setOrderShop($orderShop); | |||||
$orderPayment->setMeanPayment($meanPayment); | |||||
$orderPayment->setAmount($amount); | |||||
return $orderPayment; | return $orderPayment; | ||||
} | } | ||||
class OrderProductReductionCatalogFactory extends AbstractFactory | class OrderProductReductionCatalogFactory extends AbstractFactory | ||||
{ | { | ||||
public function create(): OrderProductReductionCatalogInterface | |||||
public function create(string $title, float $value, string $unit, string $behaviorTaxRate): OrderProductReductionCatalogInterface | |||||
{ | { | ||||
$orderProductReductionCatalog = new OrderProductReductionCatalog(); | $orderProductReductionCatalog = new OrderProductReductionCatalog(); | ||||
$orderProductReductionCatalog->setTitle($title); | |||||
$orderProductReductionCatalog->setValue($value); | |||||
$orderProductReductionCatalog->setUnit($unit); | |||||
$orderProductReductionCatalog->setBehaviorTaxRate($behaviorTaxRate); | |||||
return $orderProductReductionCatalog; | return $orderProductReductionCatalog; | ||||
} | } | ||||
namespace Lc\CaracoleBundle\Factory\Order; | namespace Lc\CaracoleBundle\Factory\Order; | ||||
use App\Entity\Order\OrderShop; | use App\Entity\Order\OrderShop; | ||||
use Lc\CaracoleBundle\Factory\MerchantFactoryTrait; | |||||
use Lc\CaracoleBundle\Factory\SectionFactoryTrait; | |||||
use Lc\CaracoleBundle\Event\Order\OrderShopChangeStatusEvent; | |||||
use Lc\CaracoleBundle\Model\Merchant\MerchantInterface; | use Lc\CaracoleBundle\Model\Merchant\MerchantInterface; | ||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | ||||
use Lc\CaracoleBundle\Model\Order\OrderStatusModel; | |||||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | use Lc\CaracoleBundle\Model\Section\SectionInterface; | ||||
use Lc\CaracoleBundle\Model\User\VisitorInterface; | |||||
use Lc\SovBundle\Factory\AbstractFactory; | use Lc\SovBundle\Factory\AbstractFactory; | ||||
use Lc\SovBundle\Model\User\UserInterface; | |||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||||
class OrderShopFactory extends AbstractFactory | class OrderShopFactory extends AbstractFactory | ||||
{ | { | ||||
protected EventDispatcherInterface $eventDispatcher; | |||||
protected OrderStatusHistoryFactory $orderStatusHistoryFactory; | |||||
public function __construct( | |||||
EventDispatcherInterface $eventDispatcher, | |||||
OrderStatusHistoryFactory $orderStatusHistoryFactory | |||||
) { | |||||
$this->eventDispatcher = $eventDispatcher; | |||||
$this->orderStatusHistoryFactory = $orderStatusHistoryFactory; | |||||
} | |||||
public function create( | |||||
MerchantInterface $merchant, | |||||
SectionInterface $section, | |||||
UserInterface $user = null, | |||||
VisitorInterface $visitor = null | |||||
): OrderShopInterface { | |||||
public function create(MerchantInterface $merchant, SectionInterface $section): OrderShopInterface | |||||
{ | |||||
$orderShop = new OrderShop(); | $orderShop = new OrderShop(); | ||||
$orderShop->setMerchant($merchant); | $orderShop->setMerchant($merchant); | ||||
$orderShop->setSection($section); | $orderShop->setSection($section); | ||||
$orderShopBelongTo = false; | |||||
if (!is_null($user)) { | |||||
$orderShopBelongTo = true; | |||||
$orderShop->setUser($user); | |||||
} | |||||
if (!is_null($visitor) && !$orderShop->getUser()) { | |||||
$orderShopBelongTo = true; | |||||
$orderShop->setVisitor($visitor); | |||||
} | |||||
if (!$orderShopBelongTo) { | |||||
throw new \ErrorException('La commande doit être liée à un utilisateur ou à un visiteur.'); | |||||
} | |||||
return $orderShop; | return $orderShop; | ||||
} | } | ||||
namespace Lc\CaracoleBundle\Factory\Order; | namespace Lc\CaracoleBundle\Factory\Order; | ||||
use App\Entity\Order\OrderStatusHistory; | use App\Entity\Order\OrderStatusHistory; | ||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||||
use Lc\CaracoleBundle\Model\Order\OrderStatusHistoryInterface; | use Lc\CaracoleBundle\Model\Order\OrderStatusHistoryInterface; | ||||
use Lc\CaracoleBundle\Model\Order\OrderStatusHistoryModel; | |||||
use Lc\SovBundle\Factory\AbstractFactory; | use Lc\SovBundle\Factory\AbstractFactory; | ||||
class OrderStatusHistoryFactory extends AbstractFactory | class OrderStatusHistoryFactory extends AbstractFactory | ||||
{ | { | ||||
public function create(): OrderStatusHistoryInterface | |||||
public function create(OrderShopInterface $orderShop, string $status, string $origin = OrderStatusHistoryModel::ORIGIN_USER): OrderStatusHistoryInterface | |||||
{ | { | ||||
$orderStatusHistory = new OrderStatusHistory(); | $orderStatusHistory = new OrderStatusHistory(); | ||||
$orderStatusHistory->setOrderShop($orderShop); | |||||
$orderStatusHistory->setOrderStatus($status); | |||||
$orderStatusHistory->setOrigin($origin); | |||||
return $orderStatusHistory; | return $orderStatusHistory; | ||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
public function compare($orderProductReductionCatalog) | |||||
{ | |||||
return $orderProductReductionCatalog | |||||
&& $this->getUnit() == $orderProductReductionCatalog->getUnit() | |||||
&& (string)$this->getValue() == (string)$orderProductReductionCatalog->getValue() | |||||
&& $this->getBehaviorTaxRate() == $orderProductReductionCatalog->getBehaviorTaxRate(); | |||||
} | |||||
} | } |
} | } | ||||
} | } | ||||
public function countQuantities() | |||||
{ | |||||
return self::countQuantitiesByOrderProducts($this->getOrderProducts()); | |||||
} | |||||
public static function countQuantitiesByOrderProducts($orderProducts = []) | |||||
{ | |||||
$count = 0; | |||||
foreach ($orderProducts as $orderProduct) { | |||||
$count += $orderProduct->getQuantityOrder(); | |||||
} | |||||
return $count; | |||||
} | |||||
public function getOrderProductsByParentCategory() | |||||
{ | |||||
$categoriesArray = []; | |||||
foreach ($this->getOrderProducts() as $orderProduct) { | |||||
$productCategories = $orderProduct->getProduct()->getProductFamily()->getProductCategories(); | |||||
$category = $productCategories[0]->getParentCategory(); | |||||
$labelCategory = $category->getTitle(); | |||||
if (!isset($categoriesArray[$labelCategory])) { | |||||
$categoriesArray[$labelCategory] = []; | |||||
} | |||||
$categoriesArray[$labelCategory][] = $orderProduct; | |||||
} | |||||
return $categoriesArray; | |||||
} | |||||
public function hasOrderProductAlreadyInCart($orderProductTest) | |||||
{ | |||||
foreach($this->getOrderProducts() as $orderProduct) { | |||||
if($orderProduct->getProduct() == $orderProductTest->getProduct()) { | |||||
return $orderProduct ; | |||||
} | |||||
} | |||||
return false ; | |||||
} | |||||
public function getOrderProductsByProductFamily($productFamily) | |||||
{ | |||||
$arrayOrderProducts = [] ; | |||||
foreach($this->getOrderProducts() as $orderProduct) { | |||||
if($orderProduct->getProduct()->getProductFamily() == $productFamily) { | |||||
$arrayOrderProducts[] = $orderProduct ; | |||||
} | |||||
} | |||||
return $arrayOrderProducts ; | |||||
} | |||||
public function getValidationDate(): ?\DateTimeInterface | public function getValidationDate(): ?\DateTimeInterface | ||||
{ | { | ||||
return $this->validationDate; | return $this->validationDate; |
*/ | */ | ||||
protected $orderStatus; | protected $orderStatus; | ||||
const ORIGIN_USER = 'user'; | |||||
const ORIGIN_ADMIN = 'admin'; | |||||
const ORIGIN_SYSTEM = 'system'; | |||||
/** | /** | ||||
* @ORM\Column(type="string", length=31) | * @ORM\Column(type="string", length=31) | ||||
*/ | */ |
namespace Lc\CaracoleBundle\Repository\Order; | namespace Lc\CaracoleBundle\Repository\Order; | ||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||||
use Lc\CaracoleBundle\Resolver\Price\PriceResolver; | |||||
use Lc\SovBundle\Repository\AbstractStore; | use Lc\SovBundle\Repository\AbstractStore; | ||||
class OrderShopStore extends AbstractStore | class OrderShopStore extends AbstractStore | ||||
{ | { | ||||
protected OrderShopRepositoryQuery $query; | protected OrderShopRepositoryQuery $query; | ||||
protected PriceResolver $priceResolver; | |||||
public function __construct(OrderShopRepositoryQuery $query) | |||||
{ | |||||
public function __construct( | |||||
OrderShopRepositoryQuery $query, | |||||
PriceResolver $priceResolver | |||||
) { | |||||
$this->query = $query; | $this->query = $query; | ||||
$this->priceResolver = $priceResolver; | |||||
} | |||||
public function getDatas(OrderShopInterface $orderShop = null): array | |||||
{ | |||||
$data = []; | |||||
if (is_null($orderShop)) { | |||||
$orderShop = $this->getCartCurrent(); | |||||
} | |||||
$data['order'] = $orderShop; | |||||
if ($orderShop) { | |||||
$data['count'] = $orderShop->countQuantities(); | |||||
$data['total_with_tax'] = $this->priceResolver->getTotalWithTax($orderShop); | |||||
$data['order_products_by_category'] = $orderShop->getOrderProductsByParentCategory(); | |||||
$data['total_remaining_to_be_paid'] = $this->getTotalRemainingToBePaid($orderShop); | |||||
} | |||||
return $data; | |||||
} | |||||
public function getAsJsonObject(OrderShopInterface $orderShop): array | |||||
{ | |||||
$data['id'] = $orderShop->getId(); | |||||
$data['user'] = $orderShop->getUser()->getSummary(); | |||||
$data['orderStatus'] = $orderShop->getOrderStatus()->__toString(); | |||||
$data['deliveryAddress'] = $orderShop->getDeliveryAddress()->getSummary(); | |||||
$data['invoiceAddress'] = $orderShop->getInvoiceAddress()->getSummary(); | |||||
$data['total'] = $this->priceResolver->getTotal($orderShop); | |||||
$data['totalWithTax'] = $this->priceResolver->getTotalWithTax($orderShop); | |||||
$data['totalWithTaxAndReduction'] = $this->priceResolver->getTotalWithTax($orderShop); | |||||
$i = 0; | |||||
foreach ($orderShop->getOrderProductsByParentCategory() as $labelCategory => $orderProducts) { | |||||
foreach ($orderProducts as $orderProduct) { | |||||
$data['orderProducts'][$i]['id'] = $orderProduct->getId(); | |||||
$data['orderProducts'][$i]['product'] = $orderProduct->getProduct()->getId(); | |||||
$data['orderProducts'][$i]['quantityOrder'] = $orderProduct->getQuantityOrder(); | |||||
$data['orderProducts'][$i]['labelCategory'] = $labelCategory; | |||||
$data['orderProducts'][$i]['title'] = $orderProduct->getTitle(); | |||||
$data['orderProducts'][$i]['price'] = $this->priceResolver->getPrice($orderProduct); | |||||
$data['orderProducts'][$i]['priceWithTax'] = $this->priceResolver->getPriceWithTax($orderProduct); | |||||
$data['orderProducts'][$i]['priceWithTaxAndReduction'] = $this->priceResolver->getPriceWithTaxAndReduction( | |||||
$orderProduct | |||||
); | |||||
$data['orderProducts'][$i]['quantity'] = $orderProduct->getQuantityOrder(); | |||||
$data['orderProducts'][$i]['totalWithTaxAndReduction'] = $this->priceResolver->getTotalOrderProductsWithTaxAndReduction( | |||||
array($orderProduct) | |||||
); | |||||
$i++; | |||||
} | |||||
} | |||||
return $data; | |||||
} | |||||
public function groupOrderProductsByProductFamily(array $orderProducts): array | |||||
{ | |||||
$orderProductsByProductFamily = []; | |||||
foreach ($orderProducts as $orderProduct) { | |||||
if ($orderProduct->getProduct() && $orderProduct->getProduct()->getProductFamily()) { | |||||
$productFamily = $orderProduct->getProduct()->getProductFamily(); | |||||
if (!isset($orderProductsByProductFamily[$productFamily->getId()])) { | |||||
$orderProductsByProductFamily[$productFamily->getId()] = [ | |||||
'order_products' => [], | |||||
'total_quantity_weight' => 0, | |||||
]; | |||||
} | |||||
$orderProductsByProductFamily[$productFamily->getId()]['order_products'][] = $orderProduct; | |||||
$orderProductsByProductFamily[$productFamily->getId( | |||||
)]['total_quantity_weight'] += ($orderProduct->getQuantityProduct() / $orderProduct->getUnit( | |||||
)->getCoefficient()) * $orderProduct->getQuantityOrder(); | |||||
} | |||||
} | |||||
return $orderProductsByProductFamily; | |||||
} | |||||
public function isPositiveAmount(OrderShopInterface $orderShop) | |||||
{ | |||||
return $this->priceResolver->getTotalWithTax($orderShop) >= 0; | |||||
} | |||||
public function isPaid(OrderShopInterface $orderShop, $mergeComplementaryOrderShop = false) | |||||
{ | |||||
$totalOrderPayments = $this->getTotalOrderPayments($orderShop, $mergeComplementaryOrderShop); | |||||
$totalOrder = $this->priceResolver->getTotalWithTax($orderShop); | |||||
if ((abs($totalOrderPayments - $totalOrder) < 0.00001 | |||||
|| $totalOrderPayments >= $totalOrder) | |||||
&& $totalOrder > 0) { | |||||
return true; | |||||
} else { | |||||
return false; | |||||
} | |||||
} | |||||
public function getTotalOrderPayments(OrderShopInterface $orderShop, $mergeComplementaryOrderShop = false): float | |||||
{ | |||||
$totalAmount = floatval(0); | |||||
foreach ($orderShop->getOrderPayments() as $orderPayment) { | |||||
$totalAmount = $orderPayment->getAmount() + $totalAmount; | |||||
} | |||||
if ($mergeComplementaryOrderShop) { | |||||
foreach ($orderShop->getComplementaryOrderShops() as $complementaryOrderShop) { | |||||
foreach ($complementaryOrderShop->getOrderPayments() as $orderPayment) { | |||||
$totalAmount = $orderPayment->getAmount() + $totalAmount; | |||||
} | |||||
} | |||||
} | |||||
return $totalAmount; | |||||
} | |||||
public function getTotalRemainingToBePaid(OrderShopInterface $orderShop): float | |||||
{ | |||||
return $this->priceResolver->getTotalWithTax($orderShop) - $this->getTotalOrderPayments($orderShop); | |||||
} | |||||
public function isOrderShopPositiveAmountRemainingToBePaid(OrderShopInterface $orderShop): bool | |||||
{ | |||||
return $this->getTotalRemainingToBePaid($orderShop) > 0; | |||||
} | } | ||||
} | } |
<?php | |||||
namespace Lc\CaracoleBundle\Resolver\Price; | |||||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | |||||
class OrderProductPriceResolver | |||||
{ | |||||
use PriceResolverTrait; | |||||
protected $ProductPriceResolver; | |||||
public function __construct(ProductPriceResolver $ProductPriceResolver) | |||||
{ | |||||
$this->ProductPriceResolver = $ProductPriceResolver; | |||||
} | |||||
public function getPrice(OrderProductInterface $orderProduct, $round = false) | |||||
{ | |||||
if ($round) { | |||||
return $this->round($orderProduct->getPrice()); | |||||
} else { | |||||
return $orderProduct->getPrice(); | |||||
} | |||||
} | |||||
public function getBuyingPrice(OrderProductInterface $orderProduct, $round = false) | |||||
{ | |||||
if ($round) { | |||||
return $this->round($orderProduct->getBuyingPrice()); | |||||
} else { | |||||
return $orderProduct->getBuyingPrice(); | |||||
} | |||||
} | |||||
public function getPriceWithTax(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $this->applyTax( | |||||
$this->getPrice($orderProduct), | |||||
$orderProduct->getTaxRate()->getValue() | |||||
); | |||||
} | |||||
public function getPriceWithTaxAndReduction(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $this->applyReductionCatalog( | |||||
$orderProduct, | |||||
$this->getPrice($orderProduct), | |||||
$this->getPriceWithTax($orderProduct) | |||||
); | |||||
} | |||||
public function getPriceWithReduction(OrderProductInterface $orderProduct, $round = true) | |||||
{ | |||||
return $this->applyReductionCatalog( | |||||
$orderProduct, | |||||
$this->getPrice($orderProduct), | |||||
$this->getPriceWithTax($orderProduct), | |||||
1, | |||||
null, | |||||
false, | |||||
$round | |||||
); | |||||
} | |||||
public function getTotal(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $orderProduct->getQuantityOrder() * $this->getPrice($orderProduct); | |||||
} | |||||
public function getTotalBuyingPrice(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $orderProduct->getQuantityOrder() * $this->getBuyingPrice($orderProduct); | |||||
} | |||||
public function getMargin(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $this->round($this->getPriceWithReduction($orderProduct, false) - $this->getBuyingPrice($orderProduct)); | |||||
} | |||||
public function getMarginPercent(OrderProductInterface $orderProduct) | |||||
{ | |||||
if ($this->getBuyingPrice($orderProduct) && $this->getPriceWithReduction($orderProduct)) { | |||||
return $this->round(($this->getMargin($orderProduct) / $this->getPriceWithReduction($orderProduct)) * 100); | |||||
} else { | |||||
return 0; | |||||
} | |||||
} | |||||
public function getTotalMargin(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $orderProduct->getQuantityOrder() * $this->getMargin($orderProduct); | |||||
} | |||||
public function getTotalWithReduction(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $this->applyReductionCatalog( | |||||
$orderProduct, | |||||
$this->getTotal($orderProduct), | |||||
$this->getTotalWithTax($orderProduct), | |||||
$orderProduct->getQuantityOrder(), | |||||
null, | |||||
false | |||||
); | |||||
} | |||||
public function getTotalWithTax(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $this->applyTax( | |||||
$this->getTotal($orderProduct), | |||||
$orderProduct->getTaxRateInherited()->getValue() | |||||
); | |||||
} | |||||
public function getTotalWithTaxAndReduction(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $this->applyReductionCatalog( | |||||
$orderProduct, | |||||
$this->getTotal($orderProduct), | |||||
$this->getTotalWithTax($orderProduct), | |||||
$orderProduct->getQuantityOrder() | |||||
); | |||||
} | |||||
public function getTotalBuyingPriceWithTax(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $this->applyTax( | |||||
$this->getTotalBuyingPrice($orderProduct), | |||||
$orderProduct->getTaxRateInherited()->getValue() | |||||
); | |||||
} | |||||
//inclus toujours les réductions catalogues | |||||
public function getTotalTaxes(OrderProductInterface $orderProduct) | |||||
{ | |||||
return $this->getTotalWithTaxAndReduction($orderProduct) - $this->getTotalWithReduction($orderProduct); | |||||
} | |||||
} | |||||
<?php | |||||
namespace Lc\CaracoleBundle\Resolver\Price; | |||||
use Lc\CaracoleBundle\Model\Order\OrderReductionCreditInterface; | |||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||||
use Lc\CaracoleBundle\Model\Reduction\ReductionCartModel; | |||||
use Lc\CaracoleBundle\Model\Reduction\ReductionCreditModel; | |||||
class OrderShopPriceResolver | |||||
{ | |||||
use PriceResolverTrait; | |||||
protected $orderProductPriceResolver; | |||||
public function __construct(OrderProductPriceResolver $orderProductPriceResolver) | |||||
{ | |||||
$this->orderProductPriceResolver = $orderProductPriceResolver; | |||||
} | |||||
//Inclus les ReductionCatalog des OrderProducts | |||||
public function getTotalOrderProducts(OrderShopInterface $orderShop): float | |||||
{ | |||||
// A tester calculer ce montant en faisant TotalOrderWithTax - TotalOrderTaxes | |||||
$total = 0; | |||||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||||
$total += $this->orderProductPriceResolver->getTotalWithReduction($orderProduct); | |||||
} | |||||
return $total; | |||||
} | |||||
//Inclus les ReductionCatalog des OrderProducts | |||||
public function getMarginOrderProducts(OrderShopInterface $orderShop): float | |||||
{ | |||||
$total = 0; | |||||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||||
$total += $this->orderProductPriceResolver->getTotalMargin($orderProduct); | |||||
} | |||||
return $total; | |||||
} | |||||
public function getMarginOrderProductsWithReductions(OrderShopInterface $orderShop, $cache = false): float | |||||
{ | |||||
if ($cache && $orderShop->getStatMarginOrderProductsWithReductions() !== null) { | |||||
return $orderShop->getStatMarginOrderProductsWithReductions(); | |||||
} else { | |||||
$total = $this->getMarginOrderProducts($orderShop); | |||||
$totalReductionAmount = 0; | |||||
foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) { | |||||
$totalReductionAmount += $this->getOrderProductsReductionCartAmountWithoutTax( | |||||
$orderShop, | |||||
$orderReductionCart | |||||
); | |||||
} | |||||
foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) { | |||||
$totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithoutTax( | |||||
$orderShop, | |||||
$orderReductionCredit | |||||
); | |||||
} | |||||
$total -= $totalReductionAmount; | |||||
return $total; | |||||
} | |||||
} | |||||
public function getMarginOrderProductsWithReductionsPercent(OrderShopInterface $orderShop): float | |||||
{ | |||||
if ($this->getTotalOrderProducts($orderShop)) { | |||||
return $this->round( | |||||
$this->getMarginOrderProductsWithReductions( | |||||
$orderShop | |||||
) / $this->getTotalOrderProductsWithReductions($orderShop) * 100 | |||||
); | |||||
} else { | |||||
return 0; | |||||
} | |||||
} | |||||
public function getMarginOrderProductsPercent(OrderShopInterface $orderShop): float | |||||
{ | |||||
if ($this->getTotalOrderProducts($orderShop)) { | |||||
return $this->round( | |||||
$this->getMarginOrderProducts($orderShop) / $this->getTotalOrderProducts($orderShop) * 100 | |||||
); | |||||
} else { | |||||
return 0; | |||||
} | |||||
} | |||||
public function getBrandTaxesOrderProductsWithReductionsPercent(OrderShopInterface $orderShop): float | |||||
{ | |||||
if ($this->getTotalOrderProducts($orderShop)) { | |||||
return $this->round( | |||||
$this->getMarginOrderProducts($orderShop) / $this->getTotalBuyingPriceOrderProducts( | |||||
$orderShop->getOrderProducts() | |||||
) * 100 | |||||
); | |||||
} else { | |||||
return 0; | |||||
} | |||||
} | |||||
public function getTotalOrderProductsWithTax(OrderShopInterface $orderShop): float | |||||
{ | |||||
return $this->getTotalOrderProductsWithTaxByOrderProducts($orderShop->getOrderProducts()); | |||||
} | |||||
public function getTotalBuyingPriceOrderProducts($orderProducts): float | |||||
{ | |||||
$total = 0; | |||||
foreach ($orderProducts as $orderProduct) { | |||||
$total += $this->orderProductPriceResolver->getTotalBuyingPrice($orderProduct); | |||||
} | |||||
return $total; | |||||
} | |||||
public function getTotalBuyingPriceOrderProductsWithTax($orderProducts): float | |||||
{ | |||||
$total = 0; | |||||
foreach ($orderProducts as $orderProduct) { | |||||
$total += $this->orderProductPriceResolver->getTotalBuyingPriceWithTax($orderProduct); | |||||
} | |||||
return $total; | |||||
} | |||||
public function getTotalOrderProductsWithTaxByOrderProducts($orderProducts): float | |||||
{ | |||||
$total = 0; | |||||
foreach ($orderProducts as $orderProduct) { | |||||
$total += $this->orderProductPriceResolver->getTotalWithTaxAndReduction($orderProduct); | |||||
} | |||||
return $total; | |||||
} | |||||
public function getTotalOrderProductsTaxes(OrderShopInterface $orderShop): float | |||||
{ | |||||
$total = 0; | |||||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||||
$total += $this->orderProductPriceResolver->getTotalTaxes($orderProduct) / $this->getReductionsCoef( | |||||
$orderShop | |||||
); | |||||
} | |||||
return $total; | |||||
} | |||||
public function getOrderProductsTaxesAsArray(OrderShopInterface $orderShop): array | |||||
{ | |||||
$orderProductsTaxes = []; | |||||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||||
$idTaxRate = $orderProduct->getTaxRate()->getId(); | |||||
if (!isset($orderProductsTaxes[$idTaxRate])) { | |||||
$orderProductsTaxes[$idTaxRate] = [ | |||||
'label' => $orderProduct->getTaxRate()->getValue() . '%', | |||||
'totalOrderProducts' => 0, | |||||
'totalTaxes' => 0, | |||||
]; | |||||
} | |||||
$orderProductsTaxes[$idTaxRate]['totalOrderProducts'] += $this->orderProductPriceResolver->getTotalWithReduction( | |||||
$orderProduct | |||||
) / $this->getReductionsCoef($orderShop); | |||||
$orderProductsTaxes[$idTaxRate]['totalTaxes'] += $this->orderProductPriceResolver->getTotalTaxes( | |||||
$orderProduct | |||||
) / $this->getReductionsCoef($orderShop); | |||||
} | |||||
return $orderProductsTaxes; | |||||
} | |||||
private function getReductionsCoef(OrderShopInterface $orderShop): float | |||||
{ | |||||
return $this->getTotalOrderProducts($orderShop) / $this->getTotalOrderProductsWithReductions($orderShop); | |||||
} | |||||
private function getTaxRateAverage(OrderShopInterface $orderShop): float | |||||
{ | |||||
return $this->getTotalOrderProductsWithTax($orderShop) / $this->getTotalOrderProducts($orderShop); | |||||
} | |||||
public function getTotalOrderProductsWithReductions(OrderShopInterface $orderShop, $cache = false) | |||||
{ | |||||
if ($cache && $orderShop->getStatTotalOrderProductsWithReductions() !== null) { | |||||
return $orderShop->getStatTotalOrderProductsWithReductions(); | |||||
} else { | |||||
$total = $this->getTotalOrderProducts($orderShop); | |||||
$total -= $this->getTotalReductionCartsAmount($orderShop); | |||||
$total -= $this->getTotalReductionCreditsAmount($orderShop); | |||||
return $total; | |||||
} | |||||
} | |||||
public function getTotalOrderProductsWithReductionCarts(OrderShopInterface $orderShop) | |||||
{ | |||||
$total = $this->getTotalOrderProducts($orderShop); | |||||
$total -= $this->getTotalReductionCartsAmount($orderShop); | |||||
return $total; | |||||
} | |||||
public function getTotalReductionCartsAmount(OrderShopInterface $orderShop) | |||||
{ | |||||
$totalReductionAmount = 0; | |||||
foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) { | |||||
$totalReductionAmount += $this->getOrderProductsReductionCartAmountWithoutTax( | |||||
$orderShop, | |||||
$orderReductionCart | |||||
); | |||||
} | |||||
return $totalReductionAmount; | |||||
} | |||||
public function getTotalReductionCreditsAmount(OrderShopInterface $orderShop) | |||||
{ | |||||
$totalReductionAmount = 0; | |||||
foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) { | |||||
$totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithoutTax( | |||||
$orderShop, | |||||
$orderReductionCredit | |||||
); | |||||
} | |||||
return $totalReductionAmount; | |||||
} | |||||
public function getTotalOrderProductsWithTaxAndReductions(OrderShopInterface $orderShop, $cache = false) | |||||
{ | |||||
if ($cache && $orderShop->getStatTotalOrderProductsWithTaxAndReductions() !== null) { | |||||
return $orderShop->getStatTotalOrderProductsWithTaxAndReductions(); | |||||
} else { | |||||
$total = $this->getTotalOrderProductsWithTax($orderShop); | |||||
$total -= $this->getTotalReductionCartsAmountWithTax($orderShop); | |||||
$total -= $this->getTotalReductionCreditsAmountWithTax($orderShop); | |||||
return $total; | |||||
} | |||||
} | |||||
public function getTotalOrderProductsWithTaxAndReductionCarts(OrderShopInterface $orderShop) | |||||
{ | |||||
$total = $this->getTotalOrderProductsWithTax($orderShop); | |||||
$total -= $this->getTotalReductionCartsAmountWithTax($orderShop); | |||||
return $total; | |||||
} | |||||
public function getTotalReductionCartsAmountWithTax(OrderShopInterface $orderShop) | |||||
{ | |||||
$totalReductionAmount = 0; | |||||
foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) { | |||||
$totalReductionAmount += $this->getOrderProductsReductionCartAmountWithTax($orderShop, $orderReductionCart); | |||||
} | |||||
return $totalReductionAmount; | |||||
} | |||||
public function getTotalReductionCreditsAmountWithTax(OrderShopInterface $orderShop) | |||||
{ | |||||
$totalReductionAmount = 0; | |||||
foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) { | |||||
$totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithTax( | |||||
$orderShop, | |||||
$orderReductionCredit | |||||
); | |||||
} | |||||
return $totalReductionAmount; | |||||
} | |||||
public function getOrderProductsReductionCartAmountWithoutTax(OrderShopInterface $order, $orderReductionCart) | |||||
{ | |||||
$amount = 0; | |||||
if ($orderReductionCart->getAppliedTo() === ReductionCartModel::APPLIED_TO_ORDER_PRODUCTS) { | |||||
if ($orderReductionCart->getUnit() == 'percent') { | |||||
$amount = $this->amountReductionByPercentValue( | |||||
$this->getTotalOrderProducts($order), | |||||
$orderReductionCart->getValue() | |||||
); | |||||
} else { | |||||
if ($orderReductionCart->getUnit() == 'amount') { | |||||
if ($orderReductionCart->getBehaviorTaxRate() == 'tax-excluded') { | |||||
$amount = $orderReductionCart->getValue(); | |||||
} else { | |||||
if ($orderReductionCart->getBehaviorTaxRate() == 'tax-included') { | |||||
$amount = $this->round($orderReductionCart->getValue() / $this->getTaxRateAverage($order)); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return $amount; | |||||
} | |||||
public function getOrderProductsReductionCartAmountWithTax(OrderShopInterface $order, $orderReductionCart) | |||||
{ | |||||
$amount = 0; | |||||
if ($orderReductionCart->getAppliedTo() === ReductionCartModel::APPLIED_TO_ORDER_PRODUCTS) { | |||||
if ($orderReductionCart->getUnit() == 'percent') { | |||||
$amount = $this->amountReductionByPercentValue( | |||||
$this->getTotalOrderProductsWithTax($order), | |||||
$orderReductionCart->getValue() | |||||
); | |||||
} elseif ($orderReductionCart->getUnit() == 'amount') { | |||||
if ($orderReductionCart->getBehaviorTaxRate() == 'tax-excluded') { | |||||
$amount = $this->round($orderReductionCart->getValue() * $this->getTaxRateAverage($order)); | |||||
} elseif ($orderReductionCart->getBehaviorTaxRate() == 'tax-included') { | |||||
$amount = $orderReductionCart->getValue(); | |||||
} | |||||
} | |||||
} | |||||
return $amount; | |||||
} | |||||
public function getOrderProductsReductionCreditAmountWithoutTax( | |||||
OrderShopInterface $order, | |||||
OrderReductionCreditInterface $orderReductionCredit | |||||
) { | |||||
$amount = 0; | |||||
if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-excluded') { | |||||
$amount = $orderReductionCredit->getValue(); | |||||
} else { | |||||
if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-included') { | |||||
$amount = $this->round($orderReductionCredit->getValue() / $this->getTaxRateAverage($order)); | |||||
} | |||||
} | |||||
return $amount; | |||||
} | |||||
public function getOrderProductsReductionCreditAmountWithTax( | |||||
OrderShopInterface $order, | |||||
OrderReductionCreditInterface $orderReductionCredit | |||||
) { | |||||
$amountWithTax = 0; | |||||
if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-excluded') { | |||||
$amountWithTax = $this->round($orderReductionCredit->getValue() * $this->getTaxRateAverage($order)); | |||||
} elseif ($orderReductionCredit->getBehaviorTaxRate() == 'tax-included') { | |||||
$amountWithTax = $orderReductionCredit->getValue(); | |||||
} | |||||
return $amountWithTax; | |||||
} | |||||
public function getTotalReductions(OrderShopInterface $orderShop) | |||||
{ | |||||
$total = 0; | |||||
foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) { | |||||
$total += $this->getOrderProductsReductionCartAmountWithoutTax($orderShop, $orderReductionCart); | |||||
} | |||||
foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) { | |||||
$total += $this->getOrderProductsReductionCreditAmountWithoutTax($orderShop, $orderReductionCredit); | |||||
} | |||||
return $total; | |||||
} | |||||
public function getTotalReductionsWithTax(OrderShopInterface $orderShop) | |||||
{ | |||||
$total = 0; | |||||
foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) { | |||||
$total += $this->getOrderProductsReductionCartAmountWithTax($orderShop, $orderReductionCart); | |||||
} | |||||
foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) { | |||||
$total += $this->getOrderProductsReductionCreditAmountWithTax($orderShop, $orderReductionCredit); | |||||
} | |||||
return $total; | |||||
} | |||||
} | |||||
<?php | |||||
namespace Lc\CaracoleBundle\Resolver\Price; | |||||
use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface; | |||||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | |||||
use Lc\CaracoleBundle\Model\Order\OrderShopInterface; | |||||
class PriceResolver | |||||
{ | |||||
protected ProductPriceResolver $productPriceResolver; | |||||
protected OrderProductPriceResolver $orderProductPriceResolver; | |||||
protected OrderShopPriceResolver $orderShopPriceResolver; | |||||
public function __construct( | |||||
ProductPriceResolver $productPriceResolver, | |||||
OrderProductPriceResolver $orderProductPriceResolver, | |||||
OrderShopPriceResolver $orderShopPriceResolver | |||||
) { | |||||
$this->productPriceResolver = $productPriceResolver; | |||||
$this->orderProductPriceResolver = $orderProductPriceResolver; | |||||
$this->orderShopPriceResolver = $orderShopPriceResolver; | |||||
} | |||||
public function __call($name, $arguments) | |||||
{ | |||||
if (strpos($name, 'apply') === false) { | |||||
$entity = $arguments[0]; | |||||
$service = ''; | |||||
if ($entity instanceof ProductPropertyInterface) { | |||||
$service = 'productPriceResolver'; | |||||
} | |||||
if ($entity instanceof OrderProductInterface) { | |||||
$service = 'orderProductPriceResolver'; | |||||
} | |||||
if ($entity instanceof OrderShopInterface || is_iterable($entity) || is_array($entity)) { | |||||
$service = 'orderShopPriceResolver'; | |||||
} | |||||
if (strlen($service) && $entity && method_exists($this->$service, $name)) { | |||||
if (isset($arguments[1]) && isset($arguments[2]) && isset($arguments[3])) { | |||||
return $this->$service->$name($entity, $arguments[1], $arguments[2], $arguments[3]); | |||||
} elseif (isset($arguments[1]) && isset($arguments[2])) { | |||||
return $this->$service->$name($entity, $arguments[1], $arguments[2]); | |||||
} elseif (isset($arguments[1])) { | |||||
return $this->$service->$name($entity, $arguments[1]); | |||||
} else { | |||||
return $this->$service->$name($entity); | |||||
} | |||||
} else { | |||||
if (!strlen($service)) { | |||||
throw new \ErrorException("PriceResolver : le type d'entité n'est pas géré"); | |||||
} else { | |||||
if (!method_exists($this->$service, $name)) { | |||||
throw new \ErrorException( | |||||
"PriceResolver : la méthode " . $name . " du service " . $service . " n'existe pas." | |||||
); | |||||
} | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\CaracoleBundle\Resolver\Price; | |||||
use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface; | |||||
use Lc\CaracoleBundle\Model\Order\OrderProductInterface; | |||||
trait PriceResolverTrait | |||||
{ | |||||
public function applyTax($price, $taxRateValue) | |||||
{ | |||||
return $this->round($this->applyPercent($price, $taxRateValue)); | |||||
} | |||||
public function applyReductionPercent($price, $percentage) | |||||
{ | |||||
return $this->applyPercent($price, -$percentage); | |||||
} | |||||
public function applyReductionAmount($price, $amount) | |||||
{ | |||||
return $price - $amount; | |||||
} | |||||
public function applyPercent($price, $percentage) | |||||
{ | |||||
return $price * ($percentage / 100 + 1); | |||||
} | |||||
public function applyPercentNegative($price, $percentage) | |||||
{ | |||||
return $price / ($percentage / 100 + 1); | |||||
} | |||||
public function round($price) | |||||
{ | |||||
return round((($price * 100)) / 100, 2); | |||||
} | |||||
public function amountReductionByPercentValue($price, $percent) | |||||
{ | |||||
return round((($price * $percent)) / 100, 2); | |||||
} | |||||
public function applyReductionCatalog( | |||||
$entity, | |||||
$price, | |||||
$priceWithTax, | |||||
$quantity = 1, | |||||
$reductionCatalog = null, | |||||
$withTax = true, | |||||
$round = true | |||||
): ?float { | |||||
if ($reductionCatalog) { | |||||
$reductionCatalogValue = $reductionCatalog->getValue(); | |||||
$reductionCatalogUnit = $reductionCatalog->getUnit(); | |||||
$reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate(); | |||||
} else { | |||||
if ($entity instanceof ProductPropertyInterface) { | |||||
$reductionCatalog = $entity->getReductionCatalogInherited(); | |||||
if ($reductionCatalog) { | |||||
$reductionCatalogValue = $reductionCatalog->getValue(); | |||||
$reductionCatalogUnit = $reductionCatalog->getUnit(); | |||||
$reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate(); | |||||
} | |||||
} | |||||
if ($entity instanceof OrderProductInterface) { | |||||
$orderProductReductionCatalog = $entity->getOrderProductReductionCatalog(); | |||||
if ($orderProductReductionCatalog) { | |||||
$reductionCatalogValue = $orderProductReductionCatalog->getValue(); | |||||
$reductionCatalogUnit = $orderProductReductionCatalog->getUnit(); | |||||
$reductionCatalogBehaviorTaxRate = $orderProductReductionCatalog->getBehaviorTaxRate(); | |||||
} | |||||
} | |||||
} | |||||
if (isset($reductionCatalogValue) && isset($reductionCatalogUnit) && isset($reductionCatalogBehaviorTaxRate)) { | |||||
if ($reductionCatalogUnit == 'percent') { | |||||
$priceWithTax = $this->applyReductionPercent( | |||||
$priceWithTax, | |||||
$reductionCatalogValue | |||||
); | |||||
} elseif ($reductionCatalogUnit == 'amount') { | |||||
if ($reductionCatalogBehaviorTaxRate == 'tax-excluded') { | |||||
$priceWithTax = $this->applyTax( | |||||
$this->applyReductionAmount( | |||||
$price, | |||||
$reductionCatalogValue * $quantity | |||||
), | |||||
$entity->getTaxRateInherited()->getValue() | |||||
); | |||||
} elseif ($reductionCatalogBehaviorTaxRate == 'tax-included') { | |||||
$priceWithTax = $this->applyReductionAmount( | |||||
$priceWithTax, | |||||
$reductionCatalogValue * $quantity | |||||
); | |||||
} | |||||
} | |||||
} | |||||
if ($withTax) { | |||||
$priceReturn = $priceWithTax; | |||||
} else { | |||||
$priceReturn = $this->applyPercentNegative($priceWithTax, $entity->getTaxRateInherited()->getValue()); | |||||
} | |||||
if ($round) { | |||||
return $this->round($priceReturn); | |||||
} else { | |||||
return $priceReturn; | |||||
} | |||||
} | |||||
} |
<?php | |||||
namespace Lc\CaracoleBundle\Resolver\Price; | |||||
use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface; | |||||
class ProductPriceResolver | |||||
{ | |||||
use PriceResolverTrait; | |||||
public function getPrice(ProductPropertyInterface $product) | |||||
{ | |||||
if ($product->getBehaviorPriceInherited() == 'by-piece') { | |||||
return $product->getPriceInherited(); | |||||
} elseif ($product->getBehaviorPriceInherited() == 'by-reference-unit') { | |||||
if ($product->getQuantityInherited() > 0) { | |||||
return $product->getPriceByRefUnitInherited() * ($product->getQuantityInherited( | |||||
) / $product->getUnitInherited()->getCoefficient()); | |||||
} else { | |||||
return 0; | |||||
} | |||||
} | |||||
} | |||||
public function getPriceWithTax(ProductPropertyInterface $product) | |||||
{ | |||||
return $this->applyTax( | |||||
$this->getPrice($product), | |||||
$product->getTaxRateInherited()->getValue() | |||||
); | |||||
} | |||||
public function getPriceByRefUnit(ProductPropertyInterface $product) | |||||
{ | |||||
if ($product->getBehaviorPriceInherited() == 'by-piece') { | |||||
return ($this->getPrice($product) * $product->getUnitInherited()->getCoefficient( | |||||
)) / $product->getQuantityInherited(); | |||||
} elseif ($product->getBehaviorPriceInherited() == 'by-reference-unit') { | |||||
return $product->getPriceByRefUnitInherited(); | |||||
} | |||||
} | |||||
public function getPriceByRefUnitWithTax(ProductPropertyInterface $product) | |||||
{ | |||||
return $this->applyTax( | |||||
$this->getPriceByRefUnit($product), | |||||
$product->getTaxRateInherited()->getValue() | |||||
); | |||||
} | |||||
public function getPriceWithTaxAndReduction(ProductPropertyInterface $product) | |||||
{ | |||||
return $this->applyReductionCatalog( | |||||
$product, | |||||
$this->getPrice($product), | |||||
$this->getPriceWithTax($product) | |||||
); | |||||
} | |||||
public function getPriceByRefUnitWithTaxAndReduction(ProductPropertyInterface $product) | |||||
{ | |||||
return ($this->getPriceByRefUnitWithTax($product) * $this->getPriceWithTaxAndReduction($product)) | |||||
/ $this->getPriceWithTax($product); | |||||
} | |||||
public function getBuyingPrice(ProductPropertyInterface $product) | |||||
{ | |||||
if ($product->getBehaviorPriceInherited() == 'by-piece') { | |||||
return $product->getBuyingPriceInherited(); | |||||
} elseif ($product->getBehaviorPriceInherited() == 'by-reference-unit') { | |||||
if ($product->getQuantityInherited() > 0) { | |||||
return $product->getBuyingPriceByRefUnitInherited() * ($product->getQuantityInherited( | |||||
) / $product->getUnitInherited()->getCoefficient()); | |||||
} else { | |||||
return 0; | |||||
} | |||||
} | |||||
} | |||||
public function getBuyingPriceWithTax(ProductPropertyInterface $product) | |||||
{ | |||||
return $this->applyTax( | |||||
$this->getBuyingPrice($product), | |||||
$product->getTaxRateInherited()->getValue() | |||||
); | |||||
} | |||||
public function getBuyingPriceByRefUnit(ProductPropertyInterface $product) | |||||
{ | |||||
return $product->getBuyingPriceByRefUnitInherited(); | |||||
} | |||||
public function getBuyingPriceByRefUnitWithTax(ProductPropertyInterface $product) | |||||
{ | |||||
return $this->applyTax( | |||||
$this->getBuyingPriceByRefUnit($product), | |||||
$product->getTaxRateInherited()->getValue() | |||||
); | |||||
} | |||||
public function getMultiplyingFactor(ProductPropertyInterface $product) | |||||
{ | |||||
return $this->round($this->getPriceWithTax($product) / $this->getBuyingPrice($product)); | |||||
} | |||||
} | |||||