Просмотр исходного кода

Merge branch reduction & master

master
Fab 4 лет назад
Родитель
Сommit
12c756887c
35 измененных файлов: 3151 добавлений и 73 удалений
  1. +8
    -0
      ShopBundle/Context/GroupUserInterface.php
  2. +7
    -0
      ShopBundle/Context/ReductionCartInterface.php
  3. +7
    -0
      ShopBundle/Context/ReductionCatalogInterface.php
  4. +15
    -0
      ShopBundle/Context/ReductionInterface.php
  5. +1
    -0
      ShopBundle/Controller/Admin/AdminController.php
  6. +9
    -1
      ShopBundle/Controller/Admin/ProductFamilyController.php
  7. +2
    -6
      ShopBundle/Form/AddressType.php
  8. +58
    -0
      ShopBundle/Form/ReductionCatalogType.php
  9. +79
    -0
      ShopBundle/Model/GroupUser.php
  10. +42
    -5
      ShopBundle/Model/Merchant.php
  11. +49
    -3
      ShopBundle/Model/PriceTrait.php
  12. +24
    -2
      ShopBundle/Model/ProductFamily.php
  13. +75
    -0
      ShopBundle/Model/ReductionCart.php
  14. +190
    -0
      ShopBundle/Model/ReductionCatalog.php
  15. +115
    -0
      ShopBundle/Model/ReductionTrait.php
  16. +35
    -1
      ShopBundle/Model/User.php
  17. +47
    -38
      ShopBundle/Repository/ProductFamilyRepository.php
  18. +72
    -0
      ShopBundle/Repository/ReductionCatalogRepository.php
  19. +410
    -0
      ShopBundle/Resources/public/css/backend/adminlte/plugins/daterange/daterangepicker.css
  20. +2
    -0
      ShopBundle/Resources/public/css/backend/custom.css
  21. +1565
    -0
      ShopBundle/Resources/public/js/backend/plugin/daterange/daterangepicker.js
  22. +7
    -0
      ShopBundle/Resources/public/js/backend/plugin/daterange/moment.min.js
  23. +56
    -3
      ShopBundle/Resources/public/js/backend/script/default/init-common.js
  24. +8
    -8
      ShopBundle/Resources/public/js/backend/script/default/init-list.js
  25. +30
    -0
      ShopBundle/Resources/public/js/backend/script/reductioncatalog/vuejs-reduction-catalog.js
  26. +30
    -1
      ShopBundle/Resources/translations/lcshop.fr.yaml
  27. +1
    -1
      ShopBundle/Resources/views/backend/default/block/macros.html.twig
  28. +0
    -1
      ShopBundle/Resources/views/backend/default/edit.html.twig
  29. +4
    -1
      ShopBundle/Resources/views/backend/default/layout.html.twig
  30. +1
    -1
      ShopBundle/Resources/views/backend/default/list.html.twig
  31. +0
    -1
      ShopBundle/Resources/views/backend/default/new.html.twig
  32. +5
    -0
      ShopBundle/Resources/views/backend/form/custom_bootstrap_4.html.twig
  33. +56
    -0
      ShopBundle/Resources/views/backend/page/login.html.twig
  34. +23
    -0
      ShopBundle/Resources/views/backend/reductioncatalog/edit.html.twig
  35. +118
    -0
      ShopBundle/Resources/views/backend/reductioncatalog/form.html.twig

+ 8
- 0
ShopBundle/Context/GroupUserInterface.php Просмотреть файл

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

namespace Lc\ShopBundle\Context;

interface GroupUserInterface
{

}

+ 7
- 0
ShopBundle/Context/ReductionCartInterface.php Просмотреть файл

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

namespace Lc\ShopBundle\Context;

interface ReductionCartInterface
{
}

+ 7
- 0
ShopBundle/Context/ReductionCatalogInterface.php Просмотреть файл

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

namespace Lc\ShopBundle\Context;

interface ReductionCatalogInterface
{
}

+ 15
- 0
ShopBundle/Context/ReductionInterface.php Просмотреть файл

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

namespace Lc\ShopBundle\Context;

interface ReductionInterface
{
/**
* Retourne le merchant courant en fonction du user ou du cookie du visitor
*
* @return MerchantInterface
*/
public function getUnit();
public function getValue();
public function getBehaviorTaxRate();
}

+ 1
- 0
ShopBundle/Controller/Admin/AdminController.php Просмотреть файл

@@ -309,6 +309,7 @@ class AdminController extends EasyAdminController
'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;

+ 9
- 1
ShopBundle/Controller/Admin/ProductFamilyController.php Просмотреть файл

@@ -13,6 +13,7 @@ use Lc\ShopBundle\Context\TaxRateInterface;
use Lc\ShopBundle\Context\UnitInterface;
use Lc\ShopBundle\Form\ProductFamilyCategoriesType;
use Lc\ShopBundle\Form\ProductType;
use Lc\ShopBundle\Form\ReductionCatalogType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -36,6 +37,7 @@ class ProductFamilyController extends AdminController
$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,
@@ -159,16 +161,22 @@ class ProductFamilyController extends AdminController
$entity->setUnit($repo->find($unitId));
}

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



$this->processCategories($entity);
$this->processProducts($entity);

/* dump($reductionCatalog);
dump($productFamilyRequest);*/
die();

parent::updateEntity($entity);
}

