Browse Source

Livraisons Produits/réductions

master
Fab 4 years ago
parent
commit
130ab33218
38 changed files with 1413 additions and 717 deletions
  1. +8
    -0
      ShopBundle/Context/OrderProductReductionCatalogInterface.php
  2. +8
    -0
      ShopBundle/Context/ProductFamilyUtilsInterface.php
  3. +80
    -67
      ShopBundle/Controller/Admin/AdminController.php
  4. +1
    -1
      ShopBundle/Controller/Admin/OrderController.php
  5. +56
    -42
      ShopBundle/Controller/Admin/ProductFamilyController.php
  6. +1
    -1
      ShopBundle/Controller/Frontend/CartController.php
  7. +4
    -7
      ShopBundle/Form/ProductType.php
  8. +96
    -12
      ShopBundle/Form/ReductionCatalogType.php
  9. +1
    -1
      ShopBundle/Model/OrderAmountMin.php
  10. +21
    -1
      ShopBundle/Model/OrderProduct.php
  11. +31
    -0
      ShopBundle/Model/OrderProductReductionCatalog.php
  12. +3
    -103
      ShopBundle/Model/PriceTrait.php
  13. +38
    -23
      ShopBundle/Model/Product.php
  14. +11
    -39
      ShopBundle/Model/ProductFamily.php
  15. +8
    -3
      ShopBundle/Model/ProductPropertyTrait.php
  16. +2
    -1
      ShopBundle/Model/ReductionCart.php
  17. +18
    -5
      ShopBundle/Model/ReductionCatalog.php
  18. +61
    -0
      ShopBundle/Model/ReductionPropertyTrait.php
  19. +0
    -55
      ShopBundle/Model/ReductionTrait.php
  20. +14
    -0
      ShopBundle/Repository/ProductFamilyRepository.php
  21. +6
    -1
      ShopBundle/Resources/public/css/backend/custom.css
  22. +13
    -1
      ShopBundle/Resources/public/js/backend/script/default/utils.js
  23. +150
    -90
      ShopBundle/Resources/public/js/backend/script/default/vuejs-mixins.js
  24. +140
    -63
      ShopBundle/Resources/public/js/backend/script/productfamily/vuejs-product-family.js
  25. +1
    -24
      ShopBundle/Resources/public/js/backend/script/reductioncatalog/vuejs-reduction-catalog.js
  26. +10
    -3
      ShopBundle/Resources/translations/lcshop.fr.yaml
  27. +128
    -3
      ShopBundle/Resources/views/backend/default/block/macros.html.twig
  28. +1
    -0
      ShopBundle/Resources/views/backend/default/list-fields/field_price.html.twig
  29. +13
    -0
      ShopBundle/Resources/views/backend/productfamily/edit.html.twig
  30. +12
    -2
      ShopBundle/Resources/views/backend/productfamily/form.html.twig
  31. +25
    -24
      ShopBundle/Resources/views/backend/productfamily/panel_price.html.twig
  32. +66
    -6
      ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig
  33. +21
    -0
      ShopBundle/Resources/views/backend/productfamily/panel_reduction.html.twig
  34. +1
    -1
      ShopBundle/Resources/views/backend/productfamily/panel_stock.html.twig
  35. +2
    -108
      ShopBundle/Resources/views/backend/reductioncatalog/form.html.twig
  36. +68
    -30
      ShopBundle/Services/OrderUtils.php
  37. +242
    -0
      ShopBundle/Services/PriceUtils.php
  38. +52
    -0
      ShopBundle/Services/ProductFamilyUtils.php

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

<?php

namespace Lc\ShopBundle\Context ;

interface OrderProductReductionCatalogInterface
{

}

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

<?php

namespace Lc\ShopBundle\Context ;

interface ProductFamilyUtilsInterface
{

}

+ 80
- 67
ShopBundle/Controller/Admin/AdminController.php View File

return $this->executeDynamicMethod('render<EntityName>Template', ['sortable', "@LcShop/backend/default/sortable.html.twig", $parameters]); return $this->executeDynamicMethod('render<EntityName>Template', ['sortable', "@LcShop/backend/default/sortable.html.twig", $parameters]);
} }


public function createEntityFormBuilder($entity, $view)
public function createEntityFormBuilder($entity, $view, $override = true)
{ {


$formBuilder = parent::createEntityFormBuilder($entity, $view); $formBuilder = parent::createEntityFormBuilder($entity, $view);


if($override)$formBuilder = $this->overrideFormBuilder($formBuilder, $entity, $view);

return $formBuilder;
}

public function overrideFormBuilder($formBuilder, $entity, $view){
$id = (null !== $entity->getId()) ? $entity->getId() : 0; $id = (null !== $entity->getId()) ? $entity->getId() : 0;


if ($entity instanceof StatusInterface) { if ($entity instanceof StatusInterface) {


$formBuilder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) { $formBuilder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
$form = $event->getForm(); $form = $event->getForm();
$allChilds = $form->all();
foreach ($allChilds as $child) {
$statusInterface = false;
$treeInterface = false;
$type = $child->getConfig()->getType()->getInnerType();

if ($type instanceof EntityType) {
$passedOptions = $child->getConfig()->getOptions();
$classImplements = class_implements($passedOptions['class']);

$isFilterMerchantInterface = in_array('Lc\ShopBundle\Context\FilterMerchantInterface', $classImplements) ;
$isFilterMultipleMerchantsInterface = in_array('Lc\ShopBundle\Context\FilterMultipleMerchantsInterface', $classImplements) ;

if ($isFilterMerchantInterface || $isFilterMultipleMerchantsInterface) {

if (in_array('Lc\ShopBundle\Context\StatusInterface', $classImplements)) {
$statusInterface = true;
}

if (in_array('Lc\ShopBundle\Context\TreeInterface', $classImplements)) {
$treeInterface = true;
}
$propertyMerchant = 'merchant';
if($isFilterMultipleMerchantsInterface) {
$propertyMerchant .= 's' ;
}

$form->add($child->getName(), EntityType::class, array(
'class' => $this->em->getClassMetadata($passedOptions['class'])->getName(),
'label' => $passedOptions['label'],
'multiple' => isset($passedOptions['multiple']) ? $passedOptions['multiple'] : false,
'placeholder' => '--',
'translation_domain'=> 'lcshop',
'query_builder' => function (EntityRepository $repo) use ($passedOptions, $propertyMerchant, $statusInterface, $treeInterface, $child) {
$queryBuilder = $repo->createQueryBuilder('e');
$propertyMerchant = 'e.' . $propertyMerchant;

if ($passedOptions['class'] == 'App\Entity\PointSale') {
$queryBuilder->where(':currentMerchant MEMBER OF ' . $propertyMerchant);
} else {
$queryBuilder->where($propertyMerchant . ' = :currentMerchant');
}

if($statusInterface){
$queryBuilder->andWhere('e.status >= 0');
}
if($treeInterface && $child->getName() =='parent'){
$queryBuilder->andWhere('e.parent is null');
}
$queryBuilder->setParameter(':currentMerchant', $this->getUser()->getMerchant()->getId());

return $queryBuilder;
},
'choice_label' => function($choice) {
if($choice instanceof StatusInterface && $choice->getStatus() == 0){
return $choice.' [hors ligne]';
}
return $choice;

},
'required' => $passedOptions['required'],
)
);
$childrens = $form->all();
$this->loopFormField($form, $childrens);
});
return $formBuilder;
}

private function loopFormField($form, $childrens){
foreach ($childrens as $child) {
$statusInterface = false;
$treeInterface = false;
$type = $child->getConfig()->getType()->getInnerType();;
if ($type instanceof EntityType) {
$passedOptions = $child->getConfig()->getOptions();
$classImplements = class_implements($passedOptions['class']);

$isFilterMerchantInterface = in_array('Lc\ShopBundle\Context\FilterMerchantInterface', $classImplements) ;
$isFilterMultipleMerchantsInterface = in_array('Lc\ShopBundle\Context\FilterMultipleMerchantsInterface', $classImplements) ;

if ($isFilterMerchantInterface || $isFilterMultipleMerchantsInterface) {

if (in_array('Lc\ShopBundle\Context\StatusInterface', $classImplements)) {
$statusInterface = true;
}

if (in_array('Lc\ShopBundle\Context\TreeInterface', $classImplements)) {
$treeInterface = true;
} }
$propertyMerchant = 'merchant';
if($isFilterMultipleMerchantsInterface) {
$propertyMerchant .= 's' ;
}

$form->add($child->getName(), EntityType::class, array(
'class' => $this->em->getClassMetadata($passedOptions['class'])->getName(),
'label' => $passedOptions['label'],
'multiple' => isset($passedOptions['multiple']) ? $passedOptions['multiple'] : false,
'placeholder' => '--',
'translation_domain'=> 'lcshop',
'query_builder' => function (EntityRepository $repo) use ($passedOptions, $propertyMerchant, $statusInterface, $treeInterface, $child) {
$queryBuilder = $repo->createQueryBuilder('e');
$propertyMerchant = 'e.' . $propertyMerchant;

if ($passedOptions['class'] == 'App\Entity\PointSale') {
$queryBuilder->where(':currentMerchant MEMBER OF ' . $propertyMerchant);
} else {
$queryBuilder->where($propertyMerchant . ' = :currentMerchant');
}

if($statusInterface){
$queryBuilder->andWhere('e.status >= 0');
}
if($treeInterface && $child->getName() =='parent'){
$queryBuilder->andWhere('e.parent is null');
}
$queryBuilder->setParameter(':currentMerchant', $this->getUser()->getMerchant()->getId());

return $queryBuilder;
},
'choice_label' => function($choice) {
if($choice instanceof StatusInterface && $choice->getStatus() == 0){
return $choice.' [hors ligne]';
}
return $choice;

},
'required' => $passedOptions['required'],
)
);
}
}else{
$subChildrens = $child->all();
if(count($subChildrens)){
$this->loopFormField($child, $subChildrens);
} }
} }
});

return $formBuilder;
}
} }
} }



+ 1
- 1
ShopBundle/Controller/Admin/OrderController.php View File

parent::persistEntity($entity); parent::persistEntity($entity);
} }


public function createEntityFormBuilder($entity, $view)
public function createEntityFormBuilder($entity, $view, $override=true)
{ {
$formBuilder = parent::createEntityFormBuilder($entity, $view); $formBuilder = parent::createEntityFormBuilder($entity, $view);



+ 56
- 42
ShopBundle/Controller/Admin/ProductFamilyController.php View File

namespace Lc\ShopBundle\Controller\Admin; namespace Lc\ShopBundle\Controller\Admin;


use App\Entity\Product; use App\Entity\Product;
use App\Entity\ReductionCatalog;
use Doctrine\DBAL\Types\FloatType; use Doctrine\DBAL\Types\FloatType;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use EasyCorp\Bundle\EasyAdminBundle\Event\EasyAdminEvents; use EasyCorp\Bundle\EasyAdminBundle\Event\EasyAdminEvents;
use Lc\ShopBundle\Context\ProductCategoryInterface; use Lc\ShopBundle\Context\ProductCategoryInterface;
use Lc\ShopBundle\Context\ProductFamilyInterface; use Lc\ShopBundle\Context\ProductFamilyInterface;
use Lc\ShopBundle\Context\ProductInterface; use Lc\ShopBundle\Context\ProductInterface;
use Lc\ShopBundle\Context\ReductionCartInterface;
use Lc\ShopBundle\Context\ReductionCatalogInterface;
use Lc\ShopBundle\Context\TaxRateInterface; use Lc\ShopBundle\Context\TaxRateInterface;
use Lc\ShopBundle\Context\UnitInterface; use Lc\ShopBundle\Context\UnitInterface;
use Lc\ShopBundle\Form\ProductFamilyCategoriesType; use Lc\ShopBundle\Form\ProductFamilyCategoriesType;
private $choicesTaxRateParam; private $choicesTaxRateParam;
private $choicesSupplierTaxRateParam; private $choicesSupplierTaxRateParam;


public function createEntityFormBuilder($entity, $view)
public function createEntityFormBuilder($entity, $view, $override = true)
{ {
$formBuilder = parent::createEntityFormBuilder($entity, $view);

$formBuilder = parent::createEntityFormBuilder($entity, $view, false);


$class = $this->em->getClassMetadata(ProductCategoryInterface::class); $class = $this->em->getClassMetadata(ProductCategoryInterface::class);
$this->taxRateClass = $this->em->getClassMetadata(TaxRateInterface::class); $this->taxRateClass = $this->em->getClassMetadata(TaxRateInterface::class);


$formBuilder->add('productCategories', ProductFamilyCategoriesType::class); $formBuilder->add('productCategories', ProductFamilyCategoriesType::class);
//$formBuilder->add('reductionCatalog', ReductionCatalogType::class);


/*$formBuilder->add('taxRate', EntityType::class, array(
'class' => $this->em->getClassMetadata(TaxRateInterface::class)->name,
'required' =>false,
'placeholder'=> 'Tva par défaut ('.$this->getUser()->getMerchant()->getTaxRate()->getValue().'%)'
));*/

$reductionCatalogRepo = $this->em->getRepository(ReductionCatalogInterface::class);

$reductionCatalogClass = $this->em->getClassMetadata(ReductionCatalogInterface::class);
$reductionCatalog = $reductionCatalogRepo->findOneBy(array('status'=>false, 'productFamily'=>$entity));

if($reductionCatalog == null)$reductionCatalog = new $reductionCatalogClass->name;
$formBuilder->add('reductionCatalog', ReductionCatalogType::class,array(
'mapped'=>false,
'data'=> $reductionCatalog
));




$formBuilder->add('warningMessageType', ChoiceType::class, array( $formBuilder->add('warningMessageType', ChoiceType::class, array(
)); ));


$formBuilder->add('behaviorAddToCart', ChoiceType::class, array( $formBuilder->add('behaviorAddToCart', ChoiceType::class, array(
'empty_data' => 'by-product-family',
'data' => $entity->getBehaviorAddToCart() ? $entity->getBehaviorAddToCart() : 'simple',
'choices' => array( 'choices' => array(
'field.ProductFamily.behaviorAddToCartOptions.simple' => 'simple', 'field.ProductFamily.behaviorAddToCartOptions.simple' => 'simple',
'field.ProductFamily.behaviorAddToCartOptions.multiple' => 'multiple' 'field.ProductFamily.behaviorAddToCartOptions.multiple' => 'multiple'
), ),
'translation_domain' => 'lcshop', 'translation_domain' => 'lcshop',
'multiple' => false, 'multiple' => false,
'required'=>false,
'expanded' => true 'expanded' => true
)); ));


'expanded' => true 'expanded' => true
)); ));


