@@ -71,7 +71,7 @@ class ProductFamilyController extends AdminController | |||
$formBuilder->add('propertyOrganicLabel', ChoiceType::class, array( | |||
'choices' => array( | |||
'field.ProductFamily.organicLabelOptions.bio' => 'by-quantity', | |||
'field.ProductFamily.organicLabelOptions.ab' => 'ab', | |||
'field.ProductFamily.organicLabelOptions.natureProgres' => 'nature-progres', | |||
'field.ProductFamily.organicLabelOptions.hVE' => 'hve' | |||
), |
@@ -50,7 +50,7 @@ trait PriceTrait | |||
public function getPriceByUnitRef() | |||
{ | |||
return $this->getPriceInherited() * $this->getUnitInherited()->getCoefficient() ; | |||
return ($this->getPriceInherited() * $this->getUnitInherited()->getCoefficient()) / $this->getQuantityInherited() ; | |||
} | |||
public function getPriceByUnitRefWithTax() | |||
@@ -91,8 +91,8 @@ trait PriceTrait | |||
private function calculatePriceWithTax($priceWithoutTax, $taxRateValue) | |||
{ | |||
$price = floatval($priceWithoutTax) * ($taxRateValue + 1) ; | |||
$price = number_format(( ($price * 100)) / 100, 2) ; | |||
$price = floatval($priceWithoutTax) * ($taxRateValue/100 + 1) ; | |||
$price = round(( ($price * 100)) / 100, 2) ; | |||
return $price ; | |||
} | |||
} |
@@ -67,6 +67,13 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
} | |||
} | |||
public function getQuantityLabelInherited() | |||
{ | |||
$quantity = $this->getQuantityInherited() ; | |||
$unit = $this->getUnitInherited() ; | |||
return $quantity.$unit->getWordingShort() ; | |||
} | |||
public function getAvailableQuantityInherited() | |||
{ | |||
if($this->productFamily->getBehaviorCountStock()) { |
@@ -61,6 +61,15 @@ abstract class ProductCategory extends AbstractDocumentEntity implements TreeInt | |||
return $this; | |||
} | |||
public function getParentCategory() | |||
{ | |||
if($this->getParent()) { | |||
return $this->getParent() ; | |||
} | |||
return $this ; | |||
} | |||
/** | |||
* @return Collection|self[] | |||
*/ |
@@ -118,6 +118,10 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
*/ | |||
protected $typeExpirationDate; | |||
/** | |||
* @ORM\Column(type="string", length=32, nullable=true) | |||
*/ | |||
protected $behaviorAddToCart; | |||
public function __construct() | |||
{ | |||
@@ -233,6 +237,30 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this; | |||
} | |||
public function getProductCategoryParent() | |||
{ | |||
$productCategories = $this->getProductCategories() ; | |||
if(count($productCategories) > 0) { | |||
return $productCategories[0]->getParent() ; | |||
} | |||
return false ; | |||
} | |||
public function getProductCategoryChild() | |||
{ | |||
$productCategories = $this->getProductCategories() ; | |||
foreach($productCategories as $productCategory) { | |||
if($productCategory->getParent()) { | |||
return $productCategory ; | |||
} | |||
} | |||
return false ; | |||
} | |||
public function getSupplierTaxRate(): ?TaxRate | |||
{ | |||
return $this->supplierTaxRate; | |||
@@ -358,21 +386,16 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
},false) ; | |||
} | |||
public function isPropertyNoveltyOnline(): ?bool | |||
{ | |||
if($this->getPropertyNoveltyExpirationDate()) { | |||
$now = new \DateTime() ; | |||
if($now <= $this->getNoveltyExpirationDate()) { | |||
if($now <= $this->getPropertyNoveltyExpirationDate()) { | |||
return true ; | |||
} | |||
} | |||
else { | |||
return false ; | |||
} | |||
return false ; | |||
} | |||
public function getPropertyNoveltyExpirationDate(): ?\DateTimeInterface | |||
@@ -435,6 +458,18 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this; | |||
} | |||
public function countProperties(): bool | |||
{ | |||
$count = 0 ; | |||
$count += (int) strlen($this->getPropertyAllergens()) > 0 ; | |||
$count += (int) strlen($this->getPropertyComposition()) > 0 ; | |||
$count += (int) strlen($this->getPropertyFragrances()) > 0 ; | |||
$count += (int) strlen($this->getPropertyOrganicLabel()) > 0 ; | |||
$count += (int) ($this->getPropertyExpirationDate() != null) ; | |||
return $count ; | |||
} | |||
public function getBehaviorExpirationDate(): ?string | |||
{ | |||
@@ -460,4 +495,56 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this; | |||
} | |||
public function getBehaviorAddToCart(): ?string | |||
{ | |||
return $this->behaviorAddToCart; | |||
} | |||
public function setBehaviorAddToCart(?string $behaviorAddToCart): self | |||
{ | |||
$this->behaviorAddToCart = $behaviorAddToCart; | |||
return $this; | |||
} | |||
public function hasProductsWithVariousWeight() | |||
{ | |||
if($this->getActiveProducts()) { | |||
$arrayCountProducts = [] ; | |||
$products = $this->getProducts() ; | |||
foreach($products as $product) { | |||
$titleProduct = $product->getTitleInherited() ; | |||
if(!isset($arrayCountProducts[$titleProduct])) { | |||
$arrayCountProducts[$titleProduct] = [] ; | |||
} | |||
if(!in_array($product->getQuantityLabelInherited(), $arrayCountProducts[$titleProduct])) { | |||
$arrayCountProducts[$titleProduct][] = $product->getQuantityLabelInherited() ; | |||
} | |||
if(count($arrayCountProducts[$titleProduct]) > 1) { | |||
return true ; | |||
} | |||
} | |||
} | |||
return false ; | |||
} | |||
public function getProductsGroupByTitle() | |||
{ | |||
$arrayProductsGroupByTitle = [] ; | |||
$products = $this->getProducts() ; | |||
foreach($products as $product) { | |||
$titleProduct = $product->getTitleInherited() ; | |||
if(!isset($arrayProductsGroupByTitle[$titleProduct])) { | |||
$arrayProductsGroupByTitle[$titleProduct] = [] ; | |||
} | |||
$arrayProductsGroupByTitle[$titleProduct][] = $product ; | |||
} | |||
return $arrayProductsGroupByTitle ; | |||
} | |||
} |
@@ -60,6 +60,11 @@ trait ProductPropertyTrait | |||
return $this; | |||
} | |||
public function getQuantityInherited(): ?float | |||
{ | |||
return $this->getQuantity() ; | |||
} | |||
public function getAvailableQuantity(): ?float | |||
{ | |||
return $this->availableQuantity; |
@@ -30,21 +30,23 @@ class ProductCategoryRepository extends BaseRepository implements DefaultReposit | |||
public function findAllParents() | |||
{ | |||
return $this->findByMerchantQuery() | |||
$query = $this->findByMerchantQuery() | |||
->andWhere('e.parent is NULL') | |||
->andWhere('e.status = 1') | |||
->orderBy('e.position', 'ASC') | |||
->getQuery() | |||
->getResult(); | |||
return $query->getQuery()->getResult(); | |||
} | |||
public function findAllByParent($parentCategory) | |||
{ | |||
//$query = $this->findByMerchantQuery($this->globalParam->getCurrentMerchant()) ; | |||
$query = $this->createQueryBuilder('e') ; | |||
$query->andWhere('e.parent = :idParentCategory') | |||
->setParameter('idParentCategory', $parentCategory->getId()); | |||
return $query->getQuery()->getResult() ; | |||
} | |||
} |
@@ -18,4 +18,46 @@ class ProductFamilyRepository extends BaseRepository implements DefaultRepositor | |||
return ProductFamilyInterface::class; | |||
} | |||
public function findNovelties() | |||
{ | |||
$query = $this->findByMerchantQuery() ; | |||
$query->andWhere(':now <= e.propertyNoveltyExpirationDate') | |||
->setParameter('now', new \DateTime()) ; | |||
return $query->getQuery()->getResult() ; | |||
} | |||
public function findNoveltiesByParentCategories() | |||
{ | |||
return $this->_productsByParentCategories($this->findNovelties()) ; | |||
} | |||
public function findOrganics() | |||
{ | |||
$query = $this->findByMerchantQuery() ; | |||
$query->andWhere('e.propertyOrganicLabel IS NOT NULL'); | |||
return $query->getQuery()->getResult() ; | |||
} | |||
public function findOrganicsByParentCategories() | |||
{ | |||
return $this->_productsByParentCategories($this->findOrganics()) ; | |||
} | |||
public function _productsByParentCategories($products) | |||
{ | |||
$categoriesArray = [] ; | |||
foreach($products as $product) { | |||
$productCategories = $product->getProductCategories() ; | |||
$category = $productCategories[0]->getParentCategory() ; | |||
if(!isset($categoriesArray[$category->getId()])) { | |||
$categoriesArray[$category->getId()] = [ | |||
'category' => $category, | |||
'products' => [] | |||
] ; | |||
} | |||
$categoriesArray[$category->getId()]['products'][] = $product ; | |||
} | |||
return $categoriesArray; | |||
} | |||
} |
@@ -117,7 +117,7 @@ field: | |||
byProductFamily: Gérer le stock par produit (à l'unité) | |||
byProduct: Gérer le stock par déclainaison | |||
organicLabelOptions: | |||
bio: Agriculture biologique | |||
ab: Agriculture biologique | |||
hVE: Haute valeur environnementale | |||
natureProgres: Nature & progrès | |||
behaviorExpirationDate: Gèrer |
@@ -227,7 +227,7 @@ | |||
<script src="{{ asset('bundles/lcshop/js/backend/script/default/init-common.js') }}"></script> | |||
{% endblock script_javascript %} | |||
{% block add_script_javascript %}{% endblock add_script_javascript %} | |||
</body> | |||
{% endblock body %} | |||
</html> |
@@ -42,7 +42,7 @@ | |||
{% if formValues.propertyNoveltyExpirationDate %}propertyNoveltyExpirationDateActive: true,{% endif %} | |||
{% if formValues.typeExpirationDate %}typeExpirationDate: "{{ formValues.typeExpirationDate }}",{% endif %} | |||
{% if formValues.behaviorExpirationDate %}behaviorExpirationDate: "{{ formValues.behaviorExpirationDate }}",{% endif %} | |||
{% if formValues.propertyExpirationDate %}propertyExpirationDate: "{{ formValues.propertyExpirationDate }}",{% endif %} | |||
{% if formValues.propertyExpirationDate %}propertyExpirationDate: "{{ formValues.propertyExpirationDate|date('d/m/Y') }}",{% endif %} | |||
}; | |||
window.productUnitPriceValues = { | |||
{% if formValues.unit %}unit: parseInt({{ formValues.unit.id }}),{% endif %} |
@@ -2,6 +2,7 @@ | |||
namespace Lc\ShopBundle\Services; | |||
use Cocur\Slugify\Slugify; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\ShopBundle\Context\PageInterface; | |||
use Lc\ShopBundle\Context\TaxRateInterface; | |||
@@ -145,4 +146,10 @@ class Utils | |||
return $text; | |||
} | |||
public function slugify($string) | |||
{ | |||
$slugify = new Slugify(); | |||
return $slugify->slugify($string) ; | |||
} | |||
} |
@@ -6,6 +6,7 @@ use Lc\ShopBundle\Context\PageInterface; | |||
use Lc\ShopBundle\Form\Frontend\NewsletterType; | |||
use Lc\ShopBundle\Services\Utils; | |||
use Twig\Extension\AbstractExtension; | |||
use Twig\TwigFilter; | |||
use Twig\TwigFunction; | |||
class BridgeTwigExtension extends AbstractExtension | |||
@@ -31,6 +32,7 @@ class BridgeTwigExtension extends AbstractExtension | |||
public function getFilters() | |||
{ | |||
return [ | |||
new TwigFilter('slugify', [$this, 'slugify']), | |||
]; | |||
} | |||
@@ -53,4 +55,9 @@ class BridgeTwigExtension extends AbstractExtension | |||
{ | |||
return $this->utils->getElementByDevAlias($devAlias, $class) ; | |||
} | |||
public function slugify($string) | |||
{ | |||
return $this->utils->slugify($string) ; | |||
} | |||
} |
@@ -5,9 +5,14 @@ namespace Lc\ShopBundle\Twig; | |||
use App\Repository\HubRepository; | |||
use App\Services\GlobalParam; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\ShopBundle\Context\GlobalParamInterface; | |||
use Lc\ShopBundle\Context\MerchantInterface; | |||
use Lc\ShopBundle\Context\ProductCategoryInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Form\Frontend\NewsletterType; | |||
use Lc\ShopBundle\Repository\ProductCategoryRepository; | |||
use Symfony\Component\Form\FormFactoryInterface; | |||
use Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\Security\Core\Security; | |||
use Twig\Extension\AbstractExtension; | |||
use Twig\TwigFilter; | |||
@@ -19,18 +24,22 @@ class FrontendTwigExtension extends AbstractExtension | |||
protected $security ; | |||
protected $globalParam ; | |||
protected $formFactory ; | |||
protected $requestStack ; | |||
protected $productCategoryRepository ; | |||
protected $hubRepository ; | |||
protected $merchantRepository ; | |||
protected $productFamilyRepository ; | |||
public function __construct(EntityManagerInterface $em, Security $security, ProductCategoryRepository $productCategoryRepository, | |||
GlobalParam $globalParam, FormFactoryInterface $formFactory, HubRepository $hubRepository) | |||
public function __construct(EntityManagerInterface $em, Security $security, GlobalParamInterface $globalParam, | |||
FormFactoryInterface $formFactory, RequestStack $requestStack) | |||
{ | |||
$this->em = $em ; | |||
$this->security = $security ; | |||
$this->productCategoryRepository = $productCategoryRepository ; | |||
$this->hubRepository = $hubRepository ; | |||
$this->globalParam = $globalParam ; | |||
$this->formFactory = $formFactory ; | |||
$this->requestStack = $requestStack ; | |||
$this->productCategoryRepository = $this->em->getRepository($this->em->getClassMetadata(ProductCategoryInterface::class)->getName()) ; | |||
$this->merchantRepository = $this->em->getRepository($this->em->getClassMetadata(MerchantInterface::class)->getName()) ; | |||
$this->productFamilyRepository = $this->em->getRepository($this->em->getClassMetadata(ProductFamilyInterface::class)->getName()) ; | |||
} | |||
public function getFunctions() | |||
@@ -63,15 +72,14 @@ class FrontendTwigExtension extends AbstractExtension | |||
public function formatPrice($price) | |||
{ | |||
$price = number_format($price, 2) ; | |||
$price = str_replace('.',',',$price) ; | |||
$price = number_format($price, 2, ',', ' ') ; | |||
$price = $price .' €' ; | |||
return $price ; | |||
} | |||
public function getMerchants() | |||
{ | |||
return $this->hubRepository->findAll() ; | |||
return $this->merchantRepository->findAll() ; | |||
} | |||
} |