public function persistEntity($entity)
{

$this->processCategories($entity);
$this->processProducts($entity);


+ 2
- 6
ShopBundle/Form/AddressType.php Просмотреть файл

@@ -16,12 +16,10 @@ use Symfony\Component\Validator\Constraints\NotBlank;
class AddressType extends AbstractType
{
protected $em;
protected $security;

public function __construct(EntityManagerInterface $entityManager, Security $security)
public function __construct(EntityManagerInterface $entityManager)
{
$this->em = $entityManager;
$this->security = $security ;
}

public function buildForm(FormBuilderInterface $builder, array $options)
@@ -61,9 +59,7 @@ class AddressType extends AbstractType
{
$resolver->setDefaults([
'label' => false,
'data_class' => $this->em->getClassMetadata(AddressInterface::class)->getName(),
'createdBy' => $this->security->getUser(),
'updatedBy' => $this->security->getUser(),
'data_class' => $this->em->getClassMetadata(AddressInterface::class)->getName()
]);
}
}

+ 58
- 0
ShopBundle/Form/ReductionCatalogType.php Просмотреть файл

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

namespace Lc\ShopBundle\Form;

use Lc\ShopBundle\Context\ReductionCatalogInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;


class ReductionCatalogType extends AbstractType
{
protected $em;

public function __construct(EntityManagerInterface $entityManager)
{
$this->em = $entityManager;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, ['label' => 'Titre'])
->add('behaviorTaxRate', ChoiceType::class, [
'required'=> true,
'choices' => [
'field.default.taxIncluded'=> 'tax-included',
'field.default.taxExcluded'=> 'tax-excluded'
]
])
->add('unit', ChoiceType::class, [
'required'=> true,
'choices' => [
'field.default.percent'=> 'percent',
'field.default.amount'=> 'amount'
]
])

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

+ 79
- 0
ShopBundle/Model/GroupUser.php Просмотреть файл

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

namespace Lc\ShopBundle\Model;

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


/**
* @ORM\MappedSuperclass()
*/
abstract class GroupUser extends AbstractDocumentEntity implements FilterMerchantInterface
{

/**
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="groupUsers")
* @ORM\JoinColumn(nullable=false)
*/
protected $merchant;

/**
* @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\UserInterface", mappedBy="groupUsers")
*/
protected $users;


public function __toString()
{
return $this->getTitle();
}


public function __construct()
{
$this->users = new ArrayCollection();
}

public function getMerchant(): ?Merchant
{
return $this->merchant;
}

public function setMerchant(?Merchant $merchant): self
{
$this->merchant = $merchant;

return $this;
}

/**
* @return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}

public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
}

return $this;
}

public function removeUser(User $user): self
{
if ($this->users->contains($user)) {
$this->users->removeElement($user);
}

return $this;
}


}

+ 42
- 5
ShopBundle/Model/Merchant.php Просмотреть файл

@@ -2,12 +2,11 @@

namespace Lc\ShopBundle\Model;

use App\Entity\News;
use App\Entity\Newsletter;
use App\Entity\ProductCategory;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Lc\ShopBundle\Context\CreditConfigInterface;
use Lc\ShopBundle\Context\GroupUserInterface;

/**
* @ORM\MappedSuperclass()
@@ -62,6 +61,12 @@ abstract class Merchant extends AbstractDocumentEntity
*/
protected $newsletters;

/**
* @ORM\OneToMany(targetEntity="App\Entity\GroupUser", mappedBy="merchant")
*/
protected $groupUsers;


public function __construct()
{
$this->pointSales = new ArrayCollection();
@@ -69,6 +74,7 @@ abstract class Merchant extends AbstractDocumentEntity
$this->merchantConfigs = new ArrayCollection();
$this->productCategories = new ArrayCollection();
$this->news = new ArrayCollection();
$this->groupUsers = new ArrayCollection();
$this->newsletters = new ArrayCollection();
}

@@ -77,7 +83,7 @@ abstract class Merchant extends AbstractDocumentEntity
return $this->creditConfig;
}

public function setCreditConfig(CreditConfig $creditConfig): self
public function setCreditConfig(CreditConfigInterface $creditConfig): self
{
$this->creditConfig = $creditConfig;

@@ -291,7 +297,7 @@ abstract class Merchant extends AbstractDocumentEntity
return $this;
}

public function removeNewsletter(Newsletter $newsletter): self
public function removeNewsletter(News $newsletter): self
{
if ($this->newsletters->contains($newsletter)) {
$this->newsletters->removeElement($newsletter);
@@ -312,4 +318,35 @@ abstract class Merchant extends AbstractDocumentEntity
}
return false ;
}

/**
* @return Collection|GroupUser[]
*/
public function getGroupUsers(): Collection
{
return $this->groupUsers;
}

public function addGroupUser(GroupUser $groupUser): self
{
if (!$this->groupUsers->contains($groupUser)) {
$this->groupUsers[] = $groupUser;
$groupUser->setMerchant($this);
}

return $this;
}

public function removeGroupUser(GroupUser $groupUser): self
{
if ($this->groupUsers->contains($groupUser)) {
$this->groupUsers->removeElement($groupUser);
// set the owning side to null (unless already changed)
if ($groupUser->getMerchant() === $this) {
$groupUser->setMerchant(null);
}
}

return $this;
}
}

+ 49
- 3
ShopBundle/Model/PriceTrait.php Просмотреть файл

@@ -58,6 +58,39 @@ trait PriceTrait
return $this->calculatePriceByUnitRef($this->getPriceWithTax()) ;
}


public function getPriceWithTaxAndReduction(): ?float
{
if ($this->reductionCatalog) {
return $this->getPriceWithTaxAndReductionCatalog($this->reductionCatalog);
} else {
return null;
}
}

public function getPriceWithTaxAndReductionCatalog(ReductionInterface $reductionCatalog): ?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());
}
}
}

