@@ -0,0 +1,8 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Context ; | |||
interface ProductFamilyUtilsInterface | |||
{ | |||
} |
@@ -47,7 +47,7 @@ class CartController extends BaseController | |||
foreach($data as $orderProduct) { | |||
if($orderProduct instanceof OrderProductInterface) { | |||
$this->orderUtils->addOrderProduct($orderShop, $orderProduct) ; | |||
if($orderProduct->getQuantity() > 0) { | |||
if($orderProduct->getQuantityorder() > 0) { | |||
$this->orderProducts[] = $orderProduct ; | |||
} | |||
} |
@@ -24,11 +24,6 @@ trait PriceTrait | |||
*/ | |||
protected $taxRate; | |||
public function getPrice(): ?float | |||
{ | |||
return $this->price; | |||
} | |||
public function getPriceInherited(): ?float | |||
{ | |||
return $this->getPrice() ; | |||
@@ -44,80 +39,10 @@ trait PriceTrait | |||
return $this->getTaxRate() ; | |||
} | |||
public function getPriceWithTax(): ?float | |||
{ | |||
return $this->calculatePriceWithTax($this->getPriceInherited(), $this->getTaxRateInherited()->getValue()) ; | |||
} | |||
public function getPriceByUnitRef(): ?float | |||
{ | |||
return $this->calculatePriceByUnitRef($this->getPriceInherited()) ; | |||
} | |||
public function getPriceByUnitRefWithTax(): ?float | |||
{ | |||
return $this->calculatePriceByUnitRef($this->getPriceWithTax()) ; | |||
} | |||
public function getTheReductionCatalog() | |||
{ | |||
$reductionCatalog = false; | |||
if($this instanceof ProductFamily) { | |||
$reductionCatalog = $this->getReductionCatalog() ; | |||
} | |||
if($this instanceof Product) { | |||
$reductionCatalog = $this->getProductFamily()->getReductionCatalog() ; | |||
} | |||
return $reductionCatalog ; | |||
} | |||
public function getPriceByUnitRefWithTaxAndReduction(): ?float | |||
{ | |||
$reductionCatalog = $this->getTheReductionCatalog() ; | |||
if (isset($reductionCatalog) && $reductionCatalog) { | |||
return $this->calculatePriceByUnitRef($this->getPriceWithTaxAndReductionCatalog($reductionCatalog)) ; | |||
} | |||
else { | |||
return $this->calculatePriceByUnitRef($this->getPriceWithTax()); | |||
} | |||
} | |||
public function getPriceWithTaxAndReduction(): ?float | |||
{ | |||
$reductionCatalog = $this->getTheReductionCatalog() ; | |||
if (isset($reductionCatalog) && $reductionCatalog) { | |||
return $this->getPriceWithTaxAndReductionCatalog($reductionCatalog); | |||
} | |||
else { | |||
return $this->getPriceWithTax(); | |||
} | |||
} | |||
public function getPriceWithTaxAndReductionCatalog(ReductionCatalogInterface $reductionCatalog): ?float | |||
public function getPrice(): ?float | |||
{ | |||
if ($reductionCatalog->getUnit() == 'percent') { | |||
//Théoriquement que la réduction s'applique sur le prixHT ou le prixTTC le résultat est le même,j'ai laisser mon code au cas où ;) | |||
return $this->calculatePriceWithReductionPercent($this->getPriceWithTax(), $reductionCatalog->getValue()); | |||
/*if ($reductionCatalog->getBehaviorTaxRate() == 'tax-excluded') { | |||
$priceReductionHT = $this->calculatePriceWithReductionPercent($this->getPriceInherited(), $reductionCatalog->getValue()); | |||
return $this->calculatePriceWithTax($priceReductionHT, $this->getTaxRateInherited()->getValue()); | |||
} else if ($reductionCatalog->getBehaviorTaxRate() == 'tax-included') { | |||
return $this->calculatePriceWithReductionPercent($this->getPriceWithTax(), $reductionCatalog->getValue()); | |||
}*/ | |||
}elseif ($reductionCatalog->getUnit() == 'amount') { | |||
if ($reductionCatalog->getBehaviorTaxRate() == 'tax-excluded') { | |||
$priceReductionHT = $this->calculatePriceWithReductionAmount($this->getPriceInherited(), $reductionCatalog->getValue()); | |||
return $this->calculatePriceWithTax($priceReductionHT, $this->getTaxRateInherited()->getValue()); | |||
}else if ($reductionCatalog->getBehaviorTaxRate() == 'tax-included') { | |||
return $this->calculatePriceWithReductionAmount($this->getPriceWithTax(), $reductionCatalog->getValue()); | |||
} | |||
} | |||
return $this->price; | |||
} | |||
public function setPrice(?float $price): self | |||
@@ -150,29 +75,4 @@ trait PriceTrait | |||
return $this; | |||
} | |||
private function calculatePriceWithTax($priceWithoutTax, $taxRateValue): ?float | |||
{ | |||
$price = floatval($priceWithoutTax) * ($taxRateValue / 100 + 1); | |||
$price = round((($price * 100)) / 100, 2); | |||
return $price; | |||
} | |||
public function calculatePriceWithReductionPercent($price, $percentValue): ?float | |||
{ | |||
$price = floatval($price) * (1 - $percentValue / 100); | |||
$price = round((($price * 100)) / 100, 2); | |||
return $price; | |||
} | |||
public function calculatePriceWithReductionAmount($price, $amountValue): ?float | |||
{ | |||
$price = floatval($price) - $amountValue; | |||
$price = round((($price * 100)) / 100, 2); | |||
return $price; | |||
} | |||
private function calculatePriceByUnitRef($price) | |||
{ | |||
return ($price * $this->getUnitInherited()->getCoefficient()) / $this->getQuantityInherited() ; | |||
} | |||
} |
@@ -43,41 +43,61 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
public function getPriceInherited() | |||
{ | |||
if($this->price) { | |||
return $this->price; | |||
if($this->getPrice()) { | |||
return $this->getPrice(); | |||
} | |||
else { | |||
return $this->productFamily->getPrice(); | |||
return $this->getProductFamily()->getPrice(); | |||
} | |||
} | |||
public function getPriceByRefUnitInherited() | |||
{ | |||
if($this->getPriceByRefUnit()) { | |||
return $this->getPriceByRefUnit(); | |||
} | |||
else { | |||
return $this->getProductFamily()->getPriceByRefUnit(); | |||
} | |||
} | |||
public function getBehaviorPriceInherited() | |||
{ | |||
return $this->getProductFamily()->getBehaviorPrice() ; | |||
} | |||
public function getReductionCatalogInherited() | |||
{ | |||
return $this->getProductFamily()->getReductionCatalog() ; | |||
} | |||
public function getUnitInherited() | |||
{ | |||
if($this->unit) { | |||
return $this->unit; | |||
if($this->getUnit()) { | |||
return $this->getUnit(); | |||
} | |||
else{ | |||
return $this->productFamily->getUnit(); | |||
else { | |||
return $this->getProductFamily()->getUnit(); | |||
} | |||
} | |||
public function getTitleInherited() | |||
{ | |||
if($this->title){ | |||
return $this->title; | |||
if($this->getTitle()){ | |||
return $this->getTitle(); | |||
} | |||
else{ | |||
return $this->productFamily->getTitle(); | |||
return $this->getProductFamily()->getTitle(); | |||
} | |||
} | |||
public function getQuantityInherited() | |||
{ | |||
if($this->quantity) { | |||
return $this->quantity; | |||
if($this->getQuantity()) { | |||
return $this->getQuantity(); | |||
} | |||
else{ | |||
return $this->productFamily->getQuantity(); | |||
return $this->getProductFamily()->getQuantity(); | |||
} | |||
} | |||
@@ -90,22 +110,17 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
public function getAvailableQuantityInherited() | |||
{ | |||
if($this->productFamily->getBehaviorCountStock()) { | |||
return $this->availableQuantity; | |||
if($this->getProductFamily()->getBehaviorCountStock()) { | |||
return $this->getAvailableQuantity(); | |||
} | |||
else{ | |||
return $this->productFamily->getAvailableQuantity(); | |||
else { | |||
return $this->getProductFamily()->getAvailableQuantity(); | |||
} | |||
} | |||
public function getTaxRateInherited() | |||
{ | |||
if($this->productFamily->getTaxRate()) { | |||
return $this->productFamily->getTaxRate(); | |||
} | |||
else{ | |||
return $this->productFamily->getMerchant()->getTaxRate()->getValue(); | |||
} | |||
return $this->getProductFamily()->getTaxRateInherited(); | |||
} | |||
public function getProductFamily(): ?ProductFamily |
@@ -236,6 +236,11 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this->reductionCatalog; | |||
} | |||
public function getReductionCatalogInherited(): ?ReductionCatalog | |||
{ | |||
return $this->getReductionCatalog() ; | |||
} | |||
public function setReductionCatalog(?ReductionCatalog $reductionCatalog): self | |||
{ | |||
$this->reductionCatalog = $reductionCatalog; | |||
@@ -383,44 +388,6 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this; | |||
} | |||
private function getCheapestOrMostExpensiveProduct($comparisonFunction, $returnSelfIfNotActiveProducts) | |||
{ | |||
$products = $this->getProducts()->getValues(); | |||
if (count($products) > 0) { | |||
usort($products, $comparisonFunction); | |||
return $products[0]; | |||
} | |||
if ($returnSelfIfNotActiveProducts) { | |||
return $this; | |||
} else { | |||
return false; | |||
} | |||
} | |||
public function getCheapestProduct() | |||
{ | |||
return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) { | |||
return $a->getPriceInherited() > $b->getPriceInherited(); | |||
}, true); | |||
} | |||
public function getCheapestProductByUnitRef() | |||
{ | |||
return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) { | |||
return $a->getPriceByUnitRef() > $b->getPriceByUnitRef(); | |||
}, false); | |||
} | |||
public function getMostExpensiveProductByUnitRef() | |||
{ | |||
return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) { | |||
return $a->getPriceByUnitRef() < $b->getPriceByUnitRef(); | |||
}, false); | |||
} | |||
public function isPropertyNoveltyOnline(): ?bool | |||
{ | |||
if ($this->getPropertyNoveltyExpirationDate()) { | |||
@@ -585,6 +552,11 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this->behaviorPrice; | |||
} | |||
public function getBehaviorPriceInherited() | |||
{ | |||
return $this->getBehaviorPrice() ; | |||
} | |||
public function setBehaviorPrice(?string $behaviorPrice): self | |||
{ | |||
$this->behaviorPrice = $behaviorPrice; |
@@ -75,6 +75,11 @@ trait ProductPropertyTrait | |||
return $this->priceByRefUnit; | |||
} | |||
public function getPriceByRefUnitInherited(): ?float | |||
{ | |||
return $this->getPriceByRefUnit(); | |||
} | |||
public function setPriceByRefUnit(?float $priceByRefUnit): self | |||
{ | |||
$this->priceByRefUnit = $priceByRefUnit; |
@@ -14,14 +14,16 @@ class OrderUtils | |||
protected $userUtils; | |||
protected $merchantUtils; | |||
private $orderShopRepo; | |||
protected $priceUtils ; | |||
public function __construct(EntityManagerInterface $em, Security $security, UserUtils $userUtils, MerchantUtilsInterface $merchantUtils) | |||
public function __construct(EntityManagerInterface $em, Security $security, UserUtils $userUtils, MerchantUtilsInterface $merchantUtils, PriceUtils $priceUtils) | |||
{ | |||
$this->em = $em; | |||
$this->security = $security; | |||
$this->userUtils = $userUtils; | |||
$this->merchantUtils = $merchantUtils; | |||
$this->orderShopRepo = $this->em->getRepository(OrderShop::class); | |||
$this->priceUtils = $priceUtils ; | |||
} | |||
public function getOrderShopCurrent() | |||
@@ -84,18 +86,19 @@ class OrderUtils | |||
public function addOrderProduct($orderShop, $orderProductAdd) | |||
{ | |||
if ($orderProductAdd->getQuantity() > 0) { | |||
if ($orderProductAdd->getQuantityOrder() > 0) { | |||
$updated = false; | |||
$orderProductAdd->setTitle($orderProductAdd->getTitleOrderShop()); | |||
$orderProductAdd->setPrice($orderProductAdd->getProduct()->getPriceInherited()); | |||
$orderProductAdd->setPrice($this->priceUtils->getPrice($orderProductAdd->getProduct())); | |||
$orderProductAdd->setUnit($orderProductAdd->getProduct()->getUnitInherited()); | |||
$orderProductAdd->setTaxRate($orderProductAdd->getProduct()->getTaxRateInherited()); | |||
$orderProductAdd->setQuantityProduct($orderProductAdd->getProduct()->getQuantityInherited()); | |||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||
foreach($orderShop->getOrderProducts() as $orderProduct) { | |||
if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()) { | |||
$updated = true; | |||
$orderProduct->setQuantity($orderProduct->getQuantity() + $orderProductAdd->getQuantity()); | |||
$orderProduct->setQuantityOrder($orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()); | |||
$this->em->persist($orderProduct); | |||
} | |||
} | |||
@@ -120,7 +123,7 @@ class OrderUtils | |||
$count = 0; | |||
foreach ($orderProducts as $orderProduct) { | |||
$count += $orderProduct->getQuantity(); | |||
$count += $orderProduct->getQuantityOrder(); | |||
} | |||
return $count; | |||
@@ -136,7 +139,7 @@ class OrderUtils | |||
$totalWithTax = 0; | |||
foreach ($orderProducts as $orderProduct) { | |||
$totalWithTax += $orderProduct->getPriceWithTax() * $orderProduct->getQuantity(); | |||
$totalWithTax += $this->priceUtils->getPriceWithTax($orderProduct) * $orderProduct->getQuantityOrder(); | |||
} | |||
return $totalWithTax; |
@@ -0,0 +1,188 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Services ; | |||
use Lc\ShopBundle\Context\OrderProductInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductInterface; | |||
use Lc\ShopBundle\Context\ProductPropertyInterface; | |||
use Lc\ShopBundle\Context\ReductionCatalogInterface; | |||
class PriceUtils | |||
{ | |||
public function getPrice($entity) | |||
{ | |||
if($entity instanceof ProductPropertyInterface) { | |||
if($entity->getBehaviorPriceInherited() == 'by-piece') { | |||
return $entity->getPriceInherited() ; | |||
} | |||
elseif($entity->getBehaviorPriceInherited() == 'by-reference-unit') { | |||
if($entity->getQuantityInherited() > 0) { | |||
return $entity->getPriceByRefUnitInherited() * $entity->getQuantityInherited() ; | |||
} | |||
} | |||
} | |||
if($entity instanceof OrderProductInterface) { | |||
return $entity->getPrice() ; | |||
} | |||
return null ; | |||
} | |||
public function getPriceWithTax($entity) | |||
{ | |||
return $this->applyTax( | |||
$this->getPrice($entity), | |||
$entity->getTaxRateInherited()->getValue() | |||
) ; | |||
} | |||
public function getPriceWithTaxAndReduction($entity) | |||
{ | |||
return $this->getPriceWithTaxAndReductionCatalog( | |||
$entity, | |||
$this->getPrice($entity), | |||
$this->getPriceWithTax($entity) | |||
); | |||
} | |||
public function getPriceByRefUnit($entity) | |||
{ | |||
if($entity instanceof ProductPropertyInterface) { | |||
if($entity->getBehaviorPriceInherited() == 'by-piece') { | |||
return ($this->getPriceInherited($entity) * $entity->getUnitInherited()->getCoefficient()) / $entity->getQuantityInherited() ; | |||
} | |||
elseif($entity->getBehaviorPriceInherited() == 'by-reference-unit') { | |||
return $entity->getPriceByRefUnitInherited() ; | |||
} | |||
} | |||
if($entity instanceof OrderProductInterface) { | |||
return ($this->getPrice($entity) * $entity->getUnitInherited()->getCoefficient()) / $entity->getQuantityProduct() ; | |||
} | |||
return null ; | |||
} | |||
public function getPriceByRefUnitWithTax($entity) | |||
{ | |||
return $this->applyTax( | |||
$this->getPriceByRefUnit($entity), | |||
$entity->getTaxRateInherited()->getValue() | |||
) ; | |||
} | |||
public function getPriceByRefUnitWithTaxAndReduction($entity) | |||
{ | |||
return $this->getPriceWithTaxAndReductionCatalog( | |||
$entity, | |||
$this->getPriceByRefUnit($entity), | |||
$this->getPriceByRefUnitWithTax($entity) | |||
); | |||
} | |||
public function getTotal($entity) | |||
{ | |||
if($entity instanceof OrderProductInterface) { | |||
return $entity->getQuantityOrder() * $this->getPrice($entity) ; | |||
} | |||
return null ; | |||
} | |||
public function getTotalWithTax($entity) | |||
{ | |||
if($entity instanceof OrderProductInterface) { | |||
return $this->applyTax( | |||
$this->getTotal($entity), | |||
$entity->getTaxRateInherited()->getValue() | |||
) ; | |||
} | |||
return null ; | |||
} | |||
public function getTotalWithTaxAndReduction($entity) | |||
{ | |||
if($entity instanceof OrderProductInterface) { | |||
return $this->getPriceWithTaxAndReductionCatalog( | |||
$entity, | |||
$this->getTotal($entity), | |||
$this->getTotalWithTax($entity) | |||
) ; | |||
} | |||
} | |||
private function getPriceWithTaxAndReductionCatalog($entity, $price, $priceWithTax): ?float | |||
{ | |||
if($entity instanceof ProductPropertyInterface) { | |||
$reductionCatalog = $entity->getReductionCatalogInherited() ; | |||
if($reductionCatalog) { | |||
$reductionCatalogValue = $reductionCatalog->getValue() ; | |||
$reductionCatalogUnit = $reductionCatalog->getUnit() ; | |||
$reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate() ; | |||
} | |||
} | |||
if($entity instanceof OrderProductInterface) { | |||
// OrderProductReductionCatalog | |||
$reductionCatalog = null ; | |||
} | |||
if(isset($reductionCatalogValue) && isset($reductionCatalogUnit) && isset($reductionCatalogBehaviorTaxRate)) { | |||
if ($reductionCatalogUnit == 'percent') { | |||
return $this->applyReductionPercent( | |||
$priceWithTax, | |||
$reductionCatalogValue | |||
); | |||
} | |||
elseif ($reductionCatalogUnit == 'amount') { | |||
if($reductionCatalogBehaviorTaxRate == 'tax-excluded') { | |||
return $this->applyTax( | |||
$this->applyReductionAmount( | |||
$price, | |||
$reductionCatalogValue | |||
), | |||
$this->getTaxRateInherited()->getValue() | |||
); | |||
} | |||
elseif($reductionCatalogBehaviorTaxRate == 'tax-included') { | |||
return $this->applyReductionAmount( | |||
$priceWithTax, | |||
$reductionCatalogValue | |||
); | |||
} | |||
} | |||
} | |||
return $priceWithTax ; | |||
} | |||
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 round($price) | |||
{ | |||
return round((($price * 100)) / 100, 2); | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Services ; | |||
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface; | |||
class ProductFamilyUtils implements ProductFamilyUtilsInterface | |||
{ | |||
protected $priceUtils ; | |||
public function __construct(PriceUtils $priceUtils) | |||
{ | |||
$this->priceUtils = $priceUtils ; | |||
} | |||
public function getCheapestProduct($productFamily) | |||
{ | |||
$priceUtils = $this->priceUtils ; | |||
return $this->getCheapestOrMostExpensiveProduct($productFamily->getProducts()->getValues(), function ($a, $b) use ($priceUtils) { | |||
return $priceUtils->getPriceWithTaxAndReduction($a) > $priceUtils->getPriceWithTaxAndReduction($b) ; | |||
}, true); | |||
} | |||
public function getCheapestProductByRefUnit($productFamily) | |||
{ | |||
$priceUtils = $this->priceUtils ; | |||
return $this->getCheapestOrMostExpensiveProduct($productFamily->getProducts()->getValues(), function ($a, $b) use ($priceUtils) { | |||
return $priceUtils->getPriceByRefUnitWithTaxAndReduction($a) > $priceUtils->getPriceByRefUnitWithTaxAndReduction($b) ; | |||
}, false); | |||
} | |||
public function getMostExpensiveProductByRefUnit($productFamily) | |||
{ | |||
$priceUtils = $this->priceUtils ; | |||
return $this->getCheapestOrMostExpensiveProduct($productFamily->getProducts()->getValues(), function ($a, $b) use ($priceUtils) { | |||
return $priceUtils->getPriceByRefUnitWithTaxAndReduction($a) < $priceUtils->getPriceByRefUnitWithTaxAndReduction($b) ; | |||
}, false); | |||
} | |||
private function getCheapestOrMostExpensiveProduct($products, $comparisonFunction, $returnSelfIfNotActiveProducts) | |||
{ | |||
if (count($products) > 0) { | |||
usort($products, $comparisonFunction); | |||
return $products[0]; | |||
} | |||
if ($returnSelfIfNotActiveProducts) { | |||
return $this; | |||
} | |||
else { | |||
return false; | |||
} | |||
} | |||
} |