$formBuilder->add('multiplyingFactor', NumberType::class, array(
'mapped'=> false,
'data'=> floatval($this->merchantUtils->getMerchantConfig('multiplying-factor')),
));

$formBuilder->add('propertyOrganicLabel', ChoiceType::class, array( $formBuilder->add('propertyOrganicLabel', ChoiceType::class, array(
'choices' => array( 'choices' => array(
'field.ProductFamily.organicLabelOptions.ab' => 'ab', 'field.ProductFamily.organicLabelOptions.ab' => 'ab',
) )
); );


$formBuilder = $this->overrideFormBuilder($formBuilder, $entity, $view);

return $formBuilder; return $formBuilder;
} }


public function updateEntity($entity)
public function updateProductFamilyEntity($entity, $editForm)
{ {
$productFamilyRequest = $this->request->request->get('productfamily');

if(isset($productFamilyRequest['taxRate'])) {
$taxRateId = intval($productFamilyRequest['taxRate']);
if ($taxRateId > 0) {
$repo = $this->em->getRepository(TaxRateInterface::class);
$entity->setTaxRate($repo->find($taxRateId));
}
}

$unitId = intval($productFamilyRequest['unit']);
if ($unitId > 0) {
$repo = $this->em->getRepository(UnitInterface::class);
$entity->setUnit($repo->find($unitId));
}

//$reductionCatalogInfo = $productFamilyRequest['reductionCatalog'];



$this->processReductionCatalog($entity, $editForm);
$this->processCategories($entity); $this->processCategories($entity);
$this->processProducts($entity); $this->processProducts($entity);
/* dump($reductionCatalog);
dump($productFamilyRequest);*/
$this->processPrice($entity);


parent::updateEntity($entity); parent::updateEntity($entity);
} }


public function persistEntity($entity)
public function persistProductFamilyEntity($entity, $newForm)
{ {
$this->processReductionCatalog($entity, $newForm);
$this->processCategories($entity); $this->processCategories($entity);
$this->processProducts($entity); $this->processProducts($entity);
$this->processPrice($entity);

$this->em->persist($entity);
$this->em->flush();
}


parent::persistEntity($entity);
protected function processReductionCatalog($entity, $editForm){
$reductionCatalog = $editForm->get('reductionCatalog')->getData();
if($reductionCatalog instanceof ReductionCatalogInterface ) {
if($reductionCatalog->getValue() && $reductionCatalog->getBehaviorTaxRate() && $reductionCatalog->getUnit()){
$reductionCatalog->setMerchant($entity->getMerchant());
$reductionCatalog->setStatus($editForm->get('activeReductionCatalog')->getData());
$reductionCatalog->setProductFamily($entity);
$this->em->persist($reductionCatalog);
}
}
}

protected function processPrice($entity){
if($entity->getBehaviorPrice()=='by-piece'){
$entity->setPriceByRefUnit(null);
$entity->setBuyingPriceByRefUnit(null);
}else if($entity->getBehaviorPrice()=='by-reference-unit') {
$entity->setPrice(null);
$entity->setBuyingPrice(null);
}
} }


protected function processProducts($entity) protected function processProducts($entity)
{ {
$repo = $this->em->getRepository(UnitInterface::class);
//si il existe un et un seul produit pour ce product family n'ajoute rien supprime rien //si il existe un et un seul produit pour ce product family n'ajoute rien supprime rien
if (count($entity->getProducts()) == 0) { if (count($entity->getProducts()) == 0) {
$product = new Product(); $product = new Product();
$product->setProductFamily($entity); $product->setProductFamily($entity);
$this->em->persist($product); $this->em->persist($product);

$entity->addProduct($product); $entity->addProduct($product);
} else { } else {

foreach ($entity->getProducts() as $i=>$product) { foreach ($entity->getProducts() as $i=>$product) {

$product->setProductFamily($entity); $product->setProductFamily($entity);
$this->em->persist($product); $this->em->persist($product);
$entity->addProduct($product); $entity->addProduct($product);

// die('ncici');
} }
} }


$sortableProductsField[$product->getPosition()] = $k; $sortableProductsField[$product->getPosition()] = $k;
} }
ksort($sortableProductsField); ksort($sortableProductsField);

$editForm->handleRequest($this->request); $editForm->handleRequest($this->request);
if ($editForm->isSubmitted() && $editForm->isValid()) { if ($editForm->isSubmitted() && $editForm->isValid()) {



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

+ 4
- 7
ShopBundle/Form/ProductType.php View File



$builder->add('buyingPriceByRefUnit', NumberType::class, array( $builder->add('buyingPriceByRefUnit', NumberType::class, array(
'label' => 'Prix d\'achat', 'label' => 'Prix d\'achat',
'required'=>false,
'mapped' => false
'required'=>false
)); ));


$builder->add('buyingPriceByRefUnitWithTax', NumberType::class, array( $builder->add('buyingPriceByRefUnitWithTax', NumberType::class, array(
)); ));


$builder->add('priceByRefUnit', NumberType::class, array( $builder->add('priceByRefUnit', NumberType::class, array(
'required'=>false,
'mapped' => false
'required'=>false
)); ));


$builder->add('priceByRefUnitWithTax', NumberType::class, array( $builder->add('priceByRefUnitWithTax', NumberType::class, array(
'required' => false, 'required' => false,
)); ));


$builder->add('propertyExpirationDate', DateType::class, array(
'required' => false,
'widget'=> 'single_text'
$builder->add('propertyExpirationDate', TextType::class, array(
'required' => false
)); ));


$builder->add('position', HiddenType::class); $builder->add('position', HiddenType::class);

+ 96
- 12
ShopBundle/Form/ReductionCatalogType.php View File



namespace Lc\ShopBundle\Form; namespace Lc\ShopBundle\Form;


use App\Entity\Supplier;
use Lc\ShopBundle\Context\GroupUserInterface;
use Lc\ShopBundle\Context\ProductCategoryInterface;
use Lc\ShopBundle\Context\ProductFamilyInterface;
use Lc\ShopBundle\Context\ReductionCatalogInterface; use Lc\ShopBundle\Context\ReductionCatalogInterface;
use Lc\ShopBundle\Context\UserInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType; use Symfony\Component\Form\Extension\Core\Type\DateTimeType;


public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {

$userClass = $this->em->getClassMetadata(UserInterface::class);
$groupUserClass = $this->em->getClassMetadata(GroupUserInterface::class);
$supplierClass = Supplier::class;
$productFamilyClass = $this->em->getClassMetadata(ProductFamilyInterface::class);
$productCategoryClass = $this->em->getClassMetadata(ProductCategoryInterface::class);


$builder $builder
->add('title', TextType::class, ['label' => 'Titre'])
->add('title', TextType::class, [
'label' => 'Titre',
'required' => false,
])
->add('behaviorTaxRate', ChoiceType::class, [ ->add('behaviorTaxRate', ChoiceType::class, [
'required'=> true,
'required' => false,
'choices' => [ 'choices' => [
'field.default.taxIncluded'=> 'tax-included',
'field.default.taxExcluded'=> 'tax-excluded'
'field.default.taxIncluded' => 'tax-included',
'field.default.taxExcluded' => 'tax-excluded'
] ]
]) ])
->add('unit', ChoiceType::class, [ ->add('unit', ChoiceType::class, [
'required'=> true,
'required' => false,
'choices' => [ 'choices' => [
'field.default.percent'=> 'percent',
'field.default.amount'=> 'amount'
'field.default.percent' => 'percent',
'field.default.amount' => 'amount'
] ]
]) ])
->add('value', NumberType::class, [
'required' => false
])
->add('permanent', CheckboxType::class, array(
'required'=>false
))
->add('dateStart', DateTimeType::class,
['widget' => 'single_text',
'required'=>false,
])
->add('dateEnd', DateTimeType::class, [
'widget' => 'single_text',
'required'=>false,
])
->add('usersActive', CheckboxType::class, array(
'label' => 'field.ReductionCatalog.usersActive',
'mapped' => false,
'required'=>false,
'attr' => ['class' => 'big']
))
->add('users', EntityType::class, array(
'class' => $userClass->name,
'required'=>false,
'multiple'=>true
))
->add('groupUsersActive', CheckboxType::class, array(
'label' => 'field.ReductionCatalog.groupUsersActive',
'mapped' => false,
'required'=>false,
'attr' => ['class' => 'big']
))
->add('groupUsers', EntityType::class, array(
'class' => $groupUserClass->name,
'required'=>false,
'multiple'=>true

));
/* ->add('productFamiliesActive', CheckboxType::class, array(
'label' => 'field.ReductionCatalog.productFamiliesActive',
'mapped' => false,
'required'=>false,
'attr' => ['class' => 'big']
))
->add('productFamilies', EntityType::class, array(
'class' => $productFamilyClass->name,
'required'=>false,
'multiple'=>true
))
->add('productCategoriesActive', CheckboxType::class, array(
'label' => 'field.ReductionCatalog.productCategoriesActive',
'mapped' => false,
'required'=>false,
'attr' => ['class' => 'big']
))
->add('productCategories', EntityType::class, array(
'class' => $productCategoryClass->name,
'required'=>false,
'multiple'=>true
))
->add('suppliersActive', CheckboxType::class, array(
'label' => 'field.ReductionCatalog.suppliersActive',
'mapped' => false,
'required'=>false,
'attr' => ['class' => 'big']
))
->add('suppliers', EntityType::class, array(
'class' => $supplierClass,
'required'=>false,
'multiple'=>true
));*/


->add('value', NumberType::class, ['required' => true])
->add('permanent', CheckboxType::class, ['required' => true])
->add('dateStart', DateTimeType::class, ['widget' => 'single_text'])
->add('dateEnd', DateTimeType::class, ['widget' => 'single_text']);
} }


public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$resolver->setDefaults([ $resolver->setDefaults([
'label' => false, 'label' => false,
'data_class' => $this->em->getClassMetadata(ReductionCatalogInterface::class)->getName()
//'data_class' => $this->em->getClassMetadata(ReductionCatalogInterface::class)->getName(),
'translation_domain'=> 'lcshop'
]); ]);
} }
} }

+ 1
- 1
ShopBundle/Model/OrderAmountMin.php View File

/** /**
* @ORM\Column(type="float") * @ORM\Column(type="float")
*/ */
private $orderAmountMin;
protected $orderAmountMin;