public function setPrice(float $price): self
{
$this->price = $price;
@@ -91,9 +124,22 @@ trait PriceTrait

private function calculatePriceWithTax($priceWithoutTax, $taxRateValue): ?float
{
$price = floatval($priceWithoutTax) * ($taxRateValue/100 + 1) ;
$price = round(( ($price * 100)) / 100, 2) ;
return $price ;
$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)

+ 24
- 2
ShopBundle/Model/ProductFamily.php Просмотреть файл

@@ -14,10 +14,14 @@ use Lc\ShopBundle\Context\ProductPropertyInterface;
/**
* @ORM\MappedSuperclass()
*/

abstract class ProductFamily extends AbstractDocumentEntity implements ProductPropertyInterface, PriceInterface, FilterMerchantInterface
{
use ProductPropertyTrait;

//Champ hydraté par ProductFamilyUtils
protected $reductionCatalog;

/**
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies")
* @ORM\JoinColumn(nullable=false)
@@ -40,7 +44,7 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
protected $productsType;

/**
* @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\ProductInterface", mappedBy="productFamily", orphanRemoval=true, cascade={"persist"})
* @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\ProductInterface", mappedBy="productFamily", orphanRemoval=true, cascade={"persist"}, fetch="EAGER")
*/
protected $products;

@@ -62,7 +66,7 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $warningMessageType;
private $warningMessageType;

/**
* @ORM\Column(type="text", nullable=true)
@@ -150,6 +154,11 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
$this->products = new ArrayCollection();
}

public function __toString()
{
return $this->getTitle();
}

public function getTaxRateInherited()
{
if ($this->getTaxRate()) {
@@ -226,6 +235,17 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
return $this;
}

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

public function setReductionCatalog(?ReductionCatalog $reductionCatalog): self
{
$this->reductionCatalog = $reductionCatalog;

return $this;
}
/**
* @return Collection|ProductCategory[]
*/
@@ -368,6 +388,8 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
}




private function getCheapestOrMostExpensiveProduct($comparisonFunction, $returnSelfIfNotActiveProducts)
{
$products = $this->getProducts()->getValues();

+ 75
- 0
ShopBundle/Model/ReductionCart.php Просмотреть файл

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

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
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\ReductionTrait;

/**
* @ORM\MappedSuperclass()
*/
abstract class ReductionCart extends AbstractDocumentEntity
{
use ReductionTrait;


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

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

/**
* @ORM\Column(type="integer")
*/
protected $priority;



public function getFreeShipping(): ?bool
{
return $this->freeShipping;
}

public function setFreeShipping(?bool $freeShipping): self
{
$this->freeShipping = $freeShipping;

return $this;
}

public function getAppliedTo(): ?string
{
return $this->appliedTo;
}

public function setAppliedTo(string $appliedTo): self
{
$this->appliedTo = $appliedTo;

return $this;
}


public function getPriority(): ?int
{
return $this->priority;
}

public function setPriority(int $priority): self
{
$this->priority = $priority;

return $this;
}


}

+ 190
- 0
ShopBundle/Model/ReductionCatalog.php Просмотреть файл

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

namespace Lc\ShopBundle\Model;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Lc\ShopBundle\Context\FilterMerchantInterface;
use Lc\ShopBundle\Context\ReductionInterface;
use phpDocumentor\Reflection\Types\Integer;

/**
* @ORM\MappedSuperclass()
*/
abstract class ReductionCatalog extends AbstractDocumentEntity implements ReductionInterface, FilterMerchantInterface
{

use ReductionTrait;

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

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

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

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

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

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


public function __construct()
{
$this->productFamilies = new ArrayCollection();
$this->groupUsers = new ArrayCollection();
$this->productCategories = new ArrayCollection();
$this->users = new ArrayCollection();
}

public function getMerchant(): ?Merchant
{
return $this->merchant;
}

public function setMerchant(?Merchant $merchant): self
{
$this->merchant = $merchant;

return $this;
}


/**
* @return Collection|ProductFamily[]
*/
public function getProductFamilies(): Collection
{
return $this->productFamilies;
}

public function addProductFamily(ProductFamily $productFamily): self
{
if (!$this->productFamilies->contains($productFamily)) {
$this->productFamilies[] = $productFamily;
}

return $this;
}

public function removeProductFamily(ProductFamily $productFamily): self
{
if ($this->productFamilies->contains($productFamily)) {
$this->productFamilies->removeElement($productFamily);
}

return $this;
}


/**
* @return Collection|GroupUser[]
*/
public function getGroupUsers(): Collection
{
return $this->groupUsers;
}

public function addGroupUser(GroupUser $groupUser): self
{
if (!$this->groupUsers->contains($groupUser)) {
$this->groupUsers[] = $groupUser;
}

return $this;
}

public function removeGroupUser(GroupUser $groupUser): self
{
if ($this->groupUsers->contains($groupUser)) {
$this->groupUsers->removeElement($groupUser);
}

return $this;
}

/**
* @return Collection|ProductCategory[]
*/
public function getProductCategories(): Collection
{
return $this->productCategories;
}

public function addProductCategory(ProductCategory $productCategory): self
{
if (!$this->productCategories->contains($productCategory)) {
$this->productCategories[] = $productCategory;
}

return $this;
}

public function removeProductCategory(ProductCategory $productCategory): self
{
if ($this->productCategories->contains($productCategory)) {
$this->productCategories->removeElement($productCategory);
}

return $this;
}

/**
* @return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}

public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
}

return $this;
}

public function removeUser(User $user): self
{
if ($this->users->contains($user)) {
$this->users->removeElement($user);
}

return $this;
}

/*public function getFromQuantity(): ?int
{
return $this->fromQuantity;
}

public function setFromQuantity(int $fromQuantity): self
{
$this->fromQuantity = $fromQuantity;

return $this;
}*/

}

+ 115
- 0
ShopBundle/Model/ReductionTrait.php Просмотреть файл

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

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)
*/
protected $value;

/**
* @ORM\Column(type="string", length=20, nullable=true)
*/
protected $unit;

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

public function setValue(?float $value): self
{
$this->value = $value;

return $this;
}

public function getUnit(): ?string
{
return $this->unit;
}

public function setUnit(?string $unit): self
{
$this->unit = $unit;

return $this;
}

public function getBehaviorTaxRate(): ?string
{
return $this->behaviorTaxRate;
}

public function setBehaviorTaxRate(?string $behaviorTaxRate): self
{
$this->behaviorTaxRate = $behaviorTaxRate;

return $this;
}

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

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

return $this;
}

}

+ 35
- 1
ShopBundle/Model/User.php Просмотреть файл

