Browse Source

PriceUtils : nouvelle gestion des prix

feature/export_comptable
Guillaume 4 years ago
parent
commit
441522c551
9 changed files with 316 additions and 171 deletions
  1. +8
    -0
      ShopBundle/Context/ProductFamilyUtilsInterface.php
  2. +1
    -1
      ShopBundle/Controller/Frontend/CartController.php
  3. +2
    -102
      ShopBundle/Model/PriceTrait.php
  4. +38
    -23
      ShopBundle/Model/Product.php
  5. +10
    -38
      ShopBundle/Model/ProductFamily.php
  6. +5
    -0
      ShopBundle/Model/ProductPropertyTrait.php
  7. +10
    -7
      ShopBundle/Services/OrderUtils.php
  8. +188
    -0
      ShopBundle/Services/PriceUtils.php
  9. +54
    -0
      ShopBundle/Services/ProductFamilyUtils.php

+ 8
- 0
ShopBundle/Context/ProductFamilyUtilsInterface.php View File

<?php

namespace Lc\ShopBundle\Context ;

interface ProductFamilyUtilsInterface
{

}

+ 1
- 1
ShopBundle/Controller/Frontend/CartController.php View File

foreach($data as $orderProduct) { foreach($data as $orderProduct) {
if($orderProduct instanceof OrderProductInterface) { if($orderProduct instanceof OrderProductInterface) {
$this->orderUtils->addOrderProduct($orderShop, $orderProduct) ; $this->orderUtils->addOrderProduct($orderShop, $orderProduct) ;
if($orderProduct->getQuantity() > 0) {
if($orderProduct->getQuantityorder() > 0) {
$this->orderProducts[] = $orderProduct ; $this->orderProducts[] = $orderProduct ;
} }
} }

+ 2
- 102
ShopBundle/Model/PriceTrait.php View File

*/ */
protected $taxRate; protected $taxRate;


public function getPrice(): ?float
{
return $this->price;
}

public function getPriceInherited(): ?float public function getPriceInherited(): ?float
{ {
return $this->getPrice() ; return $this->getPrice() ;
return $this->getTaxRate() ; 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 public function setPrice(?float $price): self


return $this; 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() ;
}
} }

+ 38
- 23
ShopBundle/Model/Product.php View File



public function getPriceInherited() public function getPriceInherited()
{ {
if($this->price) {
return $this->price;
if($this->getPrice()) {
return $this->getPrice();
} }
else { 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() 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() public function getTitleInherited()
{ {
if($this->title){
return $this->title;
if($this->getTitle()){
return $this->getTitle();
} }
else{ else{
return $this->productFamily->getTitle();
return $this->getProductFamily()->getTitle();
} }
} }


public function getQuantityInherited() public function getQuantityInherited()
{ {
if($this->quantity) {
return $this->quantity;
if($this->getQuantity()) {
return $this->getQuantity();
} }
else{ else{
return $this->productFamily->getQuantity();
return $this->getProductFamily()->getQuantity();
} }
} }




public function getAvailableQuantityInherited() 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() 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 public function getProductFamily(): ?ProductFamily

+ 10
- 38
ShopBundle/Model/ProductFamily.php View File

return $this->reductionCatalog; return $this->reductionCatalog;
} }


public function getReductionCatalogInherited(): ?ReductionCatalog
{
return $this->getReductionCatalog() ;
}

public function setReductionCatalog(?ReductionCatalog $reductionCatalog): self public function setReductionCatalog(?ReductionCatalog $reductionCatalog): self
{ {
$this->reductionCatalog = $reductionCatalog; $this->reductionCatalog = $reductionCatalog;
return $this; 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 public function isPropertyNoveltyOnline(): ?bool
{ {
if ($this->getPropertyNoveltyExpirationDate()) { if ($this->getPropertyNoveltyExpirationDate()) {
return $this->behaviorPrice; return $this->behaviorPrice;
} }


public function getBehaviorPriceInherited()
{
return $this->getBehaviorPrice() ;
}

public function setBehaviorPrice(?string $behaviorPrice): self public function setBehaviorPrice(?string $behaviorPrice): self
{ {
$this->behaviorPrice = $behaviorPrice; $this->behaviorPrice = $behaviorPrice;

+ 5
- 0
ShopBundle/Model/ProductPropertyTrait.php View File

return $this->priceByRefUnit; return $this->priceByRefUnit;
} }


public function getPriceByRefUnitInherited(): ?float
{
return $this->getPriceByRefUnit();
}

public function setPriceByRefUnit(?float $priceByRefUnit): self public function setPriceByRefUnit(?float $priceByRefUnit): self
{ {
$this->priceByRefUnit = $priceByRefUnit; $this->priceByRefUnit = $priceByRefUnit;

+ 10
- 7
ShopBundle/Services/OrderUtils.php View File

protected $userUtils; protected $userUtils;
protected $merchantUtils; protected $merchantUtils;
private $orderShopRepo; 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->em = $em;
$this->security = $security; $this->security = $security;
$this->userUtils = $userUtils; $this->userUtils = $userUtils;
$this->merchantUtils = $merchantUtils; $this->merchantUtils = $merchantUtils;
$this->orderShopRepo = $this->em->getRepository(OrderShop::class); $this->orderShopRepo = $this->em->getRepository(OrderShop::class);
$this->priceUtils = $priceUtils ;
} }


public function getOrderShopCurrent() public function getOrderShopCurrent()


public function addOrderProduct($orderShop, $orderProductAdd) public function addOrderProduct($orderShop, $orderProductAdd)
{ {
if ($orderProductAdd->getQuantity() > 0) {
if ($orderProductAdd->getQuantityOrder() > 0) {
$updated = false; $updated = false;


$orderProductAdd->setTitle($orderProductAdd->getTitleOrderShop()); $orderProductAdd->setTitle($orderProductAdd->getTitleOrderShop());
$orderProductAdd->setPrice($orderProductAdd->getProduct()->getPriceInherited());
$orderProductAdd->setPrice($this->priceUtils->getPrice($orderProductAdd->getProduct()));
$orderProductAdd->setUnit($orderProductAdd->getProduct()->getUnitInherited()); $orderProductAdd->setUnit($orderProductAdd->getProduct()->getUnitInherited());
$orderProductAdd->setTaxRate($orderProductAdd->getProduct()->getTaxRateInherited()); $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()) { if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()) {
$updated = true; $updated = true;
$orderProduct->setQuantity($orderProduct->getQuantity() + $orderProductAdd->getQuantity());
$orderProduct->setQuantityOrder($orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder());
$this->em->persist($orderProduct); $this->em->persist($orderProduct);
} }
} }
$count = 0; $count = 0;


foreach ($orderProducts as $orderProduct) { foreach ($orderProducts as $orderProduct) {
$count += $orderProduct->getQuantity();
$count += $orderProduct->getQuantityOrder();
} }


return $count; return $count;
$totalWithTax = 0; $totalWithTax = 0;


foreach ($orderProducts as $orderProduct) { foreach ($orderProducts as $orderProduct) {
$totalWithTax += $orderProduct->getPriceWithTax() * $orderProduct->getQuantity();
$totalWithTax += $this->priceUtils->getPriceWithTax($orderProduct) * $orderProduct->getQuantityOrder();
} }


return $totalWithTax; return $totalWithTax;

+ 188
- 0
ShopBundle/Services/PriceUtils.php View File

<?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);
}

}

+ 54
- 0
ShopBundle/Services/ProductFamilyUtils.php View File

<?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;
}
}

}

Loading…
Cancel
Save