public function getOrderAmountMin(): ?float public function getOrderAmountMin(): ?float
{ {

+ 21
- 1
ShopBundle/Model/OrderProduct.php View File



namespace Lc\ShopBundle\Model; namespace Lc\ShopBundle\Model;


use App\Entity\OrderProductReductionCatalog;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Lc\ShopBundle\Context\PriceInterface; use Lc\ShopBundle\Context\PriceInterface;


*/ */
protected $title; protected $title;


/**
* @ORM\OneToOne(targetEntity="Lc\ShopBundle\Context\OrderProductReductionCatalogInterface", cascade={"persist", "remove"})
*/
protected $orderProductReductionCatalog;

public function __toString() public function __toString()
{ {
if($this->getTitle()) { if($this->getTitle()) {
{ {
$product = $this->getProduct() ; $product = $this->getProduct() ;
$productFamily = $product->getProductFamily() ; $productFamily = $product->getProductFamily() ;
$titleProduct = $product->getTitleInherited() ;

$titleProduct = $product->getTitle() ;
$titleProductFamily = $productFamily->getTitle() ; $titleProductFamily = $productFamily->getTitle() ;


if(strlen($titleProduct) > 0 && strlen($titleProductFamily) > 0) { if(strlen($titleProduct) > 0 && strlen($titleProductFamily) > 0) {


return $this; return $this;
} }

public function getOrderProductReductionCatalog(): ?OrderProductReductionCatalog
{
return $this->orderProductReductionCatalog;
}

public function setOrderProductReductionCatalog(?OrderProductReductionCatalog $orderProductReductionCatalog): self
{
$this->orderProductReductionCatalog = $orderProductReductionCatalog;

return $this;
}

} }

+ 31
- 0
ShopBundle/Model/OrderProductReductionCatalog.php View File

<?php

namespace Lc\ShopBundle\Model;

use Doctrine\ORM\Mapping as ORM;
use Lc\ShopBundle\Context\OrderProductReductionCatalogInterface;

/**
* @ORM\MappedSuperclass()
*/
abstract class OrderProductReductionCatalog implements OrderProductReductionCatalogInterface
{
use ReductionTrait ;

/**
* @ORM\Column(type="string", length=255)
*/
protected $title;

public function getTitle(): ?string
{
return $this->title;
}

public function setTitle(string $title): self
{
$this->title = $title;

return $this;
}
}

+ 3
- 103
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
{ {
$this->price = $price; $this->price = $price;




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

+ 11
- 39
ShopBundle/Model/ProductFamily.php View File

/** /**
* @ORM\Column(type="string", length=255, nullable=true) * @ORM\Column(type="string", length=255, nullable=true)
*/ */
private $warningMessageType;
protected $warningMessageType;


/** /**
* @ORM\Column(type="text", nullable=true) * @ORM\Column(type="text", nullable=true)
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;

+ 8
- 3
ShopBundle/Model/ProductPropertyTrait.php View File

/** /**
* @ORM\Column(type="float", nullable=true) * @ORM\Column(type="float", nullable=true)
*/ */
protected $quantity = 1; //par défaut valeur à 1
protected $quantity;


/** /**
* @ORM\Column(type="float", nullable=true) * @ORM\Column(type="float", nullable=true)
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;
return $this; return $this;
} }


public function getPropertyExpirationDate(): ?\DateTimeInterface
public function getPropertyExpirationDate(): ?string
{ {
return $this->propertyExpirationDate; return $this->propertyExpirationDate;
} }


public function setPropertyExpirationDate(?\DateTimeInterface $propertyExpirationDate): self
public function setPropertyExpirationDate(?string $propertyExpirationDate): self
{ {
$this->propertyExpirationDate = $propertyExpirationDate; $this->propertyExpirationDate = $propertyExpirationDate;



+ 2
- 1
ShopBundle/Model/ReductionCart.php View File

use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Lc\ShopBundle\Context\ReductionInterface; use Lc\ShopBundle\Context\ReductionInterface;
use Lc\ShopBundle\Model\AbstractDocumentEntity; use Lc\ShopBundle\Model\AbstractDocumentEntity;
use Lc\ShopBundle\Model\ReductionPropertyTrait;
use Lc\ShopBundle\Model\ReductionTrait; use Lc\ShopBundle\Model\ReductionTrait;


/** /**
abstract class ReductionCart extends AbstractDocumentEntity abstract class ReductionCart extends AbstractDocumentEntity
{ {
use ReductionTrait; use ReductionTrait;
use ReductionPropertyTrait ;


/** /**
* @ORM\Column(type="boolean", nullable=true) * @ORM\Column(type="boolean", nullable=true)

+ 18
- 5
ShopBundle/Model/ReductionCatalog.php View File

*/ */
abstract class ReductionCatalog extends AbstractDocumentEntity implements ReductionCatalogInterface, FilterMerchantInterface abstract class ReductionCatalog extends AbstractDocumentEntity implements ReductionCatalogInterface, FilterMerchantInterface
{ {

use ReductionTrait; use ReductionTrait;
use ReductionPropertyTrait ;


/** /**
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies") * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies")
*/ */
protected $productFamilies; protected $productFamilies;


/**
* @ORM\OneToOne(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface")
*/
protected $productFamily;

/** /**
* @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\ProductCategoryInterface") * @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\ProductCategoryInterface")
*/ */
*/ */
protected $users; protected $users;


/*
* @ORM\Column(type="smallint")
*/
// protected $fromQuantity = 1;




public function __construct() public function __construct()
} }




public function getProductFamily(): ?ProductFamily
{
return $this->productFamily;
}

public function setProductFamily(?ProductFamily $productFamily): self
{
$this->productFamily = $productFamily;

return $this;
}

/** /**
* @return Collection|GroupUser[] * @return Collection|GroupUser[]
*/ */

+ 61
- 0
ShopBundle/Model/ReductionPropertyTrait.php View File

<?php

namespace Lc\ShopBundle\Model;

use Doctrine\ORM\Mapping as ORM;

trait ReductionPropertyTrait
{
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $dateStart;

/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $dateEnd;

/**
* @ORM\Column(type="boolean")
*/
protected $permanent;


public function getDateStart(): ?\DateTimeInterface
{
return $this->dateStart;
}

public function setDateStart(?\DateTimeInterface $dateStart): self
{
$this->dateStart = $dateStart;

return $this;
}

public function getDateEnd(): ?\DateTimeInterface
{
return $this->dateEnd;
}

public function setDateEnd(?\DateTimeInterface $dateEnd): self
{
$this->dateEnd = $dateEnd;

return $this;
}

public function getPermanent(): ?bool
{
return $this->permanent;
}

public function setPermanent(bool $permanent): self
{
$this->permanent = $permanent;

return $this;
}

}

+ 0
- 55
ShopBundle/Model/ReductionTrait.php View File



namespace Lc\ShopBundle\Model; namespace Lc\ShopBundle\Model;


use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Lc\ShopBundle\Context\StatusInterface;


trait ReductionTrait trait ReductionTrait
{ {
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $dateStart;

/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $dateEnd;

/** /**
* @ORM\Column(type="float", nullable=true) * @ORM\Column(type="float", nullable=true)
*/ */
*/ */
protected $behaviorTaxRate; protected $behaviorTaxRate;


/**
* @ORM\Column(type="boolean")
*/
protected $permanent;



public function getDateStart(): ?\DateTimeInterface
{
return $this->dateStart;
}

public function setDateStart(?\DateTimeInterface $dateStart): self
{
$this->dateStart = $dateStart;

return $this;
}

public function getDateEnd(): ?\DateTimeInterface
{
return $this->dateEnd;
}

public function setDateEnd(?\DateTimeInterface $dateEnd): self
{
$this->dateEnd = $dateEnd;

return $this;
}


public function getValue(): ?float public function getValue(): ?float
{ {


return $this; return $this;
} }

public function getPermanent(): ?bool
{
return $this->permanent;
}

public function setPermanent(bool $permanent): self
{
$this->permanent = $permanent;

return $this;
}

} }

+ 14
- 0
ShopBundle/Repository/ProductFamilyRepository.php View File

return $query->getQuery()->getResult() ; return $query->getQuery()->getResult() ;
} }


public function findByTerms($terms, $maxResults = false)
{
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.status = 1');
$query->andWhere('e.title LIKE :terms');
$query->setParameter(':terms', '%'.$terms.'%') ;

if($maxResults) {
$query->setMaxResults($maxResults) ;
}

return $query->getQuery()->getResult() ;
}



} }

+ 6
- 1
ShopBundle/Resources/public/css/backend/custom.css View File



/* ProductFamily */ /* ProductFamily */


.field-unit-quantity{border-bottom: 2px dotted #eee; padding-bottom: 10px; margin-bottom: 20px;}

.new-productfamily #nav-params, .new-productfamily #nav-params,
.edit-productfamily #nav-params { .edit-productfamily #nav-params {
margin-bottom: 30px ; margin-bottom: 30px ;
.autoresize textarea{height: auto; min-height: 38px;} .autoresize textarea{height: auto; min-height: 38px;}





/* ORDER */ /* ORDER */


.table-order-summary{width: 100%;} .table-order-summary{width: 100%;}
.product-form-modal{display: none;} .product-form-modal{display: none;}
.product-form.modal .form-check-label{font-style: italic; color: #666; text-align: left;} .product-form.modal .form-check-label{font-style: italic; color: #666; text-align: left;}
.products-collection-table .inherited{color: #888; font-style: italic; font-weight: initial;} .products-collection-table .inherited{color: #888; font-style: italic; font-weight: initial;}
.products-collection-table td{}
.products-collection-table td{position: relative;}
.products-collection-table .btn-empty-field{position: absolute; right: 3px; font-size: 0.7rem; top: 5px; padding: 0px;}
#lc-product-family-edit .products-collection-table {table-layout:fixed;} #lc-product-family-edit .products-collection-table {table-layout:fixed;}
#lc-product-family-edit .products-collection-table tr{border-bottom: 1px solid #dee2e6;} #lc-product-family-edit .products-collection-table tr{border-bottom: 1px solid #dee2e6;}
#lc-product-family-edit .products-collection-table th{font-size:13px; border-left: 1px solid #dee2e6; border-top: 1px solid #dee2e6; text-align: center;} #lc-product-family-edit .products-collection-table th{font-size:13px; border-left: 1px solid #dee2e6; border-top: 1px solid #dee2e6; text-align: center;}
#lc-product-family-edit .products-collection-table td:last-child{border-right: 1px solid #dee2e6;} #lc-product-family-edit .products-collection-table td:last-child{border-right: 1px solid #dee2e6;}
#lc-product-family-edit .btn-add-product {margin: 20px 0; float: right;} #lc-product-family-edit .btn-add-product {margin: 20px 0; float: right;}
#lc-product-family-edit .inherited {color: #888; font-style: italic; font-weight: initial;} #lc-product-family-edit .inherited {color: #888; font-style: italic; font-weight: initial;}
#lc-product-family-edit .products-collection-table td .value {min-width: 80%; margin: auto; min-height: 20px; cursor: pointer;}


/* DeliveryZone */ /* DeliveryZone */



+ 13
- 1
ShopBundle/Resources/public/js/backend/script/default/utils.js View File

* @returns {string} * @returns {string}
*/ */
function getPrice(priceWithTax, taxRate) { function getPrice(priceWithTax, taxRate) {
return parseFloat(parseFloat(priceWithTax) / ((taxRate/100) + 1)).toFixed(3);
return parseFloat(parseFloat(priceWithTax) / ((taxRate/100) + 1)).toFixed(4);
} }


/** /**
return parseFloat(parseFloat(priceWithoutTax) * ((taxRate/100) + 1)).toFixed(2); return parseFloat(parseFloat(priceWithoutTax) * ((taxRate/100) + 1)).toFixed(2);
} }



function formatNumber(number, toFixed){
if(number)return Number(number.replace(',', '.')).toFixed(toFixed);
else return null;
}
function formatNumberWithoutFixed(number){
if(typeof number == 'string')number = number.replace(',', '.');
if(number)return Number(number);
else return null;
}


/** /**
* Formate un prix en l'arrondissant et en ajoutant le sigle de la monnaie * Formate un prix en l'arrondissant et en ajoutant le sigle de la monnaie
* *

+ 150
- 90
ShopBundle/Resources/public/js/backend/script/default/vuejs-mixins.js View File



}, },
computed: { computed: {
taxRateValue: function () {
if (this.taxRate) {
return this.taxRatesList[this.taxRate]['value'];
} else if (this.taxRate == null || this.taxRate == "undefined") {
return this.taxRatesList['default']['value'];
} else {
log('ERREUR : pas de taxRate')
/*priceWithTaxAndReduction:function () {
if(this.productFamily.reductionActive){
log(this.productFamily.value);
} }
},
supplierTaxRateValue: function () {
if (this.supplierTaxRate) {
return this.taxRatesList[this.supplierTaxRate]['value'];
} else if (this.supplierTaxRate == null || this.supplierTaxRate == "undefined") {
return this.taxRateValue;
} else {
log('ERREUR : pas de supplier taxRate')
}
},

}*/
}, },
mounted: function () { mounted: function () {

}, },
methods: { methods: {
init: function () { init: function () {
this.buyingPriceUpdated();
if (this.behaviorPriceValue == 'by-piece') {
this.initByPiece();
} else if (this.behaviorPriceValue == 'by-reference-unit') {
this.initByRefUnit();
}
},
initByPiece: function () {
this.priceUpdated(); this.priceUpdated();
this.unitUpdated();
this.buyingPriceUpdated();
}, },


priceUpdated: function () {
if(this.price) {
this.setPriceWithTax();
this.setMultiplyingFactor();
this.setPriceByRefUnit();
this.setPriceByRefUnitWithTax();
}
initByRefUnit: function () {
this.buyingPriceByRefUnitUpdated();
this.priceByRefUnitUpdated();
}, },




buyingPriceUpdated: function () { buyingPriceUpdated: function () {
if(this.buyingPrice) {
if (this.buyingPrice) {
this.buyingPrice = formatNumber(this.buyingPrice, 4)
this.setBuyingPriceWithTax(); this.setBuyingPriceWithTax();
this.setMultiplyingFactor();
//Mise à jour dans le panel price
if (this.priceValue == null) {
this.setPriceFromMultiplyingFactor();
this.priceUpdated();
} else {
this.setMultiplyingFactor();
}
this.setBuyingPriceByRefUnit(); this.setBuyingPriceByRefUnit();
this.setBuyingPriceByRefUnitWithTax(); this.setBuyingPriceByRefUnitWithTax();
} }
}, },


unitUpdated: function () {
/*if(this.unit) {
buyingPriceByRefUnitUpdated: function () {
if (this.buyingPriceByRefUnit) {
this.buyingPriceByRefUnit = formatNumber(this.buyingPriceByRefUnit, 4)
this.setBuyingPriceByRefUnitWithTax();
if (this.priceByRefUnitValue == null) {
this.setPriceByRefUnitFromMultiplyingFactor();
this.priceByRefUnitUpdated();
} else {
this.setMultiplyingFactor();
}
this.setBuyingPriceFromBuyingPriceByRefUnit();
this.setBuyingPriceWithTax();
}
},


priceUpdated: function () {
if (this.price) {

this.price = formatNumber(this.price, 4)
this.setPriceWithTax();
this.setMultiplyingFactor();
this.setPriceByRefUnit(); this.setPriceByRefUnit();
this.setPriceByRefUnitWithTax(); this.setPriceByRefUnitWithTax();
//this.setBuyingPriceByRefUnit();
//this.setBuyingPriceByRefUnitWithTax();
}*/
}
}, },
quantityUpdated: function () {
/*if(this.quantity ) {
if(this.behaviorPriceValue == 'by-piece'){
this.setPriceByRefUnit();
this.setPriceByRefUnitWithTax();
*/
if(this.behaviorPriceValue == 'by-reference-unit'){
this.setPriceFromPriceByRefUnit();
this.setPriceWithTax();
//this.priceUpdated();
priceByRefUnitUpdated: function () {
if (this.priceByRefUnit) {
this.priceByRefUnit = formatNumber(this.priceByRefUnit, 4)
this.setPriceByRefUnitWithTax();
this.setMultiplyingFactor();
this.setPriceFromPriceByRefUnit();
this.setPriceWithTax();
} }

// this.setBuyingPriceByRefUnit();
// this.setBuyingPriceByRefUnitWithTax();
}, },


//Toutes les fonctions ci-dessous ne font que mettre à jour les price et buyingPrice //Toutes les fonctions ci-dessous ne font que mettre à jour les price et buyingPrice
buyingPriceWithTaxUpdated: function () { buyingPriceWithTaxUpdated: function () {
this.buyingPriceWithTax = formatNumber(this.buyingPriceWithTax, 2)
this.setBuyingPriceFromBuyingPriceWithTax(); this.setBuyingPriceFromBuyingPriceWithTax();
this.buyingPriceUpdated(); this.buyingPriceUpdated();
}, },
buyingPriceByRefUnitUpdated: function () {
this.setBuyingPriceFromBuyingPriceByRefUnit();
this.buyingPriceUpdated();
},
buyingPriceByRefUnitWithTaxUpdated: function () { buyingPriceByRefUnitWithTaxUpdated: function () {
this.buyingPriceByRefUnitWithTax = formatNumber(this.buyingPriceByRefUnitWithTax, 2)

this.setBuyingPriceByRefUnitFromBuyingPriceByRefUnitWithTax(); this.setBuyingPriceByRefUnitFromBuyingPriceByRefUnitWithTax();
this.buyingPriceByRefUnitUpdated(); this.buyingPriceByRefUnitUpdated();
}, },
multiplyingFactorUpdated: function () {
this.setPriceFromMultiplyingFactor();
this.priceUpdated();
},

priceWithTaxUpdated: function () { priceWithTaxUpdated: function () {
this.priceWithTax = formatNumber(this.priceWithTax, 2);
this.setPriceFromPriceWithTax(); this.setPriceFromPriceWithTax();
this.priceUpdated(); this.priceUpdated();
}, },
priceByRefUnitUpdated: function () {
this.setPriceFromPriceByRefUnit();
this.priceUpdated();
},

priceByRefUnitWithTaxUpdated: function () { priceByRefUnitWithTaxUpdated: function () {
this.priceByRefUnitWithTax = formatNumber(this.priceByRefUnitWithTax, 2)
this.setPriceByRefUnitFromTax(); this.setPriceByRefUnitFromTax();
this.priceByRefUnitUpdated(); this.priceByRefUnitUpdated();
}, },




//SETTER
setBuyingPriceFromBuyingPriceByRefUnit:function(){
this.buyingPrice = parseFloat((this.buyingPriceByRefUnit * this.quantityValue) / this.unitCoefficient).toFixed(2);
unitUpdated: function () {
this.quantityUpdated();
}, },
quantityUpdated: function () {
this.quantity = formatNumberWithoutFixed(this.quantity)

if(this.quantity) {
if (this.behaviorPriceValue == 'by-piece') {
this.setBuyingPriceByRefUnit();
this.setBuyingPriceByRefUnitWithTax();
this.setPriceByRefUnit();
this.setPriceByRefUnitWithTax();
} else if (this.behaviorPriceValue == 'by-reference-unit') {
this.setPriceFromPriceByRefUnit();
this.setPriceWithTax();
this.setBuyingPriceFromBuyingPriceByRefUnit();
this.setBuyingPriceWithTax();
}
}
},
multiplyingFactorUpdated: function () {
this.multiplyingFactor = formatNumber(this.multiplyingFactor, 3)

if (this.behaviorPriceValue == 'by-piece') {
this.setPriceFromMultiplyingFactor();
this.setPriceWithTax();
} else if (this.behaviorPriceValue == 'by-reference-unit') {
this.setPriceByRefUnitFromMultiplyingFactor();
this.setPriceByRefUnitWithTax();
}
},
//NEW VERSION

setBuyingPriceFromBuyingPriceWithTax: function () { setBuyingPriceFromBuyingPriceWithTax: function () {
if (this.buyingPriceWithTax) { if (this.buyingPriceWithTax) {
this.buyingPriceWithTax = parseFloat(this.buyingPriceWithTax.replace(',', '.')).toFixed(2);
this.buyingPrice = getPrice(this.buyingPriceWithTax, this.supplierTaxRateValue); this.buyingPrice = getPrice(this.buyingPriceWithTax, this.supplierTaxRateValue);
} }
}, },
setBuyingPriceWithTax: function () { setBuyingPriceWithTax: function () {
if (this.buyingPrice) { if (this.buyingPrice) {
this.buyingPrice = parseFloat(this.buyingPrice.replace(',', '.')).toFixed(3);
this.buyingPriceWithTax = getPriceWithTax(this.buyingPrice, this.supplierTaxRateValue); this.buyingPriceWithTax = getPriceWithTax(this.buyingPrice, this.supplierTaxRateValue);
} }
}, },

setPriceFromMultiplyingFactor: function () {
this.price = getPrice(this.buyingPriceValue * this.multiplyingFactor, this.taxRateValue);
},
setPriceWithTax() {
if (this.price) {
this.priceWithTax = getPriceWithTax(this.price, this.taxRateValue);
}
},

setPriceByRefUnitFromMultiplyingFactor: function () {
this.priceByRefUnit = getPrice(this.buyingPriceByRefUnitValue * this.multiplyingFactorValue, this.taxRateValue);
},

//SETTER
setBuyingPriceFromBuyingPriceByRefUnit: function () {
this.buyingPrice = parseFloat((this.buyingPriceByRefUnit * this.quantityValue) / this.unitCoefficient).toFixed(4);
},

setBuyingPriceByRefUnitFromBuyingPriceByRefUnitWithTax: function () { setBuyingPriceByRefUnitFromBuyingPriceByRefUnitWithTax: function () {
if (this.buyingPriceByRefUnitWithTax) { if (this.buyingPriceByRefUnitWithTax) {
this.buyingPriceByRefUnitWithTax = parseFloat(this.buyingPriceByRefUnitWithTax.replace(',', '.')).toFixed(2);
this.buyingPriceByRefUnit = getPrice(this.buyingPriceByRefUnitWithTax, this.supplierTaxRateValue); this.buyingPriceByRefUnit = getPrice(this.buyingPriceByRefUnitWithTax, this.supplierTaxRateValue);
} }
}, },
setBuyingPriceByRefUnit: function () { setBuyingPriceByRefUnit: function () {
if (this.unitCoefficient && this.quantityValue) { if (this.unitCoefficient && this.quantityValue) {
this.buyingPriceByRefUnit = parseFloat((this.buyingPriceValue / this.quantityValue) * this.unitCoefficient).toFixed(2);
this.buyingPriceByRefUnit = parseFloat((this.buyingPriceValue / this.quantityValue) * this.unitCoefficient).toFixed(4);
} }
}, },
setBuyingPriceByRefUnitWithTax: function () { setBuyingPriceByRefUnitWithTax: function () {
if (this.buyingPriceByRefUnit) { if (this.buyingPriceByRefUnit) {
this.buyingPriceByRefUnit = parseFloat(this.buyingPriceByRefUnit.replace(',', '.')).toFixed(3);
this.buyingPriceByRefUnitWithTax = getPriceWithTax(this.buyingPriceByRefUnit, this.supplierTaxRateValue); this.buyingPriceByRefUnitWithTax = getPriceWithTax(this.buyingPriceByRefUnit, this.supplierTaxRateValue);
} }
}, },
setMultiplyingFactor: function () { setMultiplyingFactor: function () {
if (this.priceWithTax || this.buyingPrice) {
this.multiplyingFactor = parseFloat(this.priceWithTaxValue / this.buyingPriceValue).toFixed(3);
if (this.behaviorPriceValue == 'by-piece') {
if (this.priceWithTax || this.buyingPrice) {
this.multiplyingFactor = parseFloat(this.priceWithTaxValue / this.buyingPriceValue).toFixed(3);
}
} else if (this.behaviorPriceValue == 'by-reference-unit') {
if (this.priceByRefUnitWithTax || this.buyingPriceByRefUnit) {
this.multiplyingFactor = parseFloat(this.priceByRefUnitWithTaxValue / this.buyingPriceByRefUnitValue).toFixed(3);
}
} }
}, },
setPriceByRefUnitFromTax: function () { setPriceByRefUnitFromTax: function () {
if (this.priceByRefUnitWithTax) { if (this.priceByRefUnitWithTax) {
this.priceByRefUnitWithTax = parseFloat(this.priceByRefUnitWithTax.replace(',', '.')).toFixed(2);
this.priceByRefUnit = getPrice(this.priceByRefUnitWithTax, this.taxRateValue); this.priceByRefUnit = getPrice(this.priceByRefUnitWithTax, this.taxRateValue);
} }
}, },
setPriceByRefUnit: function () { setPriceByRefUnit: function () {
if (this.unitCoefficient && this.quantityValue) { if (this.unitCoefficient && this.quantityValue) {
this.priceByRefUnit = parseFloat((this.priceValue / this.quantityValue) * this.unitCoefficient).toFixed(2);
this.priceByRefUnit = parseFloat((this.priceValue / this.quantityValue) * this.unitCoefficient).toFixed(4);
} }
}, },
setPriceByRefUnitWithTax: function () {
if (this.unitCoefficient && this.quantityValue) {
this.priceByRefUnitWithTax = parseFloat((this.priceWithTaxValue / this.quantityValue) * this.unitCoefficient).toFixed(2);
setPriceByRefUnitWithTax() {
if (this.priceByRefUnit) {
this.priceByRefUnitWithTax = getPriceWithTax(this.priceByRefUnit, this.taxRateValue);
} }
}, },

setPriceFromMultiplyingFactor: function () {
this.price = getPrice(this.buyingPriceValue * this.multiplyingFactor, this.taxRateValue);
},
setPriceFromPriceByRefUnit: function () { setPriceFromPriceByRefUnit: function () {
this.price = parseFloat((this.priceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(2);
this.price = parseFloat((this.priceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(4);
}, },
setPriceFromPriceWithTax: function () { setPriceFromPriceWithTax: function () {
if (typeof this.priceWithTax != "number") {
this.priceWithTax = parseFloat(this.priceWithTax.replace(',', '.'));
}
this.priceWithTax = this.priceWithTax.toFixed(2);
this.price = getPrice(this.priceWithTax, this.taxRateValue); this.price = getPrice(this.priceWithTax, this.taxRateValue);
}, },
setPriceWithTax() {
if (this.price) {
this.price = parseFloat(this.price.replace(',', '.')).toFixed(3);
this.priceWithTax = getPriceWithTax(this.price, this.taxRateValue);
}
},
emptyPrice:function () {
this.price=null;
this.priceInherited = true;
}
}, },
watch: {} watch: {}


} }
} }
} }
}
};