@@ -3,7 +3,6 @@
namespace Lc\ShopBundle\Model;

use App\Entity\Newsletter;
use App\Entity\ProductFamily;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
@@ -71,11 +70,17 @@ abstract class User extends UserModelFOS
*/
protected $newsletters;

/**
* @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\GroupUserInterface", inversedBy="users")
*/
protected $groupUsers;

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


public function __construct()
{
parent::__construct();
@@ -83,6 +88,7 @@ abstract class User extends UserModelFOS
$this->addresses = new ArrayCollection();
$this->orders = new ArrayCollection();
$this->carts = new ArrayCollection();
$this->groupUsers = new ArrayCollection();
$this->newsletters = new ArrayCollection();
$this->favoriteProductFamilies = new ArrayCollection();
}
@@ -315,6 +321,34 @@ abstract class User extends UserModelFOS
return $this;
}

/**
* @return Collection|GroupUser[]
*/
public function getGroupUsers(): Collection
{
return $this->groupUsers;
}

public function addGroupUser(GroupUser $groupUser): self
{
if (!$this->groupUsers->contains($groupUser)) {
$this->groupUsers[] = $groupUser;
$groupUser->addUser($this);
}

return $this;
}

public function removeGroupUser(GroupUser $groupUser): self
{
if ($this->groupUsers->contains($groupUser)) {
$this->groupUsers->removeElement($groupUser);
$groupUser->removeUser($this);
}

return $this;
}

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

+ 47
- 38
ShopBundle/Repository/ProductFamilyRepository.php Просмотреть файл

@@ -4,6 +4,7 @@ namespace Lc\ShopBundle\Repository;

use Lc\ShopBundle\Context\DefaultRepositoryInterface;
use Lc\ShopBundle\Context\ProductFamilyInterface;
use Lc\ShopBundle\Context\ReductionCatalogInterface;

/**
* @method ProductFamilyInterface|null find($id, $lockMode = null, $lockVersion = null)
@@ -18,57 +19,65 @@ class ProductFamilyRepository extends BaseRepository implements DefaultRepositor
return ProductFamilyInterface::class;
}

public function findNovelties()
{

public function getProductFamiliesByCategory($category){
$expr = $this->_em->getExpressionBuilder();

$query = $this->findByMerchantQuery() ;
$query->andWhere(':now <= e.propertyNoveltyExpirationDate')
->setParameter('now', new \DateTime()) ;
/* $query->select(array('e as product', 'reductionCatalog as reduction'));
$query->from(ReductionCatalogInterface::class, 'reductionCatalog');*/
$query->andWhere(':category MEMBER OF e.productCategories');
$query->andWhere('e.status = 1');
/* /* $query->andWhere($query->expr()->orX(
$query->expr()->eq('reductionCatalog', 'null'),
$query->expr()->eq( 'reductionCatalog.status = 1 AND (
:user MEMBER OF reductionCatalog.users OR reductionCatalog.users is empty ) AND
(:groupUser MEMBER OF reductionCatalog.groupUsers OR reductionCatalog.groupUsers is empty ) AND
(e MEMBER OF reductionCatalog.productFamilies OR reductionCatalog.productFamilies is empty')
));


$query
->andWhere('reductionCatalog.status = 1')
->andWhere(':user MEMBER OF reductionCatalog.users OR reductionCatalog.users is empty')
->andWhere(':groupUser MEMBER OF reductionCatalog.groupUsers OR reductionCatalog.groupUsers is empty')
->andWhere('e MEMBER OF reductionCatalog.productFamilies OR reductionCatalog.productFamilies is empty')
//->andWhere(':category MEMBER OF reductionCatalog.productCategories OR reductionCatalog.productCategories is empty')
//->andWhere('e.supplier MEMBER OF reductionCatalog.suppliers OR reductionCatalog.suppliers is empty')
->setParameter('user', $user)
->setParameter('groupUser', $user->getGroupUsers()
);*/

$query->setParameter('category', $category->getId());

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

public function findNoveltiesByParentCategories()
{
return $this->productsByParentCategories($this->findNovelties()) ;
}

