@@ -0,0 +1,8 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Context ; | |||
interface OrderProductReductionCatalogInterface | |||
{ | |||
} |
@@ -0,0 +1,8 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Context ; | |||
interface ProductFamilyUtilsInterface | |||
{ | |||
} |
@@ -240,11 +240,17 @@ class AdminController extends EasyAdminController | |||
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); | |||
if($override)$formBuilder = $this->overrideFormBuilder($formBuilder, $entity, $view); | |||
return $formBuilder; | |||
} | |||
public function overrideFormBuilder($formBuilder, $entity, $view){ | |||
$id = (null !== $entity->getId()) ? $entity->getId() : 0; | |||
if ($entity instanceof StatusInterface) { | |||
@@ -277,75 +283,82 @@ class AdminController extends EasyAdminController | |||
$formBuilder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) { | |||
$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; | |||
} | |||
} | |||
} | |||
@@ -77,7 +77,7 @@ class OrderController extends AdminController | |||
parent::persistEntity($entity); | |||
} | |||
public function createEntityFormBuilder($entity, $view) | |||
public function createEntityFormBuilder($entity, $view, $override=true) | |||
{ | |||
$formBuilder = parent::createEntityFormBuilder($entity, $view); | |||
@@ -3,12 +3,15 @@ | |||
namespace Lc\ShopBundle\Controller\Admin; | |||
use App\Entity\Product; | |||
use App\Entity\ReductionCatalog; | |||
use Doctrine\DBAL\Types\FloatType; | |||
use Doctrine\ORM\EntityRepository; | |||
use EasyCorp\Bundle\EasyAdminBundle\Event\EasyAdminEvents; | |||
use Lc\ShopBundle\Context\ProductCategoryInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductInterface; | |||
use Lc\ShopBundle\Context\ReductionCartInterface; | |||
use Lc\ShopBundle\Context\ReductionCatalogInterface; | |||
use Lc\ShopBundle\Context\TaxRateInterface; | |||
use Lc\ShopBundle\Context\UnitInterface; | |||
use Lc\ShopBundle\Form\ProductFamilyCategoriesType; | |||
@@ -29,21 +32,27 @@ class ProductFamilyController extends AdminController | |||
private $choicesTaxRateParam; | |||
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); | |||
$this->taxRateClass = $this->em->getClassMetadata(TaxRateInterface::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( | |||
@@ -72,14 +81,13 @@ class ProductFamilyController extends AdminController | |||
)); | |||
$formBuilder->add('behaviorAddToCart', ChoiceType::class, array( | |||
'empty_data' => 'by-product-family', | |||
'data' => $entity->getBehaviorAddToCart() ? $entity->getBehaviorAddToCart() : 'simple', | |||
'choices' => array( | |||
'field.ProductFamily.behaviorAddToCartOptions.simple' => 'simple', | |||
'field.ProductFamily.behaviorAddToCartOptions.multiple' => 'multiple' | |||
), | |||
'translation_domain' => 'lcshop', | |||
'multiple' => false, | |||
'required'=>false, | |||
'expanded' => true | |||
)); | |||
@@ -94,6 +102,11 @@ class ProductFamilyController extends AdminController | |||
'expanded' => true | |||
)); | |||
$formBuilder->add('multiplyingFactor', NumberType::class, array( | |||
'mapped'=> false, | |||
'data'=> floatval($this->merchantUtils->getMerchantConfig('multiplying-factor')), | |||
)); | |||
$formBuilder->add('propertyOrganicLabel', ChoiceType::class, array( | |||
'choices' => array( | |||
'field.ProductFamily.organicLabelOptions.ab' => 'ab', | |||
@@ -140,67 +153,67 @@ class ProductFamilyController extends AdminController | |||
) | |||
); | |||
$formBuilder = $this->overrideFormBuilder($formBuilder, $entity, $view); | |||
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->processProducts($entity); | |||
/* dump($reductionCatalog); | |||
dump($productFamilyRequest);*/ | |||
$this->processPrice($entity); | |||
parent::updateEntity($entity); | |||
} | |||
public function persistEntity($entity) | |||
public function persistProductFamilyEntity($entity, $newForm) | |||
{ | |||
$this->processReductionCatalog($entity, $newForm); | |||
$this->processCategories($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) | |||
{ | |||
$repo = $this->em->getRepository(UnitInterface::class); | |||
//si il existe un et un seul produit pour ce product family n'ajoute rien supprime rien | |||
if (count($entity->getProducts()) == 0) { | |||
$product = new Product(); | |||
$product->setProductFamily($entity); | |||
$this->em->persist($product); | |||
$entity->addProduct($product); | |||
} else { | |||
foreach ($entity->getProducts() as $i=>$product) { | |||
$product->setProductFamily($entity); | |||
$this->em->persist($product); | |||
$entity->addProduct($product); | |||
// die('ncici'); | |||
} | |||
} | |||
@@ -260,6 +273,7 @@ class ProductFamilyController extends AdminController | |||
$sortableProductsField[$product->getPosition()] = $k; | |||
} | |||
ksort($sortableProductsField); | |||
$editForm->handleRequest($this->request); | |||
if ($editForm->isSubmitted() && $editForm->isValid()) { | |||
@@ -47,7 +47,7 @@ class CartController extends BaseController | |||
foreach($data as $orderProduct) { | |||
if($orderProduct instanceof OrderProductInterface) { | |||
$this->orderUtils->addOrderProduct($orderShop, $orderProduct) ; | |||
if($orderProduct->getQuantity() > 0) { | |||
if($orderProduct->getQuantityorder() > 0) { | |||
$this->orderProducts[] = $orderProduct ; | |||
} | |||
} |
@@ -82,8 +82,7 @@ class ProductType extends AbstractType | |||
$builder->add('buyingPriceByRefUnit', NumberType::class, array( | |||
'label' => 'Prix d\'achat', | |||
'required'=>false, | |||
'mapped' => false | |||
'required'=>false | |||
)); | |||
$builder->add('buyingPriceByRefUnitWithTax', NumberType::class, array( | |||
@@ -98,8 +97,7 @@ class ProductType extends AbstractType | |||
)); | |||
$builder->add('priceByRefUnit', NumberType::class, array( | |||
'required'=>false, | |||
'mapped' => false | |||
'required'=>false | |||
)); | |||
$builder->add('priceByRefUnitWithTax', NumberType::class, array( | |||
@@ -117,9 +115,8 @@ class ProductType extends AbstractType | |||
'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); |
@@ -2,7 +2,13 @@ | |||
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\UserInterface; | |||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\Extension\Core\Type\DateTimeType; | |||
@@ -25,34 +31,112 @@ class ReductionCatalogType extends AbstractType | |||
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 | |||
->add('title', TextType::class, ['label' => 'Titre']) | |||
->add('title', TextType::class, [ | |||
'label' => 'Titre', | |||
'required' => false, | |||
]) | |||
->add('behaviorTaxRate', ChoiceType::class, [ | |||
'required'=> true, | |||
'required' => false, | |||
'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, [ | |||
'required'=> true, | |||
'required' => false, | |||
'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) | |||
{ | |||
$resolver->setDefaults([ | |||
'label' => false, | |||
'data_class' => $this->em->getClassMetadata(ReductionCatalogInterface::class)->getName() | |||
//'data_class' => $this->em->getClassMetadata(ReductionCatalogInterface::class)->getName(), | |||
'translation_domain'=> 'lcshop' | |||
]); | |||
} | |||
} |
@@ -9,7 +9,7 @@ trait OrderAmountMin | |||
/** | |||
* @ORM\Column(type="float") | |||
*/ | |||
private $orderAmountMin; | |||
protected $orderAmountMin; | |||
public function getOrderAmountMin(): ?float | |||
{ |
@@ -2,6 +2,7 @@ | |||
namespace Lc\ShopBundle\Model; | |||
use App\Entity\OrderProductReductionCatalog; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\ShopBundle\Context\PriceInterface; | |||
@@ -38,6 +39,11 @@ abstract class OrderProduct implements PriceInterface | |||
*/ | |||
protected $title; | |||
/** | |||
* @ORM\OneToOne(targetEntity="Lc\ShopBundle\Context\OrderProductReductionCatalogInterface", cascade={"persist", "remove"}) | |||
*/ | |||
protected $orderProductReductionCatalog; | |||
public function __toString() | |||
{ | |||
if($this->getTitle()) { | |||
@@ -52,7 +58,8 @@ abstract class OrderProduct implements PriceInterface | |||
{ | |||
$product = $this->getProduct() ; | |||
$productFamily = $product->getProductFamily() ; | |||
$titleProduct = $product->getTitleInherited() ; | |||
$titleProduct = $product->getTitle() ; | |||
$titleProductFamily = $productFamily->getTitle() ; | |||
if(strlen($titleProduct) > 0 && strlen($titleProductFamily) > 0) { | |||
@@ -158,4 +165,17 @@ abstract class OrderProduct implements PriceInterface | |||
return $this; | |||
} | |||
public function getOrderProductReductionCatalog(): ?OrderProductReductionCatalog | |||
{ | |||
return $this->orderProductReductionCatalog; | |||
} | |||
public function setOrderProductReductionCatalog(?OrderProductReductionCatalog $orderProductReductionCatalog): self | |||
{ | |||
$this->orderProductReductionCatalog = $orderProductReductionCatalog; | |||
return $this; | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
<?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; | |||
} | |||
} |
@@ -24,11 +24,6 @@ trait PriceTrait | |||
*/ | |||
protected $taxRate; | |||
public function getPrice(): ?float | |||
{ | |||
return $this->price; | |||
} | |||
public function getPriceInherited(): ?float | |||
{ | |||
return $this->getPrice() ; | |||
@@ -44,83 +39,13 @@ trait PriceTrait | |||
return $this->getTaxRate() ; | |||
} | |||
public function getPriceWithTax(): ?float | |||
{ | |||
return $this->calculatePriceWithTax($this->getPriceInherited(), $this->getTaxRateInherited()->getValue()) ; | |||
} | |||
public function getPriceByUnitRef(): ?float | |||
{ | |||
return $this->calculatePriceByUnitRef($this->getPriceInherited()) ; | |||
} | |||
public function getPriceByUnitRefWithTax(): ?float | |||
{ | |||
return $this->calculatePriceByUnitRef($this->getPriceWithTax()) ; | |||
} | |||
public function getTheReductionCatalog() | |||
{ | |||
$reductionCatalog = false; | |||
if($this instanceof ProductFamily) { | |||
$reductionCatalog = $this->getReductionCatalog() ; | |||
} | |||
if($this instanceof Product) { | |||
$reductionCatalog = $this->getProductFamily()->getReductionCatalog() ; | |||
} | |||
return $reductionCatalog ; | |||
} | |||
public function getPriceByUnitRefWithTaxAndReduction(): ?float | |||
{ | |||
$reductionCatalog = $this->getTheReductionCatalog() ; | |||
if (isset($reductionCatalog) && $reductionCatalog) { | |||
return $this->calculatePriceByUnitRef($this->getPriceWithTaxAndReductionCatalog($reductionCatalog)) ; | |||
} | |||
else { | |||
return $this->calculatePriceByUnitRef($this->getPriceWithTax()); | |||
} | |||
} | |||
public function getPriceWithTaxAndReduction(): ?float | |||
{ | |||
$reductionCatalog = $this->getTheReductionCatalog() ; | |||
if (isset($reductionCatalog) && $reductionCatalog) { | |||
return $this->getPriceWithTaxAndReductionCatalog($reductionCatalog); | |||
} | |||
else { | |||
return $this->getPriceWithTax(); | |||
} | |||
} | |||
public function getPriceWithTaxAndReductionCatalog(ReductionCatalogInterface $reductionCatalog): ?float | |||
public function getPrice(): ?float | |||
{ | |||
if ($reductionCatalog->getUnit() == 'percent') { | |||
//Théoriquement que la réduction s'applique sur le prixHT ou le prixTTC le résultat est le même,j'ai laisser mon code au cas où ;) | |||
return $this->calculatePriceWithReductionPercent($this->getPriceWithTax(), $reductionCatalog->getValue()); | |||
/*if ($reductionCatalog->getBehaviorTaxRate() == 'tax-excluded') { | |||
$priceReductionHT = $this->calculatePriceWithReductionPercent($this->getPriceInherited(), $reductionCatalog->getValue()); | |||
return $this->calculatePriceWithTax($priceReductionHT, $this->getTaxRateInherited()->getValue()); | |||
} else if ($reductionCatalog->getBehaviorTaxRate() == 'tax-included') { | |||
return $this->calculatePriceWithReductionPercent($this->getPriceWithTax(), $reductionCatalog->getValue()); | |||
}*/ | |||
}elseif ($reductionCatalog->getUnit() == 'amount') { | |||
if ($reductionCatalog->getBehaviorTaxRate() == 'tax-excluded') { | |||
$priceReductionHT = $this->calculatePriceWithReductionAmount($this->getPriceInherited(), $reductionCatalog->getValue()); | |||
return $this->calculatePriceWithTax($priceReductionHT, $this->getTaxRateInherited()->getValue()); | |||
}else if ($reductionCatalog->getBehaviorTaxRate() == 'tax-included') { | |||
return $this->calculatePriceWithReductionAmount($this->getPriceWithTax(), $reductionCatalog->getValue()); | |||
} | |||
} | |||
return $this->price; | |||
} | |||
public function setPrice(float $price): self | |||
public function setPrice(?float $price): self | |||
{ | |||
$this->price = $price; | |||
@@ -150,29 +75,4 @@ trait PriceTrait | |||
return $this; | |||
} | |||
private function calculatePriceWithTax($priceWithoutTax, $taxRateValue): ?float | |||
{ | |||
$price = floatval($priceWithoutTax) * ($taxRateValue / 100 + 1); | |||
$price = round((($price * 100)) / 100, 2); | |||
return $price; | |||
} | |||
public function calculatePriceWithReductionPercent($price, $percentValue): ?float | |||
{ | |||
$price = floatval($price) * (1 - $percentValue / 100); | |||
$price = round((($price * 100)) / 100, 2); | |||
return $price; | |||
} | |||
public function calculatePriceWithReductionAmount($price, $amountValue): ?float | |||
{ | |||
$price = floatval($price) - $amountValue; | |||
$price = round((($price * 100)) / 100, 2); | |||
return $price; | |||
} | |||
private function calculatePriceByUnitRef($price) | |||
{ | |||
return ($price * $this->getUnitInherited()->getCoefficient()) / $this->getQuantityInherited() ; | |||
} | |||
} |
@@ -43,41 +43,61 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
public function getPriceInherited() | |||
{ | |||
if($this->price) { | |||
return $this->price; | |||
if($this->getPrice()) { | |||
return $this->getPrice(); | |||
} | |||
else { | |||
return $this->productFamily->getPrice(); | |||
return $this->getProductFamily()->getPrice(); | |||
} | |||
} | |||
public function getPriceByRefUnitInherited() | |||
{ | |||
if($this->getPriceByRefUnit()) { | |||
return $this->getPriceByRefUnit(); | |||
} | |||
else { | |||
return $this->getProductFamily()->getPriceByRefUnit(); | |||
} | |||
} | |||
public function getBehaviorPriceInherited() | |||
{ | |||
return $this->getProductFamily()->getBehaviorPrice() ; | |||
} | |||
public function getReductionCatalogInherited() | |||
{ | |||
return $this->getProductFamily()->getReductionCatalog() ; | |||
} | |||
public function getUnitInherited() | |||
{ | |||
if($this->unit) { | |||
return $this->unit; | |||
if($this->getUnit()) { | |||
return $this->getUnit(); | |||
} | |||
else{ | |||
return $this->productFamily->getUnit(); | |||
else { | |||
return $this->getProductFamily()->getUnit(); | |||
} | |||
} | |||
public function getTitleInherited() | |||
{ | |||
if($this->title){ | |||
return $this->title; | |||
if($this->getTitle()){ | |||
return $this->getTitle(); | |||
} | |||
else{ | |||
return $this->productFamily->getTitle(); | |||
return $this->getProductFamily()->getTitle(); | |||
} | |||
} | |||
public function getQuantityInherited() | |||
{ | |||
if($this->quantity) { | |||
return $this->quantity; | |||
if($this->getQuantity()) { | |||
return $this->getQuantity(); | |||
} | |||
else{ | |||
return $this->productFamily->getQuantity(); | |||
return $this->getProductFamily()->getQuantity(); | |||
} | |||
} | |||
@@ -90,22 +110,17 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod | |||
public function getAvailableQuantityInherited() | |||
{ | |||
if($this->productFamily->getBehaviorCountStock()) { | |||
return $this->availableQuantity; | |||
if($this->getProductFamily()->getBehaviorCountStock()) { | |||
return $this->getAvailableQuantity(); | |||
} | |||
else{ | |||
return $this->productFamily->getAvailableQuantity(); | |||
else { | |||
return $this->getProductFamily()->getAvailableQuantity(); | |||
} | |||
} | |||
public function getTaxRateInherited() | |||
{ | |||
if($this->productFamily->getTaxRate()) { | |||
return $this->productFamily->getTaxRate(); | |||
} | |||
else{ | |||
return $this->productFamily->getMerchant()->getTaxRate()->getValue(); | |||
} | |||
return $this->getProductFamily()->getTaxRateInherited(); | |||
} | |||
public function getProductFamily(): ?ProductFamily |
@@ -66,7 +66,7 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
/** | |||
* @ORM\Column(type="string", length=255, nullable=true) | |||
*/ | |||
private $warningMessageType; | |||
protected $warningMessageType; | |||
/** | |||
* @ORM\Column(type="text", nullable=true) | |||
@@ -236,6 +236,11 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this->reductionCatalog; | |||
} | |||
public function getReductionCatalogInherited(): ?ReductionCatalog | |||
{ | |||
return $this->getReductionCatalog() ; | |||
} | |||
public function setReductionCatalog(?ReductionCatalog $reductionCatalog): self | |||
{ | |||
$this->reductionCatalog = $reductionCatalog; | |||
@@ -383,44 +388,6 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this; | |||
} | |||
private function getCheapestOrMostExpensiveProduct($comparisonFunction, $returnSelfIfNotActiveProducts) | |||
{ | |||
$products = $this->getProducts()->getValues(); | |||
if (count($products) > 0) { | |||
usort($products, $comparisonFunction); | |||
return $products[0]; | |||
} | |||
if ($returnSelfIfNotActiveProducts) { | |||
return $this; | |||
} else { | |||
return false; | |||
} | |||
} | |||
public function getCheapestProduct() | |||
{ | |||
return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) { | |||
return $a->getPriceInherited() > $b->getPriceInherited(); | |||
}, true); | |||
} | |||
public function getCheapestProductByUnitRef() | |||
{ | |||
return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) { | |||
return $a->getPriceByUnitRef() > $b->getPriceByUnitRef(); | |||
}, false); | |||
} | |||
public function getMostExpensiveProductByUnitRef() | |||
{ | |||
return $this->getCheapestOrMostExpensiveProduct(function ($a, $b) { | |||
return $a->getPriceByUnitRef() < $b->getPriceByUnitRef(); | |||
}, false); | |||
} | |||
public function isPropertyNoveltyOnline(): ?bool | |||
{ | |||
if ($this->getPropertyNoveltyExpirationDate()) { | |||
@@ -585,6 +552,11 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this->behaviorPrice; | |||
} | |||
public function getBehaviorPriceInherited() | |||
{ | |||
return $this->getBehaviorPrice() ; | |||
} | |||
public function setBehaviorPrice(?string $behaviorPrice): self | |||
{ | |||
$this->behaviorPrice = $behaviorPrice; |
@@ -28,7 +28,7 @@ trait ProductPropertyTrait | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $quantity = 1; //par défaut valeur à 1 | |||
protected $quantity; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
@@ -75,6 +75,11 @@ trait ProductPropertyTrait | |||
return $this->priceByRefUnit; | |||
} | |||
public function getPriceByRefUnitInherited(): ?float | |||
{ | |||
return $this->getPriceByRefUnit(); | |||
} | |||
public function setPriceByRefUnit(?float $priceByRefUnit): self | |||
{ | |||
$this->priceByRefUnit = $priceByRefUnit; | |||
@@ -124,12 +129,12 @@ trait ProductPropertyTrait | |||
return $this; | |||
} | |||
public function getPropertyExpirationDate(): ?\DateTimeInterface | |||
public function getPropertyExpirationDate(): ?string | |||
{ | |||
return $this->propertyExpirationDate; | |||
} | |||
public function setPropertyExpirationDate(?\DateTimeInterface $propertyExpirationDate): self | |||
public function setPropertyExpirationDate(?string $propertyExpirationDate): self | |||
{ | |||
$this->propertyExpirationDate = $propertyExpirationDate; | |||
@@ -7,6 +7,7 @@ use Doctrine\Common\Collections\Collection; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\ShopBundle\Context\ReductionInterface; | |||
use Lc\ShopBundle\Model\AbstractDocumentEntity; | |||
use Lc\ShopBundle\Model\ReductionPropertyTrait; | |||
use Lc\ShopBundle\Model\ReductionTrait; | |||
/** | |||
@@ -15,7 +16,7 @@ use Lc\ShopBundle\Model\ReductionTrait; | |||
abstract class ReductionCart extends AbstractDocumentEntity | |||
{ | |||
use ReductionTrait; | |||
use ReductionPropertyTrait ; | |||
/** | |||
* @ORM\Column(type="boolean", nullable=true) |
@@ -15,8 +15,8 @@ use phpDocumentor\Reflection\Types\Integer; | |||
*/ | |||
abstract class ReductionCatalog extends AbstractDocumentEntity implements ReductionCatalogInterface, FilterMerchantInterface | |||
{ | |||
use ReductionTrait; | |||
use ReductionPropertyTrait ; | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies") | |||
@@ -29,6 +29,11 @@ abstract class ReductionCatalog extends AbstractDocumentEntity implements Reduct | |||
*/ | |||
protected $productFamilies; | |||
/** | |||
* @ORM\OneToOne(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface") | |||
*/ | |||
protected $productFamily; | |||
/** | |||
* @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\ProductCategoryInterface") | |||
*/ | |||
@@ -44,10 +49,6 @@ abstract class ReductionCatalog extends AbstractDocumentEntity implements Reduct | |||
*/ | |||
protected $users; | |||
/* | |||
* @ORM\Column(type="smallint") | |||
*/ | |||
// protected $fromQuantity = 1; | |||
public function __construct() | |||
@@ -98,6 +99,18 @@ abstract class ReductionCatalog extends AbstractDocumentEntity implements Reduct | |||
} | |||
public function getProductFamily(): ?ProductFamily | |||
{ | |||
return $this->productFamily; | |||
} | |||
public function setProductFamily(?ProductFamily $productFamily): self | |||
{ | |||
$this->productFamily = $productFamily; | |||
return $this; | |||
} | |||
/** | |||
* @return Collection|GroupUser[] | |||
*/ |
@@ -0,0 +1,61 @@ | |||
<?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; | |||
} | |||
} |
@@ -2,22 +2,10 @@ | |||
namespace Lc\ShopBundle\Model; | |||
use Doctrine\Common\Collections\ArrayCollection; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\ShopBundle\Context\StatusInterface; | |||
trait ReductionTrait | |||
{ | |||
/** | |||
* @ORM\Column(type="datetime", nullable=true) | |||
*/ | |||
protected $dateStart; | |||
/** | |||
* @ORM\Column(type="datetime", nullable=true) | |||
*/ | |||
protected $dateEnd; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
@@ -33,36 +21,6 @@ trait ReductionTrait | |||
*/ | |||
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 | |||
{ | |||
@@ -99,17 +57,4 @@ trait ReductionTrait | |||
return $this; | |||
} | |||
public function getPermanent(): ?bool | |||
{ | |||
return $this->permanent; | |||
} | |||
public function setPermanent(bool $permanent): self | |||
{ | |||
$this->permanent = $permanent; | |||
return $this; | |||
} | |||
} |
@@ -79,5 +79,19 @@ class ProductFamilyRepository extends BaseRepository implements DefaultRepositor | |||
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() ; | |||
} | |||
} |
@@ -120,6 +120,8 @@ table th .select2-container--default .select2-selection--single{padding:0.3rem 0 | |||
/* ProductFamily */ | |||
.field-unit-quantity{border-bottom: 2px dotted #eee; padding-bottom: 10px; margin-bottom: 20px;} | |||
.new-productfamily #nav-params, | |||
.edit-productfamily #nav-params { | |||
margin-bottom: 30px ; | |||
@@ -168,6 +170,7 @@ table th .select2-container--default .select2-selection--single{padding:0.3rem 0 | |||
.autoresize textarea{height: auto; min-height: 38px;} | |||
/* ORDER */ | |||
.table-order-summary{width: 100%;} | |||
@@ -179,7 +182,8 @@ table th .select2-container--default .select2-selection--single{padding:0.3rem 0 | |||
.product-form-modal{display: none;} | |||
.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 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 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;} | |||
@@ -189,6 +193,7 @@ table th .select2-container--default .select2-selection--single{padding:0.3rem 0 | |||
#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 .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 */ | |||
@@ -49,7 +49,7 @@ function lcTaxPriceUpdate(priceType) { | |||
* @returns {string} | |||
*/ | |||
function getPrice(priceWithTax, taxRate) { | |||
return parseFloat(parseFloat(priceWithTax) / ((taxRate/100) + 1)).toFixed(3); | |||
return parseFloat(parseFloat(priceWithTax) / ((taxRate/100) + 1)).toFixed(4); | |||
} | |||
/** | |||
@@ -63,6 +63,18 @@ function getPriceWithTax(priceWithoutTax, taxRate) { | |||
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 | |||
* |
@@ -17,183 +17,225 @@ let mixinPrice = { | |||
}, | |||
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 () { | |||
}, | |||
methods: { | |||
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.unitUpdated(); | |||
this.buyingPriceUpdated(); | |||
}, | |||
priceUpdated: function () { | |||
if(this.price) { | |||
this.setPriceWithTax(); | |||
this.setMultiplyingFactor(); | |||
this.setPriceByRefUnit(); | |||
this.setPriceByRefUnitWithTax(); | |||
} | |||
initByRefUnit: function () { | |||
this.buyingPriceByRefUnitUpdated(); | |||
this.priceByRefUnitUpdated(); | |||
}, | |||
buyingPriceUpdated: function () { | |||
if(this.buyingPrice) { | |||
if (this.buyingPrice) { | |||
this.buyingPrice = formatNumber(this.buyingPrice, 4) | |||
this.setBuyingPriceWithTax(); | |||
this.setMultiplyingFactor(); | |||
//Mise à jour dans le panel price | |||
if (this.priceValue == null) { | |||
this.setPriceFromMultiplyingFactor(); | |||
this.priceUpdated(); | |||
} else { | |||
this.setMultiplyingFactor(); | |||
} | |||
this.setBuyingPriceByRefUnit(); | |||
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.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 | |||
buyingPriceWithTaxUpdated: function () { | |||
this.buyingPriceWithTax = formatNumber(this.buyingPriceWithTax, 2) | |||
this.setBuyingPriceFromBuyingPriceWithTax(); | |||
this.buyingPriceUpdated(); | |||
}, | |||
buyingPriceByRefUnitUpdated: function () { | |||
this.setBuyingPriceFromBuyingPriceByRefUnit(); | |||
this.buyingPriceUpdated(); | |||
}, | |||
buyingPriceByRefUnitWithTaxUpdated: function () { | |||
this.buyingPriceByRefUnitWithTax = formatNumber(this.buyingPriceByRefUnitWithTax, 2) | |||
this.setBuyingPriceByRefUnitFromBuyingPriceByRefUnitWithTax(); | |||
this.buyingPriceByRefUnitUpdated(); | |||
}, | |||
multiplyingFactorUpdated: function () { | |||
this.setPriceFromMultiplyingFactor(); | |||
this.priceUpdated(); | |||
}, | |||
priceWithTaxUpdated: function () { | |||
this.priceWithTax = formatNumber(this.priceWithTax, 2); | |||
this.setPriceFromPriceWithTax(); | |||
this.priceUpdated(); | |||
}, | |||
priceByRefUnitUpdated: function () { | |||
this.setPriceFromPriceByRefUnit(); | |||
this.priceUpdated(); | |||
}, | |||
priceByRefUnitWithTaxUpdated: function () { | |||
this.priceByRefUnitWithTax = formatNumber(this.priceByRefUnitWithTax, 2) | |||
this.setPriceByRefUnitFromTax(); | |||
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 () { | |||
if (this.buyingPriceWithTax) { | |||
this.buyingPriceWithTax = parseFloat(this.buyingPriceWithTax.replace(',', '.')).toFixed(2); | |||
this.buyingPrice = getPrice(this.buyingPriceWithTax, this.supplierTaxRateValue); | |||
} | |||
}, | |||
setBuyingPriceWithTax: function () { | |||
if (this.buyingPrice) { | |||
this.buyingPrice = parseFloat(this.buyingPrice.replace(',', '.')).toFixed(3); | |||
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 () { | |||
if (this.buyingPriceByRefUnitWithTax) { | |||
this.buyingPriceByRefUnitWithTax = parseFloat(this.buyingPriceByRefUnitWithTax.replace(',', '.')).toFixed(2); | |||
this.buyingPriceByRefUnit = getPrice(this.buyingPriceByRefUnitWithTax, this.supplierTaxRateValue); | |||
} | |||
}, | |||
setBuyingPriceByRefUnit: function () { | |||
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 () { | |||
if (this.buyingPriceByRefUnit) { | |||
this.buyingPriceByRefUnit = parseFloat(this.buyingPriceByRefUnit.replace(',', '.')).toFixed(3); | |||
this.buyingPriceByRefUnitWithTax = getPriceWithTax(this.buyingPriceByRefUnit, this.supplierTaxRateValue); | |||
} | |||
}, | |||
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 () { | |||
if (this.priceByRefUnitWithTax) { | |||
this.priceByRefUnitWithTax = parseFloat(this.priceByRefUnitWithTax.replace(',', '.')).toFixed(2); | |||
this.priceByRefUnit = getPrice(this.priceByRefUnitWithTax, this.taxRateValue); | |||
} | |||
}, | |||
setPriceByRefUnit: function () { | |||
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 () { | |||
this.price = parseFloat((this.priceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(2); | |||
this.price = parseFloat((this.priceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(4); | |||
}, | |||
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); | |||
}, | |||
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: {} | |||
@@ -280,4 +322,22 @@ let mixinTemplate = { | |||
} | |||
} | |||
} | |||
} | |||
}; | |||
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); | |||
} | |||
}; |
@@ -7,7 +7,7 @@ Vue.component('product-unit-price', { | |||
props: ['template', 'keyForm'], | |||
data() { | |||
return Object.assign({ | |||
behaviorPrice:null, | |||
behaviorPrice: 'by-piece', | |||
activeProducts: false, | |||
}, window.productUnitPriceValues); | |||
@@ -19,12 +19,27 @@ Vue.component('product-unit-price', { | |||
buyingPriceWithTaxValue: function () { | |||
return this.buyingPriceWithTax; | |||
}, | |||
buyingPriceByRefUnitValue:function(){ | |||
return this.buyingPriceByRefUnit; | |||
}, | |||
buyingPriceByRefUnitWithTaxValue:function(){ | |||
return this.buyingPriceByRefUnitWithTax; | |||
}, | |||
multiplyingFactorValue:function(){ | |||
return this.multiplyingFactor; | |||
}, | |||
priceWithTaxValue: function () { | |||
return this.priceWithTax; | |||
}, | |||
priceValue: function () { | |||
return this.price; | |||
}, | |||
priceByRefUnitValue:function(){ | |||
return this.priceByRefUnit; | |||
}, | |||
priceByRefUnitWithTaxValue:function(){ | |||
return this.priceByRefUnitWithTax; | |||
}, | |||
quantityValue: function () { | |||
return this.quantity; | |||
}, | |||
@@ -33,7 +48,25 @@ Vue.component('product-unit-price', { | |||
}, | |||
behaviorPriceValue:function(){ | |||
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 () { | |||
@@ -42,12 +75,26 @@ Vue.component('product-unit-price', { | |||
watch: { | |||
taxRate: function () { | |||
this.setBuyingPriceWithTax(); | |||
this.setBuyingPriceByRefUnitWithTax(); | |||
this.setPriceWithTax(); | |||
this.setPriceByRefUnitWithTax(); | |||
this.setMultiplyingFactor(); | |||
this.setPriceByUnitRefWithTax(); | |||
this.$parent.updateChild(); | |||
}, | |||
supplierTaxRate: function () { | |||
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; | |||
} | |||
} | |||
} | |||
}); | |||
@@ -56,11 +103,11 @@ Vue.component('product-form', { | |||
mixins: [mixinUnit, mixinPrice, mixinTemplate], | |||
props: ['template', 'keyForm', 'productFamily'], | |||
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 () { | |||
if (this.buyingPrice) return this.buyingPrice; | |||
@@ -70,6 +117,18 @@ Vue.component('product-form', { | |||
if (this.buyingPriceWithTax) return this.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 () { | |||
if (this.priceWithTax) return this.priceWithTax; | |||
else return this.productFamily.priceWithTax; | |||
@@ -94,12 +153,15 @@ Vue.component('product-form', { | |||
if (this.unit) return this.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(){ | |||
return this.productFamily.behaviorPrice; | |||
}, | |||
finalPriceWithTax:function () { | |||
return getPriceWithTax(parseFloat((this.priceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(4), this.taxRateValue); | |||
} | |||
}, | |||
data() { | |||
@@ -114,7 +176,6 @@ Vue.component('product-form', { | |||
availableQuantityDefault: null, | |||
availableQuantity: null, | |||
propertyExpirationDate: null, | |||
titleInherited: false, | |||
priceInherited: false, | |||
priceWithTaxInherited: false, | |||
@@ -137,12 +198,12 @@ Vue.component('product-form', { | |||
mounted: function () { | |||
//INIT VAR | |||
updateSortableProducts(); | |||
this.setUnitSelect2(); | |||
//this.setUnitSelect2(); | |||
//METHOD | |||
this.updateProductForm(); | |||
this.updateProductView(); | |||
//this.updateProductForm(); | |||
//this.updateProductView(); | |||
}, | |||
methods: { | |||
setUnitSelect2:function(){ | |||
@@ -154,30 +215,11 @@ Vue.component('product-form', { | |||
availableQuantityUpdated:function(){}, | |||
availableQuantityDefaultUpdated:function(){}, | |||
propertyExpirationDateUpdated:function(){}, | |||
updateLine: function(){ | |||
this.init(); | |||
}, | |||
updateProductForm: function () { | |||
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 () { | |||
this.updateProductView(); | |||
$('#form-product-modal-' + this.keyForm).modal('hide'); | |||
}, | |||
deleteProductForm: function () { | |||
@@ -192,31 +234,64 @@ Vue.component('product-form', { | |||
appProductFamily = new Vue({ | |||
el: '#lc-product-family-edit', | |||
mixins: [mixinReduction], | |||
delimiters: ['${', '}'], | |||
computed: { | |||
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 () { | |||
this.getUnitReference(); | |||
@@ -226,6 +301,7 @@ appProductFamily = new Vue({ | |||
return Object.assign( | |||
{ | |||
isMounted:false, | |||
indexFormProduct: 0, | |||
title: null, | |||
isNovelty: null, | |||
@@ -237,6 +313,7 @@ appProductFamily = new Vue({ | |||
propertyAllergens: null, | |||
propertyOrganicLabelActive: false, | |||
propertyNoveltyExpirationDateActive: false, | |||
activeProducts:false, | |||
formProductArray: [], | |||
currentSection: 'general', | |||
@@ -261,7 +338,10 @@ appProductFamily = new Vue({ | |||
name: 'property', | |||
nameDisplay: 'Caractéristiques' | |||
}, | |||
{ | |||
name: 'reduction', | |||
nameDisplay: 'Réduction' | |||
}, | |||
{ | |||
name: 'note', | |||
nameDisplay: 'Note interne' | |||
@@ -270,12 +350,12 @@ appProductFamily = new Vue({ | |||
}, window.appProductFamilyValues); | |||
}, | |||
mounted: function () { | |||
this.isMounted = true; | |||
$(".vuejs-checkbox-switch input").each(function () { | |||
setBootstrapSwitch($(this)); | |||
}); | |||
}, | |||
methods: { | |||
changeSection: function (section) { | |||
this.updateChild(); | |||
this.currentSection = section.name; | |||
@@ -298,7 +378,6 @@ appProductFamily = new Vue({ | |||
if (typeof this.$refs.productForm !== 'undefined') { | |||
for (i = 0; i < this.$refs.productForm.length; i++) { | |||
this.$refs.productForm[i].updateProductForm(); | |||
this.$refs.productForm[i].updateProductView(); | |||
} | |||
} | |||
}, | |||
@@ -307,10 +386,8 @@ appProductFamily = new Vue({ | |||
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 () { | |||
if (typeof this.$refs.productUnitPrice !== 'undefined') { |
@@ -3,28 +3,5 @@ | |||
appProductFamily = new Vue({ | |||
el: '#lc-reduction-catalog-edit', | |||
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] | |||
}); |
@@ -24,7 +24,7 @@ group: | |||
addresses: Livraisons & facturation | |||
main: Général | |||
products: Déclinaisons | |||
price: Prix | |||
priceAndUnit: Tarifs / Unités / Quantités | |||
categories: Catégories | |||
unit: Unité & quantité | |||
tax: TVA | |||
@@ -35,6 +35,7 @@ group: | |||
propertySecondary: Caractéristiques secondaires | |||
note: Note interne | |||
parameters: Paramètres | |||
initReduction: Réduction | |||
ReductionCatalog: | |||
info: Informations principal | |||
conditions: Condictions d'application | |||
@@ -130,6 +131,8 @@ field: | |||
subscribeNewsletter: S'inscrire à la newsletter | |||
send: Envoyer | |||
isSent: Envoyée | |||
behaviorTaxRate: Avec ou sans TVA | |||
behaviorTaxRateHelp: Appliquer la réduction sur le prix HT ou le prix TTC | |||
PointSale: | |||
code: Code | |||
codeHelp: Code utilisé pour retrouver l'ambassade dans le tunnel de commande (Non sensible à la casse) | |||
@@ -142,7 +145,9 @@ field: | |||
productsTypeHelp: 'Volume / Pods / Varieté / Parfum ...' | |||
buyingPrice: Prix d'achat | |||
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 | |||
buyingPriceByRefUnit: Prix d'achat / unité de référence | |||
availableQuantity: Quantité disponible | |||
availableQuantityDefault: Quantité disponible par défaut | |||
quantity: Quantité | |||
@@ -177,11 +182,10 @@ field: | |||
behaviorAddToCartOptions: | |||
simple: Simple | |||
multiple: Multiple | |||
activeReductionCatalog: Appliquer une réduction sur ce produit | |||
ReductionCatalog: | |||
fromQuantity: À partir de la quantité | |||
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é | |||
value: Montant ou valeur | |||
permanent: Réduction permanante | |||
@@ -201,6 +205,9 @@ field: | |||
productFamiliesActive: Filtrer sur les produits | |||
productFamilies: Appliquer aux produits | |||
Address: | |||
city: Commune | |||
action: | |||
new: Créer %entity_label% | |||
switchMerchant: Votre hub |
@@ -23,8 +23,8 @@ | |||
{% 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 }}"> | |||
{% verbatim %}{{ {% endverbatim %}{{ fieldDisplay }} {% verbatim %}}}{% endverbatim %}{{ displaySuffix }} | |||
</div> | |||
@@ -35,6 +35,8 @@ | |||
<div v-show="{{ fieldName }}Inherited == true"> | |||
{{ form_widget(field, {'attr' : {'v-model' : fieldName , 'v-on:focusout': fieldName~'Inherited = false', '@change' : fieldName~'Updated'}}) }} | |||
</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> | |||
{% endmacro %} | |||
@@ -70,4 +72,127 @@ | |||
</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 %} |
@@ -0,0 +1 @@ | |||
{{ priceUtils.getPriceWithTax(item) }} |
@@ -4,6 +4,19 @@ | |||
{% include '@LcShop/backend/productfamily/form.html.twig' %} | |||
{% 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 %} | |||
{{ parent() }} | |||
{% include '@LcShop/backend/default/block/script-vuejs.html.twig' %} |
@@ -8,7 +8,7 @@ | |||
<ul class="nav nav-tabs" id="nav-params"> | |||
<li class="nav-item" v-for="section in sectionsArray"> | |||
<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 ')" | |||
@click="changeSection(section)"> | |||
${ section.nameDisplay } | |||
@@ -41,16 +41,22 @@ | |||
{% if formValues.propertyNoveltyExpirationDate %}propertyNoveltyExpirationDateActive: true,{% endif %} | |||
{% if formValues.typeExpirationDate %}typeExpirationDate: "{{ formValues.typeExpirationDate }}",{% endif %} | |||
{% if formValues.behaviorExpirationDate %}behaviorExpirationDate: "{{ formValues.behaviorExpirationDate }}",{% endif %} | |||
{% if formValues.propertyExpirationDate %}propertyExpirationDate: "{{ formValues.propertyExpirationDate|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 = { | |||
{% if formValues.activeProducts %}activeProducts: "{{ formValues.activeProducts }}",{% 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.quantity %}quantity: parseFloat({{ formValues.quantity }}),{% endif %} | |||
{% if formValues.taxRate %}taxRate: parseInt({{ formValues.taxRate.id }}),{% 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.buyingPriceByRefUnit %}buyingPriceByRefUnit: parseFloat({{ formValues.buyingPriceByRefUnit }}).toFixed(3),{% endif %} | |||
{% if formValues.supplierTaxRate %}supplierTaxRate: parseInt({{ formValues.supplierTaxRate.id }}),{% endif %} | |||
{% if form.supplierTaxRate.vars.value != 0 %}differentSupplierTaxRate: true{% endif %} | |||
} | |||
@@ -76,6 +82,10 @@ | |||
{% include '@LcShop/backend/productfamily/panel_property.html.twig' %} | |||
</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 class="row"> |
@@ -14,7 +14,7 @@ | |||
{{ form_row(form.behaviorAddToCart) }} | |||
</div> | |||
<div class="col-12 form-group"> | |||
<div class="col-12 form-group" v-show="activeProducts == true"> | |||
{{ form_label(form.behaviorPrice) }} | |||
{% for field in form.behaviorPrice %} | |||
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorPrice'}}) }} | |||
@@ -22,28 +22,6 @@ | |||
</div> | |||
{{ 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') }} | |||
<div class="col-12"> | |||
{{ form_row(form.taxRate, {'attr': {'v-model':'taxRate'}}) }} | |||
@@ -57,8 +35,31 @@ | |||
{{ 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') }} | |||
@@ -45,14 +45,16 @@ | |||
{{ macros.productField(2, product.priceByRefUnitWithTax, 'priceByRefUnitWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'by-reference-unit\'"') }} | |||
<td colspan="2" v-show="productFamily.behaviorPrice == 'by-reference-unit'"> | |||
{% verbatim %}{{ priceWithTaxValue }}{% endverbatim %}€ | |||
{% verbatim %}{{ finalPriceWithTax }}{% endverbatim %}€ | |||
</td> | |||
{{ 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.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> | |||
<button type="button" class="btn-remove-product btn btn-default" @click="deleteProductForm()"> | |||
@@ -115,7 +117,6 @@ | |||
PV TTC | |||
</th> | |||
<th v-show="behaviorCountStock== 'by-product'"> | |||
Stock | |||
</th> | |||
@@ -139,6 +140,62 @@ | |||
</template> | |||
</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> | |||
<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 | |||
@@ -160,10 +217,13 @@ | |||
{% 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.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.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.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 %}#} | |||
}; | |||
window.formProductTemplate[{{ keyForm }}] = '{{ formMacros.printProductRow(product)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; |
@@ -0,0 +1,21 @@ | |||
{% 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> |
@@ -9,7 +9,7 @@ | |||
{{ form_label(form.behaviorCountStock) }} | |||
{% for field in form.behaviorCountStock %} | |||
{% if field.vars.value == "by-product" %} | |||
<div v-if="isProductsActice() == true"> | |||
<div v-if="activeProducts == true"> | |||
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorCountStock'}}) }} | |||
</div> | |||
{% else %} |
@@ -3,116 +3,10 @@ | |||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||
{% 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"> | |||
{{ 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> | |||
{{ form_end(form) }} |
@@ -2,9 +2,11 @@ | |||
namespace Lc\ShopBundle\Services ; | |||
use App\Entity\OrderProductReductionCatalog; | |||
use App\Entity\OrderShop; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\ShopBundle\Context\MerchantUtilsInterface; | |||
use Lc\ShopBundle\Context\ProductFamilyUtilsInterface; | |||
use Symfony\Component\Security\Core\Security; | |||
class OrderUtils | |||
@@ -14,14 +16,19 @@ class OrderUtils | |||
protected $userUtils; | |||
protected $merchantUtils; | |||
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->security = $security; | |||
$this->userUtils = $userUtils; | |||
$this->merchantUtils = $merchantUtils; | |||
$this->orderShopRepo = $this->em->getRepository(OrderShop::class); | |||
$this->priceUtils = $priceUtils ; | |||
$this->productFamilyUtils = $productFamilyUtils ; | |||
} | |||
public function getOrderShopCurrent() | |||
@@ -84,24 +91,45 @@ class OrderUtils | |||
public function addOrderProduct($orderShop, $orderProductAdd) | |||
{ | |||
if ($orderProductAdd->getQuantity() > 0) { | |||
if ($orderProductAdd->getQuantityOrder() > 0) { | |||
$updated = false; | |||
$orderProductAdd->setTitle($orderProductAdd->getTitleOrderShop()); | |||
$orderProductAdd->setPrice($orderProductAdd->getProduct()->getPriceInherited()); | |||
$orderProductAdd->setPrice($this->priceUtils->getPrice($orderProductAdd->getProduct())); | |||
$orderProductAdd->setUnit($orderProductAdd->getProduct()->getUnitInherited()); | |||
$orderProductAdd->setTaxRate($orderProductAdd->getProduct()->getTaxRateInherited()); | |||
$orderProductAdd->setQuantityProduct($orderProductAdd->getProduct()->getQuantityInherited()); | |||
$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; | |||
$orderProduct->setQuantity($orderProduct->getQuantity() + $orderProductAdd->getQuantity()); | |||
$orderProduct->setQuantityOrder($orderProduct->getQuantityOrder() + $orderProductAdd->getQuantityOrder()); | |||
$this->em->persist($orderProduct); | |||
} | |||
} | |||
if (!$updated) { | |||
$orderShop->addOrderProduct($orderProductAdd); | |||
if(isset($orderProductReductionCatalog)) { | |||
$this->em->persist($orderProductReductionCatalog); | |||
} | |||
$this->em->persist($orderProductAdd); | |||
$this->em->persist($orderShop); | |||
} | |||
@@ -110,6 +138,14 @@ class OrderUtils | |||
} | |||
} | |||
public function compareOrderProductReductionCatalog($orderProductReductionCatalog1, $orderProductReductionCatalog2) | |||
{ | |||
return $orderProductReductionCatalog1 && $orderProductReductionCatalog2 | |||
&& $orderProductReductionCatalog1->getUnit() == $orderProductReductionCatalog2->getUnit() | |||
&& $orderProductReductionCatalog1->getValue() == $orderProductReductionCatalog2->getValue() | |||
&& $orderProductReductionCatalog1->getBehaviorTaxRate() == $orderProductReductionCatalog2->getBehaviorTaxRate() ; | |||
} | |||
public function countQuantities($orderShop) | |||
{ | |||
return $this->countQuantitiesByOrderProducts($orderShop->getOrderProducts()); | |||
@@ -120,29 +156,13 @@ class OrderUtils | |||
$count = 0; | |||
foreach ($orderProducts as $orderProduct) { | |||
$count += $orderProduct->getQuantity(); | |||
$count += $orderProduct->getQuantityOrder(); | |||
} | |||
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 = []; | |||
foreach ($orderShop->getOrderProducts() as $orderProduct) { | |||
@@ -158,18 +178,36 @@ class OrderUtils | |||
return $categoriesArray; | |||
} | |||
public function getDatasSummary($orderShop = null) | |||
public function getOrderDatas($order = null) | |||
{ | |||
if(!$orderShop) { | |||
$orderShop = $this->getOrderShopCurrent() ; | |||
if(!$order) { | |||
$order = $this->getOrderShopCurrent() ; | |||
} | |||
$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 ; | |||
} | |||
public function getSummaryOrderProductReductionCatalog($orderProductReductionCatalog) | |||
{ | |||
$text = '' ; | |||
if($orderProductReductionCatalog) { | |||
if($orderProductReductionCatalog->getUnit() == 'amount') { | |||
$text .= '- '.$orderProductReductionCatalog->getValue().' €' ; | |||
} | |||
if($orderProductReductionCatalog->getUnit() == 'percent') { | |||
$text .= '- '.$orderProductReductionCatalog->getValue().' %' ; | |||
} | |||
} | |||
return $text ; | |||
} | |||
} |
@@ -0,0 +1,242 @@ | |||
<?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); | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
<?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; | |||
} | |||
} | |||
} |