let mixinReduction = {
data() {
return Object.assign({
reductionActive: true,
reductionUnit:null,
reductionBehaviorTaxRate:null,
reductionValue:null,
reductionPermanent: true,
reductionUsersActive: false,
reductionGroupUsersActive: false,
reductionSuppliersActive: false,
reductionProductCategoriesActive: false,
reductionProductFamiliesActive:false
}, window.mixinReductionValues);
}
};

+ 140
- 63
ShopBundle/Resources/public/js/backend/script/productfamily/vuejs-product-family.js View File

props: ['template', 'keyForm'], props: ['template', 'keyForm'],
data() { data() {
return Object.assign({ return Object.assign({
behaviorPrice:null,
behaviorPrice: 'by-piece',
activeProducts: false, activeProducts: false,
}, window.productUnitPriceValues); }, window.productUnitPriceValues);


buyingPriceWithTaxValue: function () { buyingPriceWithTaxValue: function () {
return this.buyingPriceWithTax; return this.buyingPriceWithTax;
}, },
buyingPriceByRefUnitValue:function(){
return this.buyingPriceByRefUnit;
},
buyingPriceByRefUnitWithTaxValue:function(){
return this.buyingPriceByRefUnitWithTax;
},
multiplyingFactorValue:function(){
return this.multiplyingFactor;
},
priceWithTaxValue: function () { priceWithTaxValue: function () {
return this.priceWithTax; return this.priceWithTax;
}, },
priceValue: function () { priceValue: function () {
return this.price; return this.price;
}, },
priceByRefUnitValue:function(){
return this.priceByRefUnit;
},
priceByRefUnitWithTaxValue:function(){
return this.priceByRefUnitWithTax;
},
quantityValue: function () { quantityValue: function () {
return this.quantity; return this.quantity;
}, },
}, },
behaviorPriceValue:function(){ behaviorPriceValue:function(){
return this.behaviorPrice; return this.behaviorPrice;
}
},
taxRateValue: function () {
if (this.taxRate) {
return this.taxRatesList[this.taxRate]['value'];
} else if (this.taxRate == null || this.taxRate == "undefined") {
return this.taxRatesList['default']['value'];
} else {
log('ERREUR : pas de taxRate')
}
},
supplierTaxRateValue: function () {
if (this.supplierTaxRate) {
return this.taxRatesList[this.supplierTaxRate]['value'];
} else if (this.supplierTaxRate == null || this.supplierTaxRate == "undefined") {
return this.taxRateValue;
} else {
log('ERREUR : pas de supplier taxRate')
}
},


}, },
mounted: function () { mounted: function () {
watch: { watch: {
taxRate: function () { taxRate: function () {
this.setBuyingPriceWithTax(); this.setBuyingPriceWithTax();
this.setBuyingPriceByRefUnitWithTax();
this.setPriceWithTax(); this.setPriceWithTax();
this.setPriceByRefUnitWithTax();
this.setMultiplyingFactor(); this.setMultiplyingFactor();
this.setPriceByUnitRefWithTax();
this.$parent.updateChild();
}, },
supplierTaxRate: function () { supplierTaxRate: function () {
this.setBuyingPriceWithTax(); this.setBuyingPriceWithTax();
this.setBuyingPriceByRefUnitWithTax();
},
differentSupplierTaxRate:function(){
this.supplierTaxRate = null;
},
activeProducts:function () {
this.$parent.updateActiveProducts();
},
behaviorPrice:function () {
if(this.behaviorPrice == 'by-reference-unit'){
this.quantity = 1;
}
} }
} }
}); });
mixins: [mixinUnit, mixinPrice, mixinTemplate], mixins: [mixinUnit, mixinPrice, mixinTemplate],
props: ['template', 'keyForm', 'productFamily'], props: ['template', 'keyForm', 'productFamily'],
computed: { computed: {
taxRate: function () {
return this.productFamily.taxRate;
taxRateValue: function () {
return this.productFamily.taxRateValue;
}, },
supplierTaxRate: function () {
return this.productFamily.supplierTaxRate;
supplierTaxRateValue: function () {
return this.productFamily.supplierTaxRateValue;
}, },
buyingPriceValue: function () { buyingPriceValue: function () {
if (this.buyingPrice) return this.buyingPrice; if (this.buyingPrice) return this.buyingPrice;
if (this.buyingPriceWithTax) return this.buyingPriceWithTax; if (this.buyingPriceWithTax) return this.buyingPriceWithTax;
else return this.productFamily.buyingPriceWithTax; else return this.productFamily.buyingPriceWithTax;
}, },
buyingPriceByRefUnitValue:function(){
if (this.buyingPriceByRefUnit) return this.buyingPriceByRefUnit;
else return this.productFamily.buyingPriceByRefUnit;
},
buyingPriceByRefUnitWithTaxValue:function(){
if (this.buyingPriceByRefUnitWithTax) return this.buyingPriceByRefUnitWithTax;
else return this.productFamily.buyingPriceByRefUnitWithTax;
},
multiplyingFactorValue:function(){
if (this.multiplyingFactor) return this.multiplyingFactor;
else return this.productFamily.multiplyingFactor;
},
priceWithTaxValue: function () { priceWithTaxValue: function () {
if (this.priceWithTax) return this.priceWithTax; if (this.priceWithTax) return this.priceWithTax;
else return this.productFamily.priceWithTax; else return this.productFamily.priceWithTax;
if (this.unit) return this.unit; if (this.unit) return this.unit;
else return this.productFamily.unit; else return this.productFamily.unit;
}, },
propertyExpirationDateFormated: function () {
if (this.propertyExpirationDate) return getDateFormatted(this.propertyExpirationDate, '-')
else return getDateFormatted(this.productFamily.propertyExpirationDate, '-')
propertyExpirationDateValue: function () {
if (this.propertyExpirationDate) return this.propertyExpirationDate;
else return this.productFamily.propertyExpirationDate;
}, },
behaviorPriceValue:function(){ behaviorPriceValue:function(){
return this.productFamily.behaviorPrice; return this.productFamily.behaviorPrice;
},
finalPriceWithTax:function () {
return getPriceWithTax(parseFloat((this.priceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(4), this.taxRateValue);
} }
}, },
data() { data() {
availableQuantityDefault: null, availableQuantityDefault: null,
availableQuantity: null, availableQuantity: null,
propertyExpirationDate: null, propertyExpirationDate: null,

titleInherited: false, titleInherited: false,
priceInherited: false, priceInherited: false,
priceWithTaxInherited: false, priceWithTaxInherited: false,
mounted: function () { mounted: function () {
//INIT VAR //INIT VAR
updateSortableProducts(); updateSortableProducts();
this.setUnitSelect2();
//this.setUnitSelect2();




//METHOD //METHOD
this.updateProductForm();
this.updateProductView();
//this.updateProductForm();
//this.updateProductView();
}, },
methods: { methods: {
setUnitSelect2:function(){ setUnitSelect2:function(){
availableQuantityUpdated:function(){}, availableQuantityUpdated:function(){},
availableQuantityDefaultUpdated:function(){}, availableQuantityDefaultUpdated:function(){},
propertyExpirationDateUpdated:function(){}, propertyExpirationDateUpdated:function(){},
updateLine: function(){
this.init();
},

updateProductForm: function () { updateProductForm: function () {
this.init(); this.init();
}, },

updateProductView: function () {


/*if (this.unitValue == 'piece') {
$('.priceByRefUnit').hide();
} else {
$('.priceByRefUnit').show();
}
if (this.productFamily.behaviorCountStock == 'by-product-family' || this.productFamily.behaviorCountStock == 'by-quantity') {
$('.products-collection-table').find('.stock').hide();
} else {
$('.products-collection-table').find('.stock').show();
$('#product-item-' + this.keyForm).find('.stock').html(this.availableQuantity + ' / ' + this.unitReference);
}*/
},
saveProductForm: function () { saveProductForm: function () {
this.updateProductView();
$('#form-product-modal-' + this.keyForm).modal('hide'); $('#form-product-modal-' + this.keyForm).modal('hide');
}, },
deleteProductForm: function () { deleteProductForm: function () {


appProductFamily = new Vue({ appProductFamily = new Vue({
el: '#lc-product-family-edit', el: '#lc-product-family-edit',
mixins: [mixinReduction],
delimiters: ['${', '}'], delimiters: ['${', '}'],
computed: { computed: {
productFamily: function () { productFamily: function () {
return {
'title': this.title,
'behaviorCountStock': this.behaviorCountStock,
'behaviorPrice': this.$refs.productUnitPrice.behaviorPrice,
'unit': this.$refs.productUnitPrice.unit,
'unitWording': this.$refs.productUnitPrice.unitWording,
'quantity': this.$refs.productUnitPrice.quantity,
'price': this.$refs.productUnitPrice.price,
'priceWithTax': this.$refs.productUnitPrice.priceWithTax,
'buyingPrice': this.$refs.productUnitPrice.buyingPrice,
'buyingPriceWithTax': this.$refs.productUnitPrice.buyingPriceWithTax,
'buyingPriceByRefUnit': this.$refs.productUnitPrice.buyingPriceByRefUnit,
'buyingPriceByRefUnitWithTax': this.$refs.productUnitPrice.buyingPriceByRefUnitWithTax,
'priceByRefUnit': this.$refs.productUnitPrice.priceByRefUnit,
'priceByRefUnitWithTax': this.$refs.productUnitPrice.priceByRefUnitWithTax,
'taxRate': this.$refs.productUnitPrice.taxRate,
'supplierTaxRate': this.$refs.productUnitPrice.supplierTaxRate,
'multiplyingFactor': this.$refs.productUnitPrice.multiplyingFactor,
'taxRateValue': this.$refs.productUnitPrice.taxRateValue,
'propertyExpirationDate': this.propertyExpirationDate,
'behaviorExpirationDate': this.behaviorExpirationDate
};
if(this.isMounted) {
return {
'title': this.title,
'behaviorCountStock': this.behaviorCountStock,
'behaviorPrice': this.$refs.productUnitPrice.behaviorPrice,
'unit': this.$refs.productUnitPrice.unit, //this.getProductUnitPrice('unit'),
'unitWording': this.$refs.productUnitPrice.unitWording,
'quantity': this.$refs.productUnitPrice.quantity,
'price': this.$refs.productUnitPrice.price,
'priceWithTax': this.$refs.productUnitPrice.priceWithTax,
'buyingPrice': this.$refs.productUnitPrice.buyingPrice,
'buyingPriceWithTax': this.$refs.productUnitPrice.buyingPriceWithTax,
'buyingPriceByRefUnit': this.$refs.productUnitPrice.buyingPriceByRefUnit,
'buyingPriceByRefUnitWithTax': this.$refs.productUnitPrice.buyingPriceByRefUnitWithTax,
'priceByRefUnit': this.$refs.productUnitPrice.priceByRefUnit,
'priceByRefUnitWithTax': this.$refs.productUnitPrice.priceByRefUnitWithTax,
'taxRateValue': this.$refs.productUnitPrice.taxRateValue,
'supplierTaxRateValue': this.$refs.productUnitPrice.supplierTaxRateValue,

/*'taxRate': this.$refs.productUnitPrice.taxRate,
'supplierTaxRate': this.$refs.productUnitPrice.supplierTaxRate,
*/
'multiplyingFactor': this.$refs.productUnitPrice.multiplyingFactor,
'propertyExpirationDate': this.propertyExpirationDate,
'behaviorExpirationDate': this.behaviorExpirationDate,
'reductionActive': this.reductionActive,
'reductionUnit': this.reductionUnit,
'reductionValue': this.reductionValue,
'reductionBehaviorTaxRate': this.reductionBehaviorTaxRate
};
}else{
return {
'title': null,
'behaviorCountStock': null,
'behaviorPrice': null,
'unit': null,
'unitWording': null,
'quantity': null,
'price': null,
'priceWithTax':null,
'buyingPrice': null,
'buyingPriceWithTax': null,
'buyingPriceByRefUnit': null,
'buyingPriceByRefUnitWithTax': null,
'priceByRefUnit': null,
'priceByRefUnitWithTax': null,
'taxRate': null,
'supplierTaxRate': null,
'multiplyingFactor': null,
'taxRateValue': null,
'propertyExpirationDate': this.propertyExpirationDate,
'behaviorExpirationDate': this.behaviorExpirationDate
};
}
}, },
unitReference: function () { unitReference: function () {
this.getUnitReference(); this.getUnitReference();


return Object.assign( return Object.assign(
{ {
isMounted:false,
indexFormProduct: 0, indexFormProduct: 0,
title: null, title: null,
isNovelty: null, isNovelty: null,
propertyAllergens: null, propertyAllergens: null,
propertyOrganicLabelActive: false, propertyOrganicLabelActive: false,
propertyNoveltyExpirationDateActive: false, propertyNoveltyExpirationDateActive: false,
activeProducts:false,


formProductArray: [], formProductArray: [],
currentSection: 'general', currentSection: 'general',
name: 'property', name: 'property',
nameDisplay: 'Caractéristiques' nameDisplay: 'Caractéristiques'
}, },

{
name: 'reduction',
nameDisplay: 'Réduction'
},
{ {
name: 'note', name: 'note',
nameDisplay: 'Note interne' nameDisplay: 'Note interne'
}, window.appProductFamilyValues); }, window.appProductFamilyValues);
}, },
mounted: function () { mounted: function () {
this.isMounted = true;
$(".vuejs-checkbox-switch input").each(function () { $(".vuejs-checkbox-switch input").each(function () {
setBootstrapSwitch($(this)); setBootstrapSwitch($(this));
}); });
}, },
methods: { methods: {

changeSection: function (section) { changeSection: function (section) {
this.updateChild(); this.updateChild();
this.currentSection = section.name; this.currentSection = section.name;
if (typeof this.$refs.productForm !== 'undefined') { if (typeof this.$refs.productForm !== 'undefined') {
for (i = 0; i < this.$refs.productForm.length; i++) { for (i = 0; i < this.$refs.productForm.length; i++) {
this.$refs.productForm[i].updateProductForm(); this.$refs.productForm[i].updateProductForm();
this.$refs.productForm[i].updateProductView();
} }
} }
}, },
return this.$refs.productUnitPrice.unitReference; return this.$refs.productUnitPrice.unitReference;
} }
}, },
isProductsActice: function () {
if (typeof this.$refs.productUnitPrice !== 'undefined') {
return this.$refs.productUnitPrice.activeProducts;
}
updateActiveProducts: function () {
this.activeProducts = this.$refs.productUnitPrice.activeProducts;
}, },
getBehaviorPrice: function () { getBehaviorPrice: function () {
if (typeof this.$refs.productUnitPrice !== 'undefined') { if (typeof this.$refs.productUnitPrice !== 'undefined') {

+ 1
- 24
ShopBundle/Resources/public/js/backend/script/reductioncatalog/vuejs-reduction-catalog.js View File

appProductFamily = new Vue({ appProductFamily = new Vue({
el: '#lc-reduction-catalog-edit', el: '#lc-reduction-catalog-edit',
delimiters: ['${', '}'], delimiters: ['${', '}'],
computed: {
},
data() {

return Object.assign(
{
permanent: true,
usersActive: false,
groupUsersActive: false,
suppliersActive: false,
productCategoriesActive: false,
productFamiliesActive:false

}, window.appReductionCatalogValues);
},
mounted: function () {

},
methods: {

},
watch: {

}
mixins: [mixinReduction]
}); });

+ 10
- 3
ShopBundle/Resources/translations/lcshop.fr.yaml View File

addresses: Livraisons & facturation addresses: Livraisons & facturation
main: Général main: Général
products: Déclinaisons products: Déclinaisons
price: Prix
priceAndUnit: Tarifs / Unités / Quantités
categories: Catégories categories: Catégories
unit: Unité & quantité unit: Unité & quantité
tax: TVA tax: TVA
propertySecondary: Caractéristiques secondaires propertySecondary: Caractéristiques secondaires
note: Note interne note: Note interne
parameters: Paramètres parameters: Paramètres
initReduction: Réduction
ReductionCatalog: ReductionCatalog:
info: Informations principal info: Informations principal
conditions: Condictions d'application conditions: Condictions d'application
subscribeNewsletter: S'inscrire à la newsletter subscribeNewsletter: S'inscrire à la newsletter
send: Envoyer send: Envoyer
isSent: Envoyée isSent: Envoyée
behaviorTaxRate: Avec ou sans TVA
behaviorTaxRateHelp: Appliquer la réduction sur le prix HT ou le prix TTC
PointSale: PointSale:
code: Code code: Code
codeHelp: Code utilisé pour retrouver l'ambassade dans le tunnel de commande (Non sensible à la casse) codeHelp: Code utilisé pour retrouver l'ambassade dans le tunnel de commande (Non sensible à la casse)
productsTypeHelp: 'Volume / Pods / Varieté / Parfum ...' productsTypeHelp: 'Volume / Pods / Varieté / Parfum ...'
buyingPrice: Prix d'achat buyingPrice: Prix d'achat
multiplyingFactor: Coefficiant multiplicateur multiplyingFactor: Coefficiant multiplicateur
multiplyingFactorHelp: La mise à jour de ce champ modifiera le prix de vente HT et TTC
priceByRefUnit: Prix de vente / unité de référence priceByRefUnit: Prix de vente / unité de référence
buyingPriceByRefUnit: Prix d'achat / unité de référence
availableQuantity: Quantité disponible availableQuantity: Quantité disponible
availableQuantityDefault: Quantité disponible par défaut availableQuantityDefault: Quantité disponible par défaut
quantity: Quantité quantity: Quantité
behaviorAddToCartOptions: behaviorAddToCartOptions:
simple: Simple simple: Simple
multiple: Multiple multiple: Multiple
activeReductionCatalog: Appliquer une réduction sur ce produit
ReductionCatalog: ReductionCatalog:
fromQuantity: À partir de la quantité fromQuantity: À partir de la quantité
fromQuantityHelp: Par défaut une réduction est apliqué à partir de 1 fromQuantityHelp: Par défaut une réduction est apliqué à partir de 1
behaviorTaxRate: Avec ou sans TVA
behaviorTaxRateHelp: Appliquer la réduction sur le prix HT ou le prix TTC
unit: Unité unit: Unité
value: Montant ou valeur value: Montant ou valeur
permanent: Réduction permanante permanent: Réduction permanante
productFamiliesActive: Filtrer sur les produits productFamiliesActive: Filtrer sur les produits
productFamilies: Appliquer aux produits productFamilies: Appliquer aux produits


Address:
city: Commune

action: action:
new: Créer %entity_label% new: Créer %entity_label%
switchMerchant: Votre hub switchMerchant: Votre hub

+ 128
- 3
ShopBundle/Resources/views/backend/default/block/macros.html.twig View File



{% if fieldDisplay == false %}{% set fieldDisplay = fieldName %}{% endif %} {% if fieldDisplay == false %}{% set fieldDisplay = fieldName %}{% endif %}


<td {{ attr|raw }} colspan="{{ colspan }}" class="{{ fieldName }}" v-on:click="{{ fieldName }}Inherited = true">
<div v-show="{{ fieldName }}Inherited == false">
<td {{ attr|raw }} colspan="{{ colspan }}" class="{{ fieldName }}">
<div class="value" v-show="{{ fieldName }}Inherited == false" v-on:click="{{ fieldName }}Inherited = true">
<div v-if="{{ fieldName }}"> <div v-if="{{ fieldName }}">
{% verbatim %}{{ {% endverbatim %}{{ fieldDisplay }} {% verbatim %}}}{% endverbatim %}{{ displaySuffix }} {% verbatim %}{{ {% endverbatim %}{{ fieldDisplay }} {% verbatim %}}}{% endverbatim %}{{ displaySuffix }}
</div> </div>
<div v-show="{{ fieldName }}Inherited == true"> <div v-show="{{ fieldName }}Inherited == true">
{{ form_widget(field, {'attr' : {'v-model' : fieldName , 'v-on:focusout': fieldName~'Inherited = false', '@change' : fieldName~'Updated'}}) }} {{ form_widget(field, {'attr' : {'v-model' : fieldName , 'v-on:focusout': fieldName~'Inherited = false', '@change' : fieldName~'Updated'}}) }}
</div> </div>
<button v-show="{{ fieldName }}" v-on:click="{{ fieldName }} = null; {{ fieldName }}Inherited = false; "
class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button>
</td> </td>
{% endmacro %} {% endmacro %}


</div> </div>
</div> </div>


{% endmacro %}
{% endmacro %}

{% macro reductionCatalogForm(form) %}
{{ _self.startCard(6, 'ReductionCatalog.info') }}
<div class="col-12">
{{ form_row(form.title) }}
</div>
{# <div class="col-12">
{{ form_row(form.fromQuantity) }}
</div>
#}
<div class="col-12">
{{ form_row(form.behaviorTaxRate, {"attr" : {":required": "reductionActive", 'v-model' : 'reductionBehaviorTaxRate'}}) }}
</div>

<div class="col-12">
{{ form_row(form.unit, {"attr" : {":required": "reductionActive", 'v-model' : 'reductionUnit'}}) }}
</div>
<div class="col-12">
{{ form_row(form.value, {"attr" : {":required": "reductionActive", 'v-model' : 'reductionValue'}}) }}
</div>



{{ _self.endCard() }}


{{ _self.startCard(6, 'ReductionCatalog.conditions','success') }}
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.permanent, {"attr" : {'v-model' : 'reductionPermanent' } }) }}
</div>
<div class="input-group" v-show="reductionPermanent == false">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-clock"></i></span>
</div>
<input type="text" class="form-control float-right date-time-range">
<div class="hidden date-time-range-fields" style="display: none;">
{{ form_widget(form.dateStart, {"attr" : {'class' : 'date-start'}}) }}
{{ form_widget(form.dateEnd, {"attr" : {'class' : 'date-end'}}) }}
</div>
</div>

</div>
</div>
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.usersActive, {"attr" : {'v-model' : 'reductionUsersActive' } }) }}
</div>
<div class="form-widget" v-show="reductionUsersActive == true">
{{ form_widget(form.users) }}
</div>
</div>
</div>
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.groupUsersActive, {"attr" : {'v-model' : 'reductionGroupUsersActive' } }) }}
</div>
<div class="form-widget" v-show="reductionGroupUsersActive == true">
{{ form_widget(form.groupUsers) }}
</div>
</div>

</div>
{% if form.suppliers is defined %}
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.suppliersActive, {"attr" : {'v-model' : 'reductionSuppliersActive' } }) }}
</div>
<div class="form-widget" v-show="reductionSuppliersActive == true">
{{ form_widget(form.suppliers) }}
</div>
</div>
</div>
{% endif %}
{% if form.productCategories is defined %}
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.productCategoriesActive, {"attr" : {'v-model' : 'reductionProductCategoriesActive' } }) }}
</div>
<div class="form-widget" v-show="reductionProductCategoriesActive == true">
{{ form_widget(form.productCategories) }}
</div>
</div>
</div>
{% endif %}
{% if form.productFamilies is defined %}
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.productFamiliesActive, {"attr" : {'v-model' : 'reductionProductFamiliesActive' } }) }}
</div>
<div class="form-widget" v-show="reductionProductFamiliesActive == true">
{{ form_widget(form.productFamilies) }}
</div>
</div>
</div>
{% endif %}

{{ _self.endCard() }}

{% endmacro %}

{% macro reductionCatalogFormValues(formValues, isProductFamilyForm= false) %}
<script>
window.mixinReductionValues = {
{% if formValues.status == false and isProductFamilyForm %}reductionActive: false,{% endif %}
{% if formValues.permanent is not null and formValues.permanent == false %}reductionPermanent: false,{% endif %}
{% if formValues.behaviorTaxRate %}reductionBehaviorTaxRate: '{{ formValues.behaviorTaxRate }}',{% endif %}
{% if formValues.value %}reductionValue: parseFloat({{ formValues.value }}),{% endif %}
{% if formValues.unit %}reductionUnit: "{{ formValues.unit }}",{% endif %}
{% if formValues.users is not empty %}reductionUsersActive: true,{% endif %}
{% if formValues.groupUsers is not empty %}reductionGroupUsersActive: true,{% endif %}
{% if formValues.productFamilies is not empty %}reductionProductFamiliesActive: true,{% endif %}
{% if formValues.productCategories is not empty %}reductionProductCategoriesActive: true,{% endif %}
{% if formValues.suppliers is not empty %}reductionSuppliersActive: true,{% endif %}
}
</script>
{% endmacro %}

+ 1
- 0
ShopBundle/Resources/views/backend/default/list-fields/field_price.html.twig View File

{{ priceUtils.getPriceWithTax(item) }}

+ 13
- 0
ShopBundle/Resources/views/backend/productfamily/edit.html.twig View File

{% include '@LcShop/backend/productfamily/form.html.twig' %} {% include '@LcShop/backend/productfamily/form.html.twig' %}
{% endblock entity_form %} {% endblock entity_form %}



{% block head_stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/daterange/daterangepicker.css') }}">
{% endblock %}

{% block plugin_javascript %}
{{ parent() }}

<script src="{{ asset('bundles/lcshop/js/backend/plugin/daterange/moment.min.js')}}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/daterange/daterangepicker.js')}}"></script>
{% endblock %}

{% block script_javascript %} {% block script_javascript %}
{{ parent() }} {{ parent() }}
{% include '@LcShop/backend/default/block/script-vuejs.html.twig' %} {% include '@LcShop/backend/default/block/script-vuejs.html.twig' %}

+ 12
- 2
ShopBundle/Resources/views/backend/productfamily/form.html.twig View File

<ul class="nav nav-tabs" id="nav-params"> <ul class="nav nav-tabs" id="nav-params">
<li class="nav-item" v-for="section in sectionsArray"> <li class="nav-item" v-for="section in sectionsArray">
<button type="button" <button type="button"
v-if="(section.name == 'products' && isProductsActice() == true) || (section.name != 'products')"
v-if="(section.name == 'products' && activeProducts == true) || (section.name != 'products')"
:class="'btn '+((currentSection == section.name) ? 'btn btn-primary' : 'btn ')" :class="'btn '+((currentSection == section.name) ? 'btn btn-primary' : 'btn ')"
@click="changeSection(section)"> @click="changeSection(section)">
${ section.nameDisplay } ${ section.nameDisplay }
{% if formValues.propertyNoveltyExpirationDate %}propertyNoveltyExpirationDateActive: true,{% endif %} {% if formValues.propertyNoveltyExpirationDate %}propertyNoveltyExpirationDateActive: true,{% endif %}
{% if formValues.typeExpirationDate %}typeExpirationDate: "{{ formValues.typeExpirationDate }}",{% endif %} {% if formValues.typeExpirationDate %}typeExpirationDate: "{{ formValues.typeExpirationDate }}",{% endif %}
{% if formValues.behaviorExpirationDate %}behaviorExpirationDate: "{{ formValues.behaviorExpirationDate }}",{% endif %} {% if formValues.behaviorExpirationDate %}behaviorExpirationDate: "{{ formValues.behaviorExpirationDate }}",{% endif %}
{% if formValues.propertyExpirationDate %}propertyExpirationDate: "{{ formValues.propertyExpirationDate|date('d/m/Y') }}",{% endif %}
{% if formValues.propertyExpirationDate %}propertyExpirationDate: "{{ formValues.propertyExpirationDate }}",{% endif %}
{% if formValues.activeProducts %}activeProducts: "{{ formValues.activeProducts }}",{% endif %}

}; };
multiplyingFactor = "{{ form.multiplyingFactor.vars.value }}"
window.productUnitPriceValues = { window.productUnitPriceValues = {
{% if formValues.activeProducts %}activeProducts: "{{ formValues.activeProducts }}",{% endif %} {% if formValues.activeProducts %}activeProducts: "{{ formValues.activeProducts }}",{% endif %}
{% if formValues.behaviorPrice %}behaviorPrice: "{{ formValues.behaviorPrice }}",{% endif %} {% if formValues.behaviorPrice %}behaviorPrice: "{{ formValues.behaviorPrice }}",{% endif %}
{% if form.multiplyingFactor.vars.value %}multiplyingFactor: parseFloat(multiplyingFactor.replace(',', '.')),{% endif %}
{% if formValues.unit %}unit: parseInt({{ formValues.unit.id }}),{% endif %} {% if formValues.unit %}unit: parseInt({{ formValues.unit.id }}),{% endif %}
{% if formValues.quantity %}quantity: parseFloat({{ formValues.quantity }}),{% endif %} {% if formValues.quantity %}quantity: parseFloat({{ formValues.quantity }}),{% endif %}
{% if formValues.taxRate %}taxRate: parseInt({{ formValues.taxRate.id }}),{% endif %} {% if formValues.taxRate %}taxRate: parseInt({{ formValues.taxRate.id }}),{% endif %}
{% if formValues.price %}price: parseFloat({{ formValues.price }}).toFixed(3),{% endif %} {% if formValues.price %}price: parseFloat({{ formValues.price }}).toFixed(3),{% endif %}
{% if formValues.priceByRefUnit %}priceByRefUnit: parseFloat({{ formValues.priceByRefUnit }}).toFixed(3),{% endif %}
{% if formValues.buyingPrice %}buyingPrice: parseFloat({{ formValues.buyingPrice }}).toFixed(3),{% endif %} {% if formValues.buyingPrice %}buyingPrice: parseFloat({{ formValues.buyingPrice }}).toFixed(3),{% endif %}
{% if formValues.buyingPriceByRefUnit %}buyingPriceByRefUnit: parseFloat({{ formValues.buyingPriceByRefUnit }}).toFixed(3),{% endif %}
{% if formValues.supplierTaxRate %}supplierTaxRate: parseInt({{ formValues.supplierTaxRate.id }}),{% endif %} {% if formValues.supplierTaxRate %}supplierTaxRate: parseInt({{ formValues.supplierTaxRate.id }}),{% endif %}
{% if form.supplierTaxRate.vars.value != 0 %}differentSupplierTaxRate: true{% endif %} {% if form.supplierTaxRate.vars.value != 0 %}differentSupplierTaxRate: true{% endif %}
} }
{% include '@LcShop/backend/productfamily/panel_property.html.twig' %} {% include '@LcShop/backend/productfamily/panel_property.html.twig' %}
</div> </div>