public function findOrganics()
{
public function getProductFamiliesNovelties(){
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.propertyOrganicLabel IS NOT NULL');
$query->andWhere('e.status = 1');
$query->andWhere(':now <= e.propertyNoveltyExpirationDate')
->setParameter('now', new \DateTime()) ;

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

public function findOrganicsByParentCategories()
{
return $this->productsByParentCategories($this->findOrganics()) ;
}
public function getProductFamiliesLargeVolumes(){
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.status = 1');
$query->andWhere('e.propertyLargeVolume = 1');

public function productsByParentCategories($products)
{
$categoriesArray = [] ;
foreach($products as $product) {
$productCategories = $product->getProductCategories() ;
$category = $productCategories[0]->getParentCategory() ;
if(!isset($categoriesArray[$category->getId()])) {
$categoriesArray[$category->getId()] = [
'category' => $category,
'products' => []
] ;
}
$categoriesArray[$category->getId()]['products'][] = $product ;
}

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

public function findByTerms($terms, $maxResults = false)
{
public function getProductFamiliesOrganics(){
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.title LIKE :terms');
$query->setParameter('terms', '%'.$terms.'%') ;
if($maxResults) {
$query->setMaxResults($maxResults) ;
}
$query->andWhere('e.status = 1');
$query->andWhere('e.propertyOrganicLabel IS NOT NULL');

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


}

+ 72
- 0
ShopBundle/Repository/ReductionCatalogRepository.php Просмотреть файл

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

namespace Lc\ShopBundle\Repository;

use Lc\ShopBundle\Context\DefaultRepositoryInterface;
use Lc\ShopBundle\Context\ReductionCatalogInterface;
use Symfony\Component\Validator\Constraints\DateTime;

/**
* @method ReductionCatalogInterface|null find($id, $lockMode = null, $lockVersion = null)
* @method ReductionCatalogInterface|null findOneBy(array $criteria, array $orderBy = null)
* @method ReductionCatalogInterface[] findAll()
* @method ReductionCatalogInterface[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ReductionCatalogRepository extends BaseRepository implements DefaultRepositoryInterface
{
public function getInterfaceClass()
{
return ReductionCatalogInterface::class;
}


public function getReductionCatalogByProductFamily($productFamily, $user)
{

$query = $this->findByMerchantQuery();
$query->andWhere('e.status = 1');
$query->andWhere(':user MEMBER OF e.users OR e.users is empty');
$query->andWhere(':groupUser MEMBER OF e.groupUsers OR e.groupUsers is empty');
$query->andWhere(':productFamily MEMBER OF e.productFamilies OR e.productFamilies is empty');
$query->andWhere(':productCategory MEMBER OF e.productCategories OR e.productCategories is empty');
$query->andWhere(':supplier MEMBER OF e.suppliers OR e.suppliers is empty');
$query->setParameter('user', $user);
$query->setParameter('groupUser', $user->getGroupUsers());
$query->setParameter('productFamily', $productFamily);
$query->setParameter('productCategory', $productFamily->getProductCategories());
$query->setParameter('supplier', $productFamily->getSupplier());


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


}


public function getReductionCatalogByProductFamilyConditions($productFamilyIds, $user)
{
dump($user);

$query = $this->findByMerchantQuery();
$query->andWhere('e.status = 1');
$query->andWhere('e.permanent = 1 OR (e.dateStart <= :now AND e.dateEnd >= :now)');
if($user){
$query->andWhere(':user MEMBER OF e.users OR e.users is empty');
$query->andWhere(':groupUser MEMBER OF e.groupUsers OR e.groupUsers is empty');
$query->setParameter('user', $user);
$query->setParameter('groupUser', $user->getGroupUsers());
}

$query->andWhere(':productFamily MEMBER OF e.productFamilies OR e.productFamilies is empty');
$query->andWhere(':productCategory MEMBER OF e.productCategories OR e.productCategories is empty');
$query->andWhere(':supplier MEMBER OF e.suppliers OR e.suppliers is empty');
$query->setParameter('productFamily', $productFamilyIds['ids']);
$query->setParameter('productCategory', $productFamilyIds['categories']);
$query->setParameter('supplier', $productFamilyIds['suppliers']);
$query->setParameter(':now', new \DateTime());

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


}
}

+ 410
- 0
ShopBundle/Resources/public/css/backend/adminlte/plugins/daterange/daterangepicker.css Просмотреть файл

@@ -0,0 +1,410 @@
.daterangepicker {
position: absolute;
color: inherit;
background-color: #fff;
border-radius: 4px;
border: 1px solid #ddd;
width: 278px;
max-width: none;
padding: 0;
margin-top: 7px;
top: 100px;
left: 20px;
z-index: 3001;
display: none;
font-family: arial;
font-size: 15px;
line-height: 1em;
}
.daterangepicker:before, .daterangepicker:after {
position: absolute;
display: inline-block;
border-bottom-color: rgba(0, 0, 0, 0.2);
content: '';
}
.daterangepicker:before {
top: -7px;
border-right: 7px solid transparent;
border-left: 7px solid transparent;
border-bottom: 7px solid #ccc;
}
.daterangepicker:after {
top: -6px;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-left: 6px solid transparent;
}
.daterangepicker.opensleft:before {
right: 9px;
}
.daterangepicker.opensleft:after {
right: 10px;
}
.daterangepicker.openscenter:before {
left: 0;
right: 0;
width: 0;
margin-left: auto;
margin-right: auto;
}
.daterangepicker.openscenter:after {
left: 0;
right: 0;
width: 0;
margin-left: auto;
margin-right: auto;
}
.daterangepicker.opensright:before {
left: 9px;
}
.daterangepicker.opensright:after {
left: 10px;
}
.daterangepicker.drop-up {
margin-top: -7px;
}
.daterangepicker.drop-up:before {
top: initial;
bottom: -7px;
border-bottom: initial;
border-top: 7px solid #ccc;
}
.daterangepicker.drop-up:after {
top: initial;
bottom: -6px;
border-bottom: initial;
border-top: 6px solid #fff;
}
.daterangepicker.single .daterangepicker .ranges, .daterangepicker.single .drp-calendar {
float: none;
}
.daterangepicker.single .drp-selected {
display: none;
}
.daterangepicker.show-calendar .drp-calendar {
display: block;
}
.daterangepicker.show-calendar .drp-buttons {
display: block;
}
.daterangepicker.auto-apply .drp-buttons {
display: none;
}
.daterangepicker .drp-calendar {
display: none;
max-width: 270px;
}
.daterangepicker .drp-calendar.left {
padding: 8px 0 8px 8px;
}
.daterangepicker .drp-calendar.right {
padding: 8px;
}
.daterangepicker .drp-calendar.single .calendar-table {
border: none;
}
.daterangepicker .calendar-table .next span, .daterangepicker .calendar-table .prev span {
color: #fff;
border: solid black;
border-width: 0 2px 2px 0;
border-radius: 0;
display: inline-block;
padding: 3px;
}
.daterangepicker .calendar-table .next span {
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.daterangepicker .calendar-table .prev span {
transform: rotate(135deg);
-webkit-transform: rotate(135deg);
}
.daterangepicker .calendar-table th, .daterangepicker .calendar-table td {
white-space: nowrap;
text-align: center;
vertical-align: middle;
min-width: 32px;
width: 32px;
height: 24px;
line-height: 24px;
font-size: 12px;
border-radius: 4px;
border: 1px solid transparent;
white-space: nowrap;
cursor: pointer;
}
.daterangepicker .calendar-table {
border: 1px solid #fff;
border-radius: 4px;
background-color: #fff;
}
.daterangepicker .calendar-table table {
width: 100%;
margin: 0;
border-spacing: 0;
border-collapse: collapse;
}
.daterangepicker td.available:hover, .daterangepicker th.available:hover {
background-color: #eee;
border-color: transparent;
color: inherit;
}
.daterangepicker td.week, .daterangepicker th.week {
font-size: 80%;
color: #ccc;
}
.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date {
background-color: #fff;
border-color: transparent;
color: #999;
}
.daterangepicker td.in-range {
background-color: #ebf4f8;
border-color: transparent;
color: #000;
border-radius: 0;
}
.daterangepicker td.start-date {
border-radius: 4px 0 0 4px;
}
.daterangepicker td.end-date {
border-radius: 0 4px 4px 0;
}
.daterangepicker td.start-date.end-date {
border-radius: 4px;
}
.daterangepicker td.active, .daterangepicker td.active:hover {
background-color: #357ebd;
border-color: transparent;
color: #fff;
}
.daterangepicker th.month {
width: auto;
}
.daterangepicker td.disabled, .daterangepicker option.disabled {
color: #999;
cursor: not-allowed;
text-decoration: line-through;
}
.daterangepicker select.monthselect, .daterangepicker select.yearselect {
font-size: 12px;
padding: 1px;
height: auto;
margin: 0;
cursor: default;
}
.daterangepicker select.monthselect {
margin-right: 2%;
width: 56%;
}
.daterangepicker select.yearselect {
width: 40%;
}
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect {
width: 50px;
margin: 0 auto;
background: #eee;
border: 1px solid #eee;
padding: 2px;
outline: 0;
font-size: 12px;
}
.daterangepicker .calendar-time {
text-align: center;
margin: 4px auto 0 auto;
line-height: 30px;
position: relative;
}
.daterangepicker .calendar-time select.disabled {
color: #ccc;
cursor: not-allowed;
}
.daterangepicker .drp-buttons {
clear: both;
text-align: right;
padding: 8px;
border-top: 1px solid #ddd;
display: none;
line-height: 12px;
vertical-align: middle;
}
.daterangepicker .drp-selected {
display: inline-block;
font-size: 12px;
padding-right: 8px;
}
.daterangepicker .drp-buttons .btn {
margin-left: 8px;
font-size: 12px;
font-weight: bold;
padding: 4px 8px;
}
.daterangepicker.show-ranges.single.rtl .drp-calendar.left {
border-right: 1px solid #ddd;
}
.daterangepicker.show-ranges.single.ltr .drp-calendar.left {
border-left: 1px solid #ddd;
}
.daterangepicker.show-ranges.rtl .drp-calendar.right {
border-right: 1px solid #ddd;
}
.daterangepicker.show-ranges.ltr .drp-calendar.left {
border-left: 1px solid #ddd;
}
.daterangepicker .ranges {
float: none;
text-align: left;
margin: 0;
}
.daterangepicker.show-calendar .ranges {
margin-top: 8px;
}
.daterangepicker .ranges ul {
list-style: none;
margin: 0 auto;
padding: 0;
width: 100%;
}
.daterangepicker .ranges li {
font-size: 12px;
padding: 8px 12px;
cursor: pointer;
}
.daterangepicker .ranges li:hover {
background-color: #eee;
}
.daterangepicker .ranges li.active {
background-color: #08c;
color: #fff;
}
/* Larger Screen Styling */
@media (min-width: 564px) {
.daterangepicker {
width: auto;
}
.daterangepicker .ranges ul {
width: 140px;
}
.daterangepicker.single .ranges ul {
width: 100%;
}
.daterangepicker.single .drp-calendar.left {
clear: none;
}
.daterangepicker.single .ranges, .daterangepicker.single .drp-calendar {
float: left;
}
.daterangepicker {
direction: ltr;
text-align: left;
}
.daterangepicker .drp-calendar.left {
clear: left;
margin-right: 0;
}
.daterangepicker .drp-calendar.left .calendar-table {
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.daterangepicker .drp-calendar.right {
margin-left: 0;
}
.daterangepicker .drp-calendar.right .calendar-table {
border-left: none;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.daterangepicker .drp-calendar.left .calendar-table {
padding-right: 8px;
}
.daterangepicker .ranges, .daterangepicker .drp-calendar {
float: left;
}
}
@media (min-width: 730px) {
.daterangepicker .ranges {
width: auto;
}
.daterangepicker .ranges {
float: left;
}
.daterangepicker.rtl .ranges {
float: right;
}
.daterangepicker .drp-calendar.left {
clear: none !important;
}
}

+ 2
- 0
ShopBundle/Resources/public/css/backend/custom.css Просмотреть файл

@@ -25,6 +25,8 @@ td.actions{white-space: nowrap; text-align: right;}
table th input{width: auto}
table th .select2-container--default .select2-selection--single{padding:0.3rem 0.4rem; }

/************************ LOGIN PAGE *********************/
.login-logo{display: block; margin: auto;}
/************************ form error *********************/

.form-sent .form-control:invalid{border-color: #dc3545; padding-right: 2.25rem; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat: no-repeat;background-position: center right calc(.375em + .1875rem); background-size: calc(.75em + .375rem) calc(.75em + .375rem);}

+ 1565
- 0
ShopBundle/Resources/public/js/backend/plugin/daterange/daterangepicker.js
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 7
- 0
ShopBundle/Resources/public/js/backend/plugin/daterange/moment.min.js
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 56
- 3
ShopBundle/Resources/public/js/backend/script/default/init-common.js Просмотреть файл

@@ -18,7 +18,7 @@ function initLcNoty() {


function custom_switch_merchants() {
$('#switch-merchant').on('change',function () {
$('#switch-merchant').on('change', function () {
$('#switch-merchant').parents('form').submit();
});
}
@@ -48,7 +48,7 @@ function initAdminLtePlugin() {
}*/
});
$('form button[type="submit"]').on('click', function (e) {
log('EVENT CLICK:');
checkForm()
})

@@ -79,8 +79,61 @@ function initAdminLtePlugin() {
}
});


$('.date-time-range').each(function (i, picker) {
//log(moment('2020-04-05 20:00:00').format( "DD/MM/YYYY HH:mm"))
options = {
timePicker: true,
timePickerIncrement: 30,
timePicker24Hour: true,
locale: {
"format": "DD/MM/YYYY HH:mm",
"separator": " - ",
"applyLabel": "Appliquer",
"cancelLabel": "Annuler",
"fromLabel": "Du",
"toLabel": "au",
"customRangeLabel": "Custom",
"daysOfWeek": ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"],
"monthNames": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Decembre"],
"firstDay": 1
}
};

if($(picker).nextAll('.date-time-range-fields').find('.date-start').val()){
options.startDate = new Date($(picker).nextAll('.date-time-range-fields').find('.date-start').val());
}
if($(picker).nextAll('.date-time-range-fields').find('.date-end').val()){
options.endDate = new Date($(picker).nextAll('.date-time-range-fields').find('.date-end').val());
}
$(picker).daterangepicker(options);
$(picker).on('apply.daterangepicker', function(ev, pickerElm) {
$(picker).nextAll('.date-time-range-fields').find('.date-start').val(pickerElm.startDate.format('YYYY-MM-DD HH:mm'));
$(picker).nextAll('.date-time-range-fields').find('.date-end').val(pickerElm.endDate.format('YYYY-MM-DD HH:mm'));
});
});


}

function moment() {
return '2020-04-08';
}


function checkForm(){
$('form').addClass('form-sent');
//Panel vues js
if($('form').find('.panel').length){
$('form').find('.panel').each(function(i, panel){
if($(panel).find(':invalid').length){
$('#nav-params').find('.nav-item:eq('+i+')').addClass('has-invalid');
}else{
$('#nav-params').find('.nav-item:eq('+i+')').removeClass('has-invalid');
}
})
}
}

function setSelect2($select) {
if (typeof $select.data('select2-id') === 'undefined') {
@@ -94,7 +147,7 @@ function setSelect2($select) {
};

if ($select.data('allow-clear') == 'false') {
options.allowClear= false;
options.allowClear = false;
}
if ($select.data('width')) {
options.width = 'auto'

+ 8
- 8
ShopBundle/Resources/public/js/backend/script/default/init-list.js Просмотреть файл

@@ -1,15 +1,16 @@
jQuery(document).ready(function () {

initDeleteAction();

initDataTable();

});


});

function initDeleteAction() {

$('.action-delete').each(function (){
log($(this));
$(this).on('click', function (e) {
e.preventDefault();
log('ncnecd')
@@ -36,14 +37,14 @@ function initDataTable() {
if ($(this).data('searchable') == "input") {
var title = $(this).text();
var cssClass = '';
if($(this).text().trim().toLowerCase() =='id')cssClass = 'small'
$(this).html('<input type="text" placeholder="" class="datatable-field-search '+cssClass+'" />');
if ($(this).text().trim().toLowerCase() == 'id') cssClass = 'small'
$(this).html('<input type="text" placeholder="" class="datatable-field-search ' + cssClass + '" />');

$('input', this).on('keyup change', function () {
if(this.value === "") {
if (this.value === "") {
$('.table.datatable-simple thead tr:eq(0) th:eq(' + i + ')').removeClass('filtered')
}else{
$('.table.datatable-simple thead tr:eq(0) th:eq('+i+')').addClass('filtered')
} else {
$('.table.datatable-simple thead tr:eq(0) th:eq(' + i + ')').addClass('filtered')
}
if (table.column(i).search() !== this.value) {
table
@@ -68,7 +69,6 @@ function initDataTable() {

var table = $(".table.datatable-simple").DataTable({
orderCellsTop: true,
order: [[$('th.sorted').data('index'), 'asc']],
fixedHeader: {
header: true,
headerOffset: $('.main-header').outerHeight(),

+ 30
- 0
ShopBundle/Resources/public/js/backend/script/reductioncatalog/vuejs-reduction-catalog.js Просмотреть файл

@@ -0,0 +1,30 @@


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: {

}
});

+ 30
- 1
ShopBundle/Resources/translations/lcshop.fr.yaml Просмотреть файл

@@ -34,6 +34,10 @@ group:
propertyMain: Caractéristiques principales
propertySecondary: Caractéristiques secondaires
note: Note interne
ReductionCatalog:
info: Informations principal
conditions: Condictions d'application

None: Aucune valeur
label.form.empty_value: Choisissez une option
form.label.delete: Supprimer l'image
@@ -116,6 +120,10 @@ field:
taxRate: Règle de taxe
value: Valeur
behaviorAddToCart: Ajout au panier
taxIncluded: TVA incluse
taxExcluded: TVA exclue
percent: Pourcentage
amount: Montant
madame: Madame
monsieur: Monsieur
subscribeNewsletter: S'inscrire à la newsletter
@@ -126,7 +134,6 @@ field:
codeHelp: Code utilisé pour retrouver l'ambassade dans le tunnel de commande (Non sensible à la casse)
Supplier:
user: Utilisateur lié

ProductFamily:
taxRateInherited: Utiliser la TVA par défaut
activeProducts: Activer les déclinaisons
@@ -169,7 +176,29 @@ field:
behaviorAddToCartOptions:
simple: Simple
multiple: Multiple
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
dateRange: Date de but et date de fin
usersActive: Filtrer sur les utilisateurs
users: Appliquer aux utilisateurs

groupUsersActive: Filtrer sur les groupes d'utilisateurs
groupUsers: Appliquer aux groupes d'utilisateurs

suppliersActive: Filtrer sur les producteurs
suppliers: Appliquer aux producteurs

productCategoriesActive: Filtrer sur les catégories
productCategories: Appliquer aux catégories

productFamiliesActive: Filtrer sur les produits
productFamilies: Appliquer aux produits

action:
new: Créer %entity_label%

+ 1
- 1
ShopBundle/Resources/views/backend/default/block/macros.html.twig Просмотреть файл

@@ -10,7 +10,7 @@
<div class="card-body {{ fullWidth == true ? 'p-0' : 'row' }}">

{% endmacro %}
v
{% macro endCard(noCol = false) %}
</div>
</div>

+ 0
- 1
ShopBundle/Resources/views/backend/default/edit.html.twig Просмотреть файл

@@ -9,7 +9,6 @@
{% extends _entity_config.templates.layout %}

{% block body_id 'easyadmin-edit-' ~ _entity_config.name ~ '-' ~ _entity_id %}
{% block body_class 'edit edit-' ~ _entity_config.name|lower %}

{% block content_title %}
{% apply spaceless %}

+ 4
- 1
ShopBundle/Resources/views/backend/default/layout.html.twig Просмотреть файл

@@ -52,7 +52,7 @@
</head>

{% block body %}
<body class="layout-navbar-fixed sidebar-mini">
<body class="{% block body_class %}layout-navbar-fixed sidebar-mini{% endblock %}">
{# <script>
document.body.classList.add(
'easyadmin-content-width-' + (localStorage.getItem('easyadmin/content/width') || 'normal'),
@@ -120,6 +120,9 @@
{% endif %}
{% endif %}
</li>
<li>
<a target="_blank" class="btn btn-outline-success" href="{{ path('frontend_home') }}">Afficher le site</a>
</li>
</ul>
{% endblock navbar %}
</nav>

+ 1
- 1
ShopBundle/Resources/views/backend/default/list.html.twig Просмотреть файл

@@ -27,7 +27,7 @@
{% set _has_filters = _entity_config.list.filters|default(false) %}

{% block body_id 'easyadmin-list-' ~ _entity_config.name %}
{% block body_class 'list list-' ~ _entity_config.name|lower %}

{% block content_title %}
{% apply spaceless %}

+ 0
- 1
ShopBundle/Resources/views/backend/default/new.html.twig Просмотреть файл

@@ -7,7 +7,6 @@
{% extends _entity_config.templates.layout %}

{% block body_id 'easyadmin-new-' ~ _entity_config.name %}
{% block body_class 'new new-' ~ _entity_config.name|lower %}

{% block content_title %}
{% apply spaceless %}

+ 5
- 0
ShopBundle/Resources/views/backend/form/custom_bootstrap_4.html.twig Просмотреть файл

@@ -205,3 +205,8 @@
</div>
{% endspaceless %}
{% endblock %}

{% block niche %}
NCICICICI
{{ form_widget(form) }}
{% endblock %}

+ 56
- 0
ShopBundle/Resources/views/backend/page/login.html.twig Просмотреть файл

@@ -0,0 +1,56 @@
{% trans_default_domain easyadmin_config('translation_domain') %}
{% extends easyadmin_config('design.templates.layout') %}

{% block body_class 'login-page' %}

{% block wrapper_wrapper %}
{% set _username_label = username_label is defined ? username_label|trans : 'login.username'|trans({}, 'EasyAdminBundle') %}
{% set _password_label = password_label is defined ? password_label|trans : 'login.password'|trans({}, 'EasyAdminBundle') %}
{% set _sign_in_label = sign_in_label is defined ? sign_in_label|trans : 'login.sign_in'|trans({}, 'EasyAdminBundle') %}

<div class="login-box">

{% block header_logo %}
<a class="login-logo {{ easyadmin_config('site_name')|length > 14 ? 'logo-long' }}" title="{{ easyadmin_config('site_name')|striptags }}" href="{{ path('easyadmin') }}">
{{ easyadmin_config('site_name')|raw }}
</a>
{% endblock header_logo %}


{% if error|default(false) %}
<div class="w-100 alert alert-danger">
{{ error.messageKey|trans(error.messageData, 'security') }}
</div>
{% endif %}

<section class="content">
<form method="post" action="{{ action|default('') }}">
{% if csrf_token_intention|default(false) %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token(csrf_token_intention) }}">
{% endif %}

<input type="hidden" name="{{ target_path_parameter|default('_target_path') }}" value="{{ target_path|default(path('easyadmin')) }}" />

<div class="form-group field-text">
<label for="username" class="sr-only form-control-label required">{{ _username_label }}</label>
<div class="form-widget form-widget-with-icon">
<i class="fa fa-fw fa-user"></i>
<input type="text" id="username" name="{{ username_parameter|default('_username') }}" class="form-control" placeholder="{{ _username_label }}" value="{{ last_username|default('') }}" required autofocus>
</div>
</div>

<div class="form-group field-password">
<label for="password" class="sr-only form-control-label required">{{ _password_label }}</label>
<div class="form-widget form-widget-with-icon">
<i class="fa fa-fw fa-lock"></i>
<input type="password" id="password" name="{{ password_parameter|default('_password') }}" class="form-control" placeholder="{{ _password_label }}" required>
</div>
</div>

<div class="form-group field-button">
<button type="submit" class="btn btn-primary btn-lg btn-block" onclick="this.form.submit(); this.disabled=true;">{{ _sign_in_label }}</button>
</div>
</form>
</section>
</div>
{% endblock %}

+ 23
- 0
ShopBundle/Resources/views/backend/reductioncatalog/edit.html.twig Просмотреть файл

@@ -0,0 +1,23 @@
{% extends app.request.query.get('action') == 'edit' ? '@LcShop/backend/default/edit.html.twig' : '@LcShop/backend/default/new.html.twig' %}

{% block entity_form %}
{% include '@LcShop/backend/reductioncatalog/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' %}
<script src="{{ asset('bundles/lcshop/js/backend/script/reductioncatalog/vuejs-reduction-catalog.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/script/productfamily/init-edit.js') }}"></script>#}
{% endblock %}

+ 118
- 0
ShopBundle/Resources/views/backend/reductioncatalog/form.html.twig Просмотреть файл

@@ -0,0 +1,118 @@
{{ form_start(form) }}

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

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

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

</div>
{{ form_end(form) }}

Загрузка…
Отмена
Сохранить