Ver código fonte

PriceUtils : nouvelle gestion des prix

feature/export_comptable
Guillaume 4 anos atrás
pai
commit
441522c551
9 arquivos alterados com 316 adições e 171 exclusões
  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 Ver arquivo

@@ -0,0 +1,8 @@
<?php

namespace Lc\ShopBundle\Context ;

interface ProductFamilyUtilsInterface
{

}

+ 1
- 1
ShopBundle/Controller/Frontend/CartController.php Ver arquivo

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

+ 2
- 102
ShopBundle/Model/PriceTrait.php Ver arquivo

@@ -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() ;
}
}

+ 38
- 23
ShopBundle/Model/Product.php Ver arquivo

@@ -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

+ 10
- 38
ShopBundle/Model/ProductFamily.php Ver arquivo

@@ -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;

+ 5
- 0
ShopBundle/Model/ProductPropertyTrait.php Ver arquivo

@@ -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;

+ 10
- 7
ShopBundle/Services/OrderUtils.php Ver arquivo

@@ -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;

+ 188
- 0
ShopBundle/Services/PriceUtils.php Ver arquivo

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

}

+ 54
- 0
ShopBundle/Services/ProductFamilyUtils.php Ver arquivo

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

}

Carregando…
Cancelar
Salvar