<div v-show="currentSection == 'reduction'" class="panel panel-default">
{% include '@LcShop/backend/productfamily/panel_reduction.html.twig' %}
</div>



<div v-show="currentSection == 'note'" class="panel panel-default"> <div v-show="currentSection == 'note'" class="panel panel-default">
<div class="row"> <div class="row">

+ 25
- 24
ShopBundle/Resources/views/backend/productfamily/panel_price.html.twig View File

{{ form_row(form.behaviorAddToCart) }} {{ form_row(form.behaviorAddToCart) }}
</div> </div>


<div class="col-12 form-group">
<div class="col-12 form-group" v-show="activeProducts == true">
{{ form_label(form.behaviorPrice) }} {{ form_label(form.behaviorPrice) }}
{% for field in form.behaviorPrice %} {% for field in form.behaviorPrice %}
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorPrice'}}) }} {{ form_widget(field, {"attr" : {"v-model" : 'behaviorPrice'}}) }}
</div> </div>
{{ macros.endCard(true) }} {{ macros.endCard(true) }}


{{ macros.startCard(0, 'ProductFamily.unit','light') }}
<div class="col-12">
{{ form_row(form.unit, {"attr":{'v-model': 'unit', '@change': "unitUpdated"}}) }}
</div>

<div class="col-12">
<div class="form-group field-weight">
{{ form_label(form.quantity) }}
<div class="form-widget">
<div class="input-group">
{{ form_widget(form.quantity, {'attr' : {'v-model': 'quantity', '@change': "quantityUpdated"}}) }}
<div class="input-group-append">
<span class="input-group-text">${ unitWording }</span>
</div>
</div>
{{ form_help(form.quantity) }}
</div>
</div>
</div>

{{ macros.endCard(true) }}

{{ macros.startCard(0, 'ProductFamily.tax','light') }} {{ macros.startCard(0, 'ProductFamily.tax','light') }}
<div class="col-12"> <div class="col-12">
{{ form_row(form.taxRate, {'attr': {'v-model':'taxRate'}}) }} {{ form_row(form.taxRate, {'attr': {'v-model':'taxRate'}}) }}


{{ macros.endCard() }} {{ macros.endCard() }}


{{ macros.startCard(8, 'ProductFamily.price','light') }}
{{ macros.startCard(8, 'ProductFamily.priceAndUnit','light') }}


<div class="col-12 field-unit-quantity">
<div class="row">
<div class="col-6">
{{ form_row(form.unit, {"attr":{'v-model': 'unit', '@change': "unitUpdated"}}) }}
</div>


<div class="col-6" v-show="behaviorPrice=='by-piece'">
<div class="form-group field-weight">
{{ form_label(form.quantity) }}
<div class="form-widget">
<div class="input-group">
{{ form_widget(form.quantity, {'attr' : {'v-model': 'quantity', '@change': "quantityUpdated"}}) }}
<div class="input-group-append">
<span class="input-group-text">${ unitWording }</span>
</div>
</div>
{{ form_help(form.quantity) }}
</div>
</div>
</div>
</div>
</div>


{{ macros.priceField(form.buyingPrice, form.buyingPriceWithTax, 'buyingPrice', 'by-piece') }} {{ macros.priceField(form.buyingPrice, form.buyingPriceWithTax, 'buyingPrice', 'by-piece') }}



+ 66
- 6
ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig View File

{{ macros.productField(2, product.priceByRefUnitWithTax, 'priceByRefUnitWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'by-reference-unit\'"') }} {{ macros.productField(2, product.priceByRefUnitWithTax, 'priceByRefUnitWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'by-reference-unit\'"') }}


<td colspan="2" v-show="productFamily.behaviorPrice == 'by-reference-unit'"> <td colspan="2" v-show="productFamily.behaviorPrice == 'by-reference-unit'">
{% verbatim %}{{ priceWithTaxValue }}{% endverbatim %}€
{% verbatim %}{{ finalPriceWithTax }}{% endverbatim %}€
</td> </td>

{{ macros.productField(2, product.price, 'price', false, '€', 'v-show="productFamily.behaviorPrice == \'by-piece\'"') }} {{ macros.productField(2, product.price, 'price', false, '€', 'v-show="productFamily.behaviorPrice == \'by-piece\'"') }}
{{ macros.productField(2, product.priceWithTax, 'priceWithTax', false, '€', 'v-show="productFamily.behaviorPrice == \'by-piece\'"') }} {{ macros.productField(2, product.priceWithTax, 'priceWithTax', false, '€', 'v-show="productFamily.behaviorPrice == \'by-piece\'"') }}


{{ macros.productField(2, product.availableQuantity, 'availableQuantity',false, '', 'v-show="productFamily.behaviorCountStock== \'by-product\'"') }}
{{ macros.productField(2, product.availableQuantityDefault, 'availableQuantityDefault',false, '', 'v-show="productFamily.behaviorCountStock== \'by-product\'"') }}
{{ macros.productField(2, product.propertyExpirationDate, 'propertyExpirationDate','propertyExpirationDateFormated', '', 'v-show="productFamily.behaviorExpirationDate== \'by-product\'"') }}
{{ macros.productField(1, product.availableQuantity, 'availableQuantity',false, '', 'v-show="productFamily.behaviorCountStock== \'by-product\'"') }}
{{ macros.productField(1, product.availableQuantityDefault, 'availableQuantityDefault',false, '', 'v-show="productFamily.behaviorCountStock== \'by-product\'"') }}

{{ macros.productField(2, product.propertyExpirationDate, 'propertyExpirationDate','propertyExpirationDateValue', '', 'v-show="productFamily.behaviorExpirationDate== \'by-product\'"') }}


<td> <td>
<button type="button" class="btn-remove-product btn btn-default" @click="deleteProductForm()"> <button type="button" class="btn-remove-product btn btn-default" @click="deleteProductForm()">
PV TTC PV TTC
</th> </th>



<th v-show="behaviorCountStock== 'by-product'"> <th v-show="behaviorCountStock== 'by-product'">
Stock Stock
</th> </th>
</template> </template>


</tbody> </tbody>
<tfoot>
<th>
Rappel
</th>
<th colspan="2" class="string">
${title}
</th>
<th colspan="1" class="string ">
${productFamily.quantity}
</th>
<th colspan="2" class="quantity">
${productFamily.unitWording}
</th>
<th v-show="getBehaviorPrice() == 'by-reference-unit'" colspan="2" class="buyingPriceByRefUnit">
${productFamily.buyingPriceByRefUnit}
</th>
<th v-show="getBehaviorPrice() == 'by-reference-unit'" colspan="2" class="priceByRefUnit">
${productFamily.buyingPriceByRefUnitWithTax}
</th>

<th colspan="2" class="price" v-show="getBehaviorPrice() =='by-piece'">
${productFamily.buyingPrice}
</th>
<th colspan="2" class="price" v-show="getBehaviorPrice() =='by-piece'">
${productFamily.buyingPriceWithTax}
</th>
<th colspan="2" class="">
${productFamily.multiplyingFactor}
</th>


<th v-show="getBehaviorPrice() == 'by-reference-unit'" colspan="2" class="">
${productFamily.priceByRefUnit}
</th>
<th v-show="getBehaviorPrice() == 'by-reference-unit'" colspan="2" class="price">
${productFamily.priceByRefUnitWithTax}
</th>

<th colspan="2" class="price" v-show="getBehaviorPrice() =='by-piece'">
${productFamily.price}
</th>
<th colspan="2" class="price">
${productFamily.priceWithTax}
</th>

<th v-show="behaviorCountStock== 'by-product'">
</th>
<th v-show="behaviorCountStock== 'by-product'">
</th>
<th colspan="2" class="" v-show="behaviorExpirationDate== 'by-product'">
${propertyExpirationDate}
</th>
<th class="">

</th>
</tfoot>
</table> </table>
<button type="button" class="add_tag_link btn-add-product btn btn-default" @click="addProductForm"><span <button type="button" class="add_tag_link btn-add-product btn btn-default" @click="addProductForm"><span
class="fa fa-plus"></span> Ajouter une déclinaison class="fa fa-plus"></span> Ajouter une déclinaison
{% if product.vars.value.title %}title: "{{ product.vars.value.title }}",{% endif %} {% if product.vars.value.title %}title: "{{ product.vars.value.title }}",{% endif %}
{% if product.vars.value.quantity %}quantity: "{{ product.vars.value.quantity }}",{% endif %} {% if product.vars.value.quantity %}quantity: "{{ product.vars.value.quantity }}",{% endif %}
{% if product.vars.value.unit %}unit: {{ product.vars.value.unit.id }},{% endif %} {% if product.vars.value.unit %}unit: {{ product.vars.value.unit.id }},{% endif %}
{% if product.vars.value.buyingPrice %}buyingPrice: "{{ product.vars.value.buyingPrice }}",{% endif %}
{% if product.vars.value.buyingPrice %}buyingPrice: parseFloat({{ product.vars.value.buyingPrice }}).toFixed(3),{% endif %}
{% if product.vars.value.buyingPriceByRefUnit %}buyingPriceByRefUnit: parseFloat({{ product.vars.value.buyingPriceByRefUnit }}).toFixed(3),{% endif %}
{% if product.vars.value.price %}price: parseFloat({{ product.vars.value.price }}).toFixed(3),{% endif %} {% if product.vars.value.price %}price: parseFloat({{ product.vars.value.price }}).toFixed(3),{% endif %}
{% if product.vars.value.priceByRefUnit %}priceByRefUnit: parseFloat({{ product.vars.value.priceByRefUnit }}).toFixed(3),{% endif %}
{% if product.vars.value.availableQuantity %}availableQuantity: parseInt({{ product.vars.value.availableQuantity }}),{% endif %} {% if product.vars.value.availableQuantity %}availableQuantity: parseInt({{ product.vars.value.availableQuantity }}),{% endif %}
{% if product.vars.value.availableQuantityDefault %}availableQuantityDefault: parseInt({{ product.vars.value.availableQuantityDefault }}),{% endif %} {% if product.vars.value.availableQuantityDefault %}availableQuantityDefault: parseInt({{ product.vars.value.availableQuantityDefault }}),{% endif %}
{% if product.vars.value.propertyExpirationDate %}propertyExpirationDate: "{{ product.vars.value.propertyExpirationDate }}",{% endif %}
{#{% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %}#} {#{% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %}#}
}; };
window.formProductTemplate[{{ keyForm }}] = '{{ formMacros.printProductRow(product)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; window.formProductTemplate[{{ keyForm }}] = '{{ formMacros.printProductRow(product)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}';

+ 21
- 0
ShopBundle/Resources/views/backend/productfamily/panel_reduction.html.twig View File

{% trans_default_domain 'lcshop' %}
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %}

{% set formValues = form.reductionCatalog.vars.value %}

{{ macros.reductionCatalogFormValues(formValues, true) }}

<div class="row">
{{ macros.startCard(12, 'ProductFamily.initReduction', 'light') }}
<div class="col-12">
{{ form_row(form.activeReductionCatalog, {'attr': {'v-model' : 'reductionActive'}}) }}
</div>
{{ macros.endCard() }}

<div class="col-12">

<div class="row" v-show="reductionActive == true">
{{ macros.reductionCatalogForm(form.reductionCatalog) }}
</div>
</div>
</div>

+ 1
- 1
ShopBundle/Resources/views/backend/productfamily/panel_stock.html.twig View File

{{ form_label(form.behaviorCountStock) }} {{ form_label(form.behaviorCountStock) }}
{% for field in form.behaviorCountStock %} {% for field in form.behaviorCountStock %}
{% if field.vars.value == "by-product" %} {% if field.vars.value == "by-product" %}
<div v-if="isProductsActice() == true">
<div v-if="activeProducts == true">
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorCountStock'}}) }} {{ form_widget(field, {"attr" : {"v-model" : 'behaviorCountStock'}}) }}
</div> </div>
{% else %} {% else %}

+ 2
- 108
ShopBundle/Resources/views/backend/reductioncatalog/form.html.twig View File

{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} {% import '@LcShop/backend/default/block/macros.html.twig' as macros %}


{% set formValues = form.vars.value %} {% set formValues = form.vars.value %}
{{ macros.reductionCatalogFormValues(formValues) }}


<script>

window.appReductionCatalogValues = {
{% if formValues.permanent is not null and formValues.permanent == false %}permanent: false,{% endif %}
{% if formValues.users is not empty %}usersActive: true,{% endif %}
{% if formValues.groupUsers is not empty %}groupUsersActive: true,{% endif %}
{% if formValues.productFamilies is not empty %}productFamiliesActive: true,{% endif %}
{% if formValues.productCategories is not empty %}productCategoriesActive: true,{% endif %}
{% if formValues.suppliers is not empty %}suppliersActive: true,{% endif %}
}
</script>
<div id="lc-reduction-catalog-edit" class="row"> <div id="lc-reduction-catalog-edit" class="row">


{{ macros.startCard(6, 'ReductionCatalog.info') }}
<div class="col-12">
{{ form_row(form.title) }}
</div>
{# <div class="col-12">
{{ form_row(form.fromQuantity) }}
</div>
#}
<div class="col-12">
{{ form_row(form.behaviorTaxRate) }}
</div>

<div class="col-12">
{{ form_row(form.unit) }}
</div>
<div class="col-12">
{{ form_row(form.value) }}
</div>



{{ macros.endCard() }}


{{ macros.startCard(6, 'ReductionCatalog.conditions','success') }}
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.permanent, {"attr" : {'v-model' : 'permanent' } }) }}
</div>
<div class="input-group" v-show="permanent == false">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-clock"></i></span>
</div>
<input type="text" class="form-control float-right date-time-range">
<div class="hidden date-time-range-fields" style="display: none;">
{{ form_widget(form.dateStart, {"attr" : {'class' : 'date-start'}}) }}
{{ form_widget(form.dateEnd, {"attr" : {'class' : 'date-end'}}) }}
</div>
</div>

</div>
</div>
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.usersActive, {"attr" : {'v-model' : 'usersActive' } }) }}
</div>
<div class="form-widget" v-show="usersActive == true">
{{ form_widget(form.users) }}
</div>
</div>
</div>
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.groupUsersActive, {"attr" : {'v-model' : 'groupUsersActive' } }) }}
</div>
<div class="form-widget" v-show="groupUsersActive == true">
{{ form_widget(form.groupUsers) }}
</div>
</div>

</div>
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.suppliersActive, {"attr" : {'v-model' : 'suppliersActive' } }) }}
</div>
<div class="form-widget" v-show="suppliersActive == true">
{{ form_widget(form.suppliers) }}
</div>
</div>
</div>
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.productCategoriesActive, {"attr" : {'v-model' : 'productCategoriesActive' } }) }}
</div>
<div class="form-widget" v-show="productCategoriesActive == true">
{{ form_widget(form.productCategories) }}
</div>
</div>
</div>
<div class="col-12">
<div class="form-group">
<div class="form-group">
{{ form_widget(form.productFamiliesActive, {"attr" : {'v-model' : 'productFamiliesActive' } }) }}
</div>
<div class="form-widget" v-show="productFamiliesActive == true">
{{ form_widget(form.productFamilies) }}
</div>
</div>
</div>

{{ macros.endCard() }}

{{ macros.reductionCatalogForm(form) }}
</div> </div>
{{ form_end(form) }} {{ form_end(form) }}

+ 68
- 30
ShopBundle/Services/OrderUtils.php View File



namespace Lc\ShopBundle\Services ; namespace Lc\ShopBundle\Services ;


use App\Entity\OrderProductReductionCatalog;
use App\Entity\OrderShop; use App\Entity\OrderShop;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Lc\ShopBundle\Context\MerchantUtilsInterface; use Lc\ShopBundle\Context\MerchantUtilsInterface;
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;


class OrderUtils class OrderUtils
protected $userUtils; protected $userUtils;
protected $merchantUtils; protected $merchantUtils;
private $orderShopRepo; private $orderShopRepo;
protected $priceUtils ;
protected $productFamilyUtils ;


public function __construct(EntityManagerInterface $em, Security $security, UserUtils $userUtils, MerchantUtilsInterface $merchantUtils)
public function __construct(EntityManagerInterface $em, Security $security, UserUtils $userUtils,
MerchantUtilsInterface $merchantUtils, PriceUtils $priceUtils, ProductFamilyUtilsInterface $productFamilyUtils)
{ {
$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 ;
$this->productFamilyUtils = $productFamilyUtils ;
} }


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

$productFamily = $this->productFamilyUtils->getProductFamilyBySlug($orderProductAdd->getProduct()->getProductFamily()->getSlug()) ;
$reductionCatalog = $productFamily->getReductionCatalog() ;
if($reductionCatalog) {
$orderProductReductionCatalog = new OrderProductReductionCatalog() ;
$orderProductReductionCatalog->setTitle($reductionCatalog->getTitle()) ;
$orderProductReductionCatalog->setValue($reductionCatalog->getValue()) ;
$orderProductReductionCatalog->setUnit($reductionCatalog->getUnit()) ;
$orderProductReductionCatalog->setBehaviorTaxRate($reductionCatalog->getBehaviorTaxRate()) ;

$orderProductAdd->setOrderProductReductionCatalog($orderProductReductionCatalog);
}

foreach($orderShop->getOrderProducts() as $orderProduct) {
if ($orderProduct->getProduct()->getId() == $orderProductAdd->getProduct()->getId()
&& $this->priceUtils->getPrice($orderProduct) == $this->priceUtils->getPrice($orderProductAdd)
&& $this->compareOrderProductReductionCatalog($orderProduct->getOrderProductReductionCatalog(), $orderProductAdd->getOrderProductReductionCatalog())) {


foreach ($orderShop->getOrderProducts() as $orderProduct) {
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);
} }
} }


if (!$updated) { if (!$updated) {
$orderShop->addOrderProduct($orderProductAdd); $orderShop->addOrderProduct($orderProductAdd);

if(isset($orderProductReductionCatalog)) {
$this->em->persist($orderProductReductionCatalog);
}

$this->em->persist($orderProductAdd); $this->em->persist($orderProductAdd);
$this->em->persist($orderShop); $this->em->persist($orderShop);
} }
} }
} }


public function compareOrderProductReductionCatalog($orderProductReductionCatalog1, $orderProductReductionCatalog2)
{
return $orderProductReductionCatalog1 && $orderProductReductionCatalog2
&& $orderProductReductionCatalog1->getUnit() == $orderProductReductionCatalog2->getUnit()
&& $orderProductReductionCatalog1->getValue() == $orderProductReductionCatalog2->getValue()
&& $orderProductReductionCatalog1->getBehaviorTaxRate() == $orderProductReductionCatalog2->getBehaviorTaxRate() ;
}

public function countQuantities($orderShop) public function countQuantities($orderShop)
{ {
return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts()); return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts());
$count = 0; $count = 0;


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


return $count; return $count;
} }


public function calculateTotalWithTax($orderShop)
{
return $this->calculateTotalWithTaxByOrderProducts($orderShop->getOrderProducts());
}

public function calculateTotalWithTaxByOrderProducts($orderProducts = [])
{
$totalWithTax = 0;

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

return $totalWithTax;
}

public function orderProductsByParentCategory($orderShop = null)
public function getOrderProductsByParentCategory($orderShop = null)
{ {
$categoriesArray = []; $categoriesArray = [];
foreach ($orderShop->getOrderProducts() as $orderProduct) { foreach ($orderShop->getOrderProducts() as $orderProduct) {
return $categoriesArray; return $categoriesArray;
} }


public function getDatasSummary($orderShop = null)
public function getOrderDatas($order = null)
{ {
if(!$orderShop) {
$orderShop = $this->getOrderShopCurrent() ;
if(!$order) {
$order = $this->getOrderShopCurrent() ;
} }


$data = [] ; $data = [] ;
$data['count'] = $this->countQuantities($orderShop) ;
$data['total_with_tax'] = $this->calculateTotalWithTax($orderShop) ;
$data['categories'] = $this->orderProductsByParentCategory($orderShop) ;
$data['order'] = $order ;
$data['count'] = $this->countQuantities($order) ;
$data['total_with_tax'] = $this->priceUtils->getTotalWithTaxAndReduction($order) ;
$data['order_products_by_category'] = $this->getOrderProductsByParentCategory($order) ;


return $data ; return $data ;
} }


public function getSummaryOrderProductReductionCatalog($orderProductReductionCatalog)
{
$text = '' ;

if($orderProductReductionCatalog) {
if($orderProductReductionCatalog->getUnit() == 'amount') {
$text .= '- '.$orderProductReductionCatalog->getValue().'&nbsp;€' ;
}

if($orderProductReductionCatalog->getUnit() == 'percent') {
$text .= '- '.$orderProductReductionCatalog->getValue().'&nbsp;%' ;
}
}

return $text ;
}

} }

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

<?php

namespace Lc\ShopBundle\Services ;

use Lc\ShopBundle\Context\OrderProductInterface;
use Lc\ShopBundle\Context\OrderShopInterface;
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() / $entity->getUnitInherited()->getCoefficient()) ;
}
}
}

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->getPrice($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) ;
}
if($entity instanceof OrderShopInterface) {
$total = 0 ;
foreach($entity->getOrderProducts() as $orderProduct) {
$total += $this->getTotal($orderProduct) ;
}
return $total ;
}
return null ;
}

public function getTotalWithTax($entity)
{
if($entity instanceof OrderProductInterface) {
return $this->applyTax(
$this->getTotal($entity),
$entity->getTaxRateInherited()->getValue()
) ;
}
if($entity instanceof OrderShopInterface) {
$total = 0 ;
foreach($entity->getOrderProducts() as $orderProduct) {
$total += $this->getTotalWithTax($orderProduct) ;
}
return $total ;
}
if($entity instanceof OrderShopInterface) {
return $this->getTotalWithTaxByOrderProducts($entity->getOrderProducts()) ;
}
return null ;
}

public function getTotalWithTaxAndReduction($entity)
{
if($entity instanceof OrderProductInterface) {
return $this->getPriceWithTaxAndReductionCatalog(
$entity,
$this->getTotal($entity),
$this->getTotalWithTax($entity)
) ;
}

if($entity instanceof OrderShopInterface) {
return $this->getTotalWithTaxAndReductionByOrderProducts($entity->getOrderProducts()) ;
}
}

public function getTotalWithTaxByOrderProducts($orderProducts)
{
$totalWithTax = 0;

foreach ($orderProducts as $orderProduct) {
$totalWithTax += $this->getTotalWithTax($orderProduct);
}

return $totalWithTax;
}

public function getTotalWithTaxAndReductionByOrderProducts($orderProducts)
{
$totalWithTax = 0;

foreach ($orderProducts as $orderProduct) {
$totalWithTax += $this->getTotalWithTaxAndReduction($orderProduct);
}

return $totalWithTax;
}

public function getPriceWithTaxAndReductionCatalog($entity, $price, $priceWithTax, $reductionCatalog = null): ?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') {
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);
}

}

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

<?php

namespace Lc\ShopBundle\Services ;

class ProductFamilyUtils
{
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