@@ -89,7 +89,6 @@ class AdminController extends EasyAdminController | |||
protected function commonQueryFilter($entityClass, $queryBuilder) | |||
{ | |||
if (new $entityClass instanceof FilterMultipleMerchantsInterface) { | |||
$queryBuilder->andWhere(':currentMerchant MEMBER OF entity.merchants') | |||
->setParameter(':currentMerchant', $this->getUser()->getMerchant()->getId()); | |||
@@ -276,27 +275,42 @@ class AdminController extends EasyAdminController | |||
); | |||
} | |||
// @TODO : À passer dans le controller de App | |||
$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']); | |||
if (in_array('Lc\ShopBundle\Context\FilterMerchantInterface', $classImplements)) { | |||
$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' => '--', | |||
'query_builder' => function (EntityRepository $repo) use ($passedOptions, $propertyMerchant) { | |||
'translation_domain'=> 'lcshop', | |||
'query_builder' => function (EntityRepository $repo) use ($passedOptions, $propertyMerchant, $statusInterface, $treeInterface, $child) { | |||
$queryBuilder = $repo->createQueryBuilder('e'); | |||
$propertyMerchant = 'e.' . $propertyMerchant; | |||
@@ -306,9 +320,23 @@ class AdminController extends EasyAdminController | |||
$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'], | |||
) | |||
); |
@@ -255,15 +255,11 @@ class ProductFamilyController extends AdminController | |||
$this->dispatch(EasyAdminEvents::POST_EDIT); | |||
$productCategoryRepository = $this->getDoctrine()->getRepository(ProductCategoryInterface::class); | |||
$categories = $productCategoryRepository->findAllParents(); | |||
$parameters = [ | |||
'form' => $editForm->createView(), | |||
'entity_fields' => $fields, | |||
'entity' => $entity, | |||
'delete_form' => $deleteForm->createView(), | |||
'categories' => $categories, | |||
'sortableProductsField' => $sortableProductsField | |||
]; | |||
@@ -55,9 +55,8 @@ class EditEventSubscriber implements EventSubscriberInterface | |||
} | |||
public function updateCommonProperty(GenericEvent $event){ | |||
dump($event); | |||
public function updateCommonProperty(GenericEvent $event) | |||
{ | |||
/* $this->setUpdated($entity); | |||
$this->setAddressCreatedBy($entity) ;*/ | |||
} |
@@ -15,6 +15,7 @@ use Symfony\Component\Form\FormEvent; | |||
use Symfony\Component\Form\FormEvents; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
use Symfony\Component\Security\Core\Security; | |||
use Vich\UploaderBundle\Form\Type\VichImageType; | |||
class MerchantConfigType extends AbstractType | |||
{ | |||
@@ -48,7 +49,7 @@ class MerchantConfigType extends AbstractType | |||
]); | |||
} | |||
elseif($merchantConfig->getFieldType() == 'image') { | |||
$form->add('value', CKFinderFileChooserType::class, [ | |||
$form->add('imageFile', VichImageType::class, [ | |||
'label' => $merchantConfig->getLabel(), | |||
]); | |||
} |
@@ -26,7 +26,7 @@ class ProductFamilyCategoriesType extends AbstractType | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
$categories = $this->productCategoryRepository->findAllParents(); | |||
$categories = $this->productCategoryRepository->findAllParents(true); | |||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($categories) { | |||
$builder = $event->getForm(); | |||
@@ -34,7 +34,7 @@ class ProductFamilyCategoriesType extends AbstractType | |||
foreach ($categories as $category) { | |||
$builder->add('category_' . $category->getId(), CheckboxType::class, [ | |||
'label' => $category->getTitle(), | |||
'label' => $category->getStatus() == 0 ? $category->getTitle() .' (hors ligne)': $category->getTitle() , | |||
'data' => $currentProductCategories->contains($category), | |||
'required' => false, | |||
'disabled'=>true, | |||
@@ -42,11 +42,12 @@ class ProductFamilyCategoriesType extends AbstractType | |||
'class'=>'none' | |||
] | |||
]); | |||
foreach ($category->getChildrens() as $children) { | |||
$childrenCategories = $this->productCategoryRepository->findAllByParent($category, true); | |||
foreach ($childrenCategories as $children) { | |||
$builder->add('category_children_' . $children->getId(), CheckboxType::class, [ | |||
'label' => $children->getTitle(), | |||
'label' => $children->getStatus() == 0 ? $children->getTitle() .' (hors ligne)': $children->getTitle() , | |||
'data' => $currentProductCategories->contains($children), | |||
'required' => false, | |||
'required' => false | |||
]); | |||
} | |||
} |
@@ -7,7 +7,6 @@ use Gedmo\Mapping\Annotation as Gedmo; | |||
use Lc\ShopBundle\Context\SluggableInterface; | |||
use Lc\ShopBundle\Context\SortableInterface; | |||
use Lc\ShopBundle\Context\StatusInterface; | |||
use Lc\ShopBundle\Model\AbstractEntity; | |||
use Symfony\Component\HttpFoundation\File\File; | |||
use Vich\UploaderBundle\Mapping\Annotation as Vich; | |||
@@ -3,11 +3,14 @@ | |||
namespace Lc\ShopBundle\Model; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Symfony\Component\HttpFoundation\File\File; | |||
use Vich\UploaderBundle\Mapping\Annotation as Vich; | |||
/** | |||
* @ORM\MappedSuperclass() | |||
* @Vich\Uploadable | |||
*/ | |||
abstract class MerchantConfig | |||
abstract class MerchantConfig extends AbstractEntity | |||
{ | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="merchantConfigs") | |||
@@ -25,6 +28,12 @@ abstract class MerchantConfig | |||
*/ | |||
protected $value; | |||
/** | |||
* @Vich\UploadableField(mapping="images", fileNameProperty="value") | |||
* @var File | |||
*/ | |||
protected $imageFile; | |||
public static $availableOptions = [] ; | |||
public function getMerchant(): ?Merchant | |||
@@ -63,6 +72,24 @@ abstract class MerchantConfig | |||
return $this; | |||
} | |||
public function setImageFile(File $image = null) | |||
{ | |||
$this->imageFile = $image; | |||
// VERY IMPORTANT: | |||
// It is required that at least one field changes if you are using Doctrine, | |||
// otherwise the event listeners won't be called and the file is lost | |||
if ($image) { | |||
// if 'updatedAt' is not defined in your entity, use another property | |||
$this->updatedAt = new \DateTime('now'); | |||
} | |||
} | |||
public function getImageFile() | |||
{ | |||
return $this->imageFile; | |||
} | |||
public static function getAvailableOptions(): array | |||
{ | |||
return static::$availableOptions ; |
@@ -19,6 +19,8 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
{ | |||
use ProductPropertyTrait; | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies") | |||
* @ORM\JoinColumn(nullable=false) | |||
@@ -30,6 +32,11 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
*/ | |||
protected $productCategories; | |||
/** | |||
* @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\ReductionCatalogInterface", mappedBy="reductionCatalogs") | |||
*/ | |||
protected $reductionCatalogs; | |||
/** | |||
* @ORM\Column(type="boolean") | |||
*/ | |||
@@ -120,6 +127,10 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
*/ | |||
protected $behaviorAddToCart; | |||
//Champ hydraté par ProductFamilyUtils | |||
public $reductionCatalog; | |||
public function __construct() | |||
{ | |||
$this->productCategories = new ArrayCollection(); | |||
@@ -208,6 +219,37 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this; | |||
} | |||
/** | |||
* @return Collection|ReductionCatalog[] | |||
*/ | |||
public function getReductionCatalogs(): Collection | |||
{ | |||
return $this->reductionCatalogs; | |||
} | |||
public function initReductionCatalogs() | |||
{ | |||
$this->reductionCatalogs = new ArrayCollection(); | |||
} | |||
public function addReductionCatalog(ReductionCatalog $reductionCatalog): self | |||
{ | |||
if (!$this->reductionCatalogs->contains($reductionCatalog)) { | |||
$this->reductionCatalogs[] = $reductionCatalog; | |||
} | |||
return $this; | |||
} | |||
public function removeReductionCatalog(ReductionCatalog $reductionCatalog): self | |||
{ | |||
if ($this->reductionCatalogs->contains($reductionCatalog)) { | |||
$this->reductionCatalogs->removeElement($reductionCatalog); | |||
} | |||
return $this; | |||
} | |||
/** | |||
* @return Collection|ProductCategory[] | |||
*/ |
@@ -5,18 +5,26 @@ 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 | |||
abstract class ReductionCatalog extends AbstractDocumentEntity implements ReductionInterface, FilterMerchantInterface | |||
{ | |||
use ReductionTrait; | |||
/** | |||
* @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface") | |||
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies") | |||
* @ORM\JoinColumn(nullable=false) | |||
*/ | |||
protected $merchant; | |||
/** | |||
* @ORM\ManyToMany(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface", inversedBy="reductionCatalogs") | |||
*/ | |||
protected $productFamilies; | |||
@@ -35,6 +43,11 @@ abstract class ReductionCatalog extends AbstractDocumentEntity implements Reduct | |||
*/ | |||
protected $users; | |||
/** | |||
* @ORM\Column(type="smallint") | |||
*/ | |||
protected $fromQuantity = 1; | |||
public function __construct() | |||
{ | |||
@@ -44,6 +57,18 @@ abstract class ReductionCatalog extends AbstractDocumentEntity implements Reduct | |||
$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[] | |||
@@ -150,5 +175,16 @@ abstract class ReductionCatalog extends AbstractDocumentEntity implements Reduct | |||
return $this; | |||
} | |||
public function getFromQuantity(): ?int | |||
{ | |||
return $this->fromQuantity; | |||
} | |||
public function setFromQuantity(int $fromQuantity): self | |||
{ | |||
$this->fromQuantity = $fromQuantity; | |||
return $this; | |||
} | |||
} |
@@ -28,6 +28,11 @@ trait ReductionTrait | |||
*/ | |||
protected $unit; | |||
/** | |||
* @ORM\Column(type="string", length=20, nullable=true) | |||
*/ | |||
protected $behaviorTaxRate; | |||
public function getDateStart(): ?\DateTimeInterface | |||
{ | |||
@@ -77,5 +82,17 @@ trait ReductionTrait | |||
return $this; | |||
} | |||
public function getBehaviorTaxRate(): ?string | |||
{ | |||
return $this->behaviorTaxRate; | |||
} | |||
public function setBehaviorTaxRate(?string $behaviorTaxRate): self | |||
{ | |||
$this->behaviorTaxRate = $behaviorTaxRate; | |||
return $this; | |||
} | |||
} |
@@ -28,23 +28,29 @@ class ProductCategoryRepository extends BaseRepository implements DefaultReposit | |||
->orderBy('e.position', 'ASC'); | |||
} | |||
public function findAllParents() | |||
public function findAllParents($withOffline = false) | |||
{ | |||
$query = $this->findByMerchantQuery() | |||
->andWhere('e.parent is NULL') | |||
->andWhere('e.parent is NULL'); | |||
->andWhere('e.status = 1') | |||
->orderBy('e.position', 'ASC'); | |||
if ($withOffline) $query->andWhere('e.status >= 0'); | |||
else $query->andWhere('e.status = 1'); | |||
$query->orderBy('e.position', 'ASC'); | |||
return $query->getQuery()->getResult(); | |||
} | |||
public function findAllByParent($parentCategory) | |||
public function findAllByParent($parentCategory, $withOffline = false) | |||
{ | |||
$query = $this->createQueryBuilder('e') ; | |||
$query->andWhere('e.parent = :idParentCategory') | |||
->setParameter('idParentCategory', $parentCategory->getId()); | |||
return $query->getQuery()->getResult() ; | |||
$query = $this->createQueryBuilder('e'); | |||
$query->andWhere('e.parent = :idParentCategory'); | |||
if ($withOffline) $query->andWhere('e.status >= 0'); | |||
else $query->andWhere('e.status = 1'); | |||
$query->setParameter('idParentCategory', $parentCategory->getId()); | |||
return $query->getQuery()->getResult(); | |||
} | |||
} |
@@ -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,11 +19,61 @@ class ProductFamilyRepository extends BaseRepository implements DefaultRepositor | |||
return ProductFamilyInterface::class; | |||
} | |||
public function findNovelties() | |||
{ | |||
public function getProductFamiliesByCategory($category){ | |||
$expr = $this->_em->getExpressionBuilder(); | |||
$query = $this->findByMerchantQuery() ; | |||
/* $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 getProductFamiliesByNovelties(){ | |||
$query = $this->findByMerchantQuery() ; | |||
$query->andWhere('e.status = 1'); | |||
$query->andWhere(':now <= e.propertyNoveltyExpirationDate') | |||
->setParameter('now', new \DateTime()) ; | |||
return $query->getQuery()->getResult() ; | |||
} | |||
/**************************** OLD *********************************/ | |||
public function findNovelties() | |||
{ | |||
$query = $this->findByMerchantQuery() ; | |||
return $query->getQuery()->getResult() ; | |||
} | |||
@@ -18,4 +18,49 @@ class ReductionCatalogRepository extends BaseRepository implements DefaultReposi | |||
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) | |||
{ | |||
$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', $productFamilyIds['ids']); | |||
$query->setParameter('productCategory', $productFamilyIds['categories']); | |||
$query->setParameter('supplier', $productFamilyIds['suppliers']); | |||
return $query->getQuery()->getResult(); | |||
} | |||
} |
@@ -1,4 +1,5 @@ | |||
/* STRUCTURE */ | |||
body{font-size: 0.9rem;} | |||
[class*="sidebar-dark-"] .nav-sidebar > .nav-item.menu-open , [class*="sidebar-dark-"] .nav-sidebar > .nav-item:hover {background:rgba(255,255,255,.1); } | |||
.main-sidebar .logo-long{padding: 8px 0; text-align: center;} | |||
@@ -20,6 +21,10 @@ td.actions{white-space: nowrap; text-align: right;} | |||
.table td, .table th{padding: 0.35rem;} | |||
.delivery-field .form-group{display: inline-block; margin-bottom: 0px; margin-right: 15px;} | |||
.delivery-field .form-group .form-control{width: 150px;} | |||
table th input{width: auto} | |||
table th .select2-container--default .select2-selection--single{padding:0.3rem 0.4rem; } | |||
/************************ 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);} | |||
@@ -61,6 +66,9 @@ td.actions{white-space: nowrap; text-align: right;} | |||
.product-categories .parent .form-group.field-checkbox .form-check-label{padding-left: 0px; font-style: italic;} | |||
.product-categories .children .form-group.field-checkbox{margin-left: 20px} | |||
.product-categories .form-group{margin-bottom: 0.5rem;} | |||
.lc-deleted-field{display: none;} | |||
.lc-offline-field{opacity: 0.5} | |||
.lc-offline-field label::after{content:' [hors ligne]'} | |||
/* Général */ |
@@ -41,18 +41,21 @@ function initAdminLtePlugin() { | |||
}*/ | |||
}); | |||
$('form button[type="submit"]').on('click', function (e) { | |||
log('EVENT CLICK:'); | |||
checkForm() | |||
}) | |||
if ($('.select2, select.form-control').length) { | |||
$('form .form-widget>select.form-control, .select2').each(function (i, elm) { | |||
setSelect2($(elm)) | |||
if(!$(this).hasClass('disable-select2')) { | |||
setSelect2($(elm)) ; | |||
} | |||
}); | |||
$('form .form-inline>select.form-control').each(function (i, elm) { | |||
setSelect2($(elm)) | |||
if(!$(this).hasClass('disable-select2')) { | |||
setSelect2($(elm)) ; | |||
} | |||
}); | |||
} | |||
@@ -77,7 +80,7 @@ function initAdminLtePlugin() { | |||
timePickerIncrement: 30, | |||
timePicker24Hour: true, | |||
locale: { | |||
"format": "MM/DD/YYYY HH:mm", | |||
"format": "DD/MM/YYYY HH:mm", | |||
"separator": " - ", | |||
"applyLabel": "Appliquer", | |||
"cancelLabel": "Cancel", | |||
@@ -111,9 +114,9 @@ function initAdminLtePlugin() { | |||
} | |||
}); | |||
$(picker).on('apply.daterangepicker', function(ev, picker) { | |||
picker.startDate.format('YYYY-MM-DD HH:mm'); | |||
console.log(picker.endDate.format('YYYY-MM-DD')); | |||
$(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')); | |||
}); | |||
}); | |||
@@ -124,6 +127,21 @@ 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') { | |||
@@ -1,68 +1,19 @@ | |||
jQuery(document).ready(function () { | |||
initLcCkEditor(); | |||
initCkFinder(); | |||
//generateNotice('error', 'Ceci est une notice'); | |||
}); | |||
function checkForm(){ | |||
$('form').addClass('form-sent'); | |||
//Panel vues js | |||
if($('form').find('.panel').length){ | |||
log('here'); | |||
$('form').find('.panel').each(function(i, panel){ | |||
log(i); | |||
log($(panel).find(':invalid').length); | |||
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 initCkFinder(){ | |||
$('.lc-ckfinder-wrap').each(function(){ | |||
$widget = $(this); | |||
if($widget.find('.lc-ckfinder-field').val() !== ''){ | |||
$widget.find('.lc-ckfinder-illu').css('background-image', "url('"+$widget.find('.lc-ckfinder-field').val()+"')"); | |||
$widget.find('.lc-ckfinder-remove').show(); | |||
} | |||
$widget.find('.lc-ckfinder-button').on( 'click', function( e ) { | |||
e.preventDefault(); | |||
CKFinder.popup( { | |||
chooseFiles: true, | |||
onInit: function( finder ) { | |||
finder.on( 'files:choose', function( evt ) { | |||
var file = evt.data.files.first(); | |||
$widget.find('.lc-ckfinder-illu').css('background-image', "url('"+file.getUrl()+"')"); | |||
$widget.find('.lc-ckfinder-remove').show(); | |||
$widget.find('.lc-ckfinder-field').val(file.getUrl()); | |||
} ); | |||
finder.on( 'file:choose:resizedImage', function( evt ) { | |||
var output = document.getElementById( '{{ id }}' ); | |||
output.value = evt.data.resizedUrl; | |||
} ); | |||
} | |||
} ); | |||
} ); | |||
$widget.find('.lc-ckfinder-remove').on('click', function () { | |||
$widget.find('.lc-ckfinder-remove').hide(); | |||
$widget.find('.lc-ckfinder-illu').css('background-image', 'none'); | |||
$widget.find('.lc-ckfinder-field').val(""); | |||
}) | |||
$('.action-delete').on('click', function(e) { | |||
e.preventDefault(); | |||
const id = $(this).parents('tr').first().data('id'); | |||
$('#modal-delete').modal({ backdrop: true, keyboard: true }) | |||
.off('click', '#modal-delete-button') | |||
.on('click', '#modal-delete-button', function () { | |||
let deleteForm = $('#delete-form'); | |||
deleteForm.attr('action', deleteForm.attr('action').replace('__id__', id)); | |||
deleteForm.trigger('submit'); | |||
}); | |||
}); | |||
if ($('.field-ckfinder_file_chooser').length > 0) { | |||
CKFinder.config({connectorPath: '/ckfinder/connector'}); | |||
} | |||
} | |||
}); | |||
/* CKEditor */ | |||
@@ -84,7 +35,6 @@ function initLcCkEditor(){ | |||
], | |||
"language": "fr" | |||
}); | |||
CKFinder.setupCKEditor(editor); | |||
} | |||
} | |||
} |
@@ -1,20 +1,33 @@ | |||
jQuery(document).ready(function () { | |||
initDeleteAction(); | |||
initDataTable(); | |||
//generateNotice('error', 'Ceci est une notice'); | |||
$('a.action-delete').on('click', function(e) { | |||
e.preventDefault(); | |||
$('#modal-delete').modal({ backdrop: true, keyboard: true }) | |||
.off('click', '#modal-delete-button') | |||
.on('click', '#modal-delete-button', function () { | |||
$('#delete-form').trigger('submit'); | |||
}); | |||
}); | |||
}); | |||
function initDeleteAction() { | |||
$('.action-delete').each(function (){ | |||
log($(this)); | |||
$(this).on('click', function (e) { | |||
e.preventDefault(); | |||
log('ncnecd') | |||
const id = $(this).parents('tr').first().data('id'); | |||
$('#modal-delete').modal({backdrop: true, keyboard: true}) | |||
.off('click', '#modal-delete-button') | |||
.on('click', '#modal-delete-button', function () { | |||
let deleteForm = $('#delete-form'); | |||
deleteForm.attr('action', deleteForm.attr('action').replace('__id__', id)); | |||
deleteForm.trigger('submit'); | |||
}); | |||
}); | |||
}); | |||
} | |||
function initDataTable() { | |||
if ($(".table.datatable-simple").length > 0) { | |||
//$(".table.datatable-simple thead tr").clone(true).appendTo( '.table.datatable-simple tfoot' ); | |||
@@ -24,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 | |||
@@ -39,13 +52,13 @@ function initDataTable() { | |||
.search(this.value) | |||
.draw(); | |||
var searchVal = this.value; | |||
var body = $( table.table().body() ); | |||
var body = $(table.table().body()); | |||
body.unhighlight(); | |||
body.highlight(searchVal); | |||
} | |||
}); | |||
} else if ($(this).data('searchable') == 'select' ){ | |||
} else if ($(this).data('searchable') == 'select') { | |||
$(this).html('<select data-allow-clear="false" class="list"><option value="all">Tout afficher</option></select>'); //LC_TRAD | |||
} else if ($(this).data('searchable') == 'select-text') { | |||
$(this).html('<select data-allow-clear="false" class="list-text"><option value="all">Tout afficher</option></select>'); //LC_TRAD | |||
@@ -63,23 +76,23 @@ function initDataTable() { | |||
paging: true, | |||
//responsive: true, | |||
initComplete: function () { | |||
this.api().columns().every( function (i) { | |||
this.api().columns().every(function (i) { | |||
var column = this; | |||
var select = false; | |||
if($('.table.datatable-simple thead tr:eq(1) th:eq('+i+') select.list-text').length) { | |||
if ($('.table.datatable-simple thead tr:eq(1) th:eq(' + i + ') select.list-text').length) { | |||
select = $('.table.datatable-simple thead tr:eq(1) th:eq(' + i + ') select.list-text'); | |||
} | |||
if(select.length) { | |||
if (select.length) { | |||
column.data().unique().sort().each(function (d, j) { | |||
values = d.split('\n'); | |||
for(k=0; k< values.length; k++) { | |||
for (k = 0; k < values.length; k++) { | |||
val = values[k]; | |||
select.append('<option value="' + val.trim() + '">' + val.trim() + '</option>') | |||
} | |||
}); | |||
} | |||
if(!select) select = $('.table.datatable-simple thead tr:eq(1) th:eq('+i+') select.list') | |||
if(select.length) { | |||
if (!select) select = $('.table.datatable-simple thead tr:eq(1) th:eq(' + i + ') select.list') | |||
if (select.length) { | |||
column.data().unique().sort().each(function (d, j) { | |||
$(d).each(function (k, val) { | |||
@@ -87,40 +100,40 @@ function initDataTable() { | |||
}); | |||
}); | |||
setSelect2(select); | |||
select.on( 'change', function () { | |||
select.on('change', function () { | |||
var val = $(this).val(); | |||
if(val=="all"){ | |||
$('.table.datatable-simple thead tr:eq(0) th:eq('+i+')').removeClass('filtered') | |||
if (val == "all") { | |||
$('.table.datatable-simple thead tr:eq(0) th:eq(' + i + ')').removeClass('filtered') | |||
column.search('').draw(); | |||
}else { | |||
} else { | |||
log($(this).val()); | |||
$('.table.datatable-simple thead tr:eq(0) th:eq('+i+')').addClass('filtered') | |||
$('.table.datatable-simple thead tr:eq(0) th:eq(' + i + ')').addClass('filtered') | |||
column.search(val, false).draw(); | |||
} | |||
} ); | |||
}); | |||
} | |||
} ); | |||
}); | |||
}, | |||
language: { | |||
"sEmptyTable": "Aucune donnée disponible dans le tableau", | |||
"sInfo": "Affichage de l'élément _START_ à _END_ sur _TOTAL_ éléments", | |||
"sInfoEmpty": "Affichage de l'élément 0 à 0 sur 0 élément", | |||
"sInfoFiltered": "(filtré à partir de _MAX_ éléments au total)", | |||
"sInfoPostFix": "", | |||
"sInfoThousands": ",", | |||
"sLengthMenu": "Afficher _MENU_ éléments", | |||
"sEmptyTable": "Aucune donnée disponible dans le tableau", | |||
"sInfo": "Affichage de l'élément _START_ à _END_ sur _TOTAL_ éléments", | |||
"sInfoEmpty": "Affichage de l'élément 0 à 0 sur 0 élément", | |||
"sInfoFiltered": "(filtré à partir de _MAX_ éléments au total)", | |||
"sInfoPostFix": "", | |||
"sInfoThousands": ",", | |||
"sLengthMenu": "Afficher _MENU_ éléments", | |||
"sLoadingRecords": "Chargement...", | |||
"sProcessing": "Traitement...", | |||
"sSearch": "Rechercher :", | |||
"sZeroRecords": "Aucun élément correspondant trouvé", | |||
"sProcessing": "Traitement...", | |||
"sSearch": "Rechercher :", | |||
"sZeroRecords": "Aucun élément correspondant trouvé", | |||
"oPaginate": { | |||
"sFirst": "Premier", | |||
"sLast": "Dernier", | |||
"sNext": "Suivant", | |||
"sFirst": "Premier", | |||
"sLast": "Dernier", | |||
"sNext": "Suivant", | |||
"sPrevious": "Précédent" | |||
}, | |||
"oAria": { | |||
"sSortAscending": ": activer pour trier la colonne par ordre croissant", | |||
"sSortAscending": ": activer pour trier la colonne par ordre croissant", | |||
"sSortDescending": ": activer pour trier la colonne par ordre décroissant" | |||
}, | |||
"select": { |
@@ -0,0 +1,30 @@ | |||
appProductFamily = new Vue({ | |||
el: '#lc-reduction-catalog-edit', | |||
delimiters: ['${', '}'], | |||
computed: { | |||
}, | |||
data() { | |||
return Object.assign( | |||
{ | |||
dateActive: true, | |||
usersActive: true, | |||
groupUsersActive: true, | |||
suppliersActive: true, | |||
productCategoriesActive: true, | |||
productFamiliesActive:true | |||
}, window.appReductionCatalogValues); | |||
}, | |||
mounted: function () { | |||
}, | |||
methods: { | |||
}, | |||
watch: { | |||
} | |||
}); |
@@ -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 | |||
@@ -67,7 +71,7 @@ field: | |||
company: Société | |||
siret: N° SIRET | |||
tva: N° TVA | |||
price: Prix de vente | |||
price: Prix | |||
priceWithTax: Prix de vente TTC | |||
username: Nom d'utilisateur | |||
email: E-mail | |||
@@ -115,7 +119,11 @@ field: | |||
merchantConfigs: Configuration | |||
taxRate: Règle de taxe | |||
value: Valeur | |||
behaviorAddToCart: Ajout au panier | |||
taxIncluded: TVA incluse | |||
taxExcluded: TVA exclue | |||
percent: Pourcentage | |||
amount: Montant | |||
ProductFamily: | |||
taxRateInherited: Utiliser la TVA par défaut | |||
activeProducts: Activer les déclinaisons | |||
@@ -147,6 +155,32 @@ field: | |||
product: Par déclinaisons | |||
taxRate: TVA | |||
unit: Unité | |||
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 | |||
usersActive: Appliquer la réduction à tout les utilisateurs | |||
users: Appliquer aux utilisateurs | |||
groupUsersActive: Appliquer la réduction à tout les groupes d'utilisateurs | |||
groupUsers: Appliquer aux groupes d'utilisateurs | |||
suppliersActive: Appliquer la réduction à tout les producteurs | |||
suppliers: Appliquer aux producteurs | |||
productCategoriesActive: Appliquer la réduction à toutes les catégories | |||
productCategories: Appliquer aux catégories | |||
productFamiliesActive: Appliquer la réduction à tout les produits | |||
productFamilies: Appliquer aux produits | |||
action: | |||
new: Créer %entity_label% | |||
switchMerchant: Votre hub |
@@ -43,17 +43,11 @@ | |||
{{ macros.startCard(0, 'ProductFamily.categories','light') }} | |||
<div class="col-12 product-categories"> | |||
{% for category in categories %} | |||
{% set child = 'category_' ~ category.id %} | |||
<div class="parent"> | |||
{{ form_row(attribute(form.productCategories, child)) }} | |||
</div> | |||
{% for children in category.childrens %} | |||
<div class="children"> | |||
{% set child = 'category_children_' ~ children.id %} | |||
{{ form_row(attribute(form.productCategories, child), {attrs: {class: 'test'}}) }} | |||
</div> | |||
{% endfor %} | |||
{% for category in form.productCategories %} | |||
<div class="field {{ category.vars.disabled ? 'parent' }}"> | |||
{{ form_row(category) }} | |||
</div> | |||
{% endfor %} | |||
</div> |
@@ -18,6 +18,6 @@ | |||
{% block script_javascript %} | |||
{{ parent() }} | |||
{% include '@LcShop/backend/default/block/script-vuejs.html.twig' %} | |||
{#<script src="{{ asset('bundles/lcshop/js/backend/script/reductioncatalog/vuejs-product-family.js') }}"></script> | |||
<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 %} |
@@ -3,13 +3,29 @@ | |||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||
{% set formValues = form.vars.value %} | |||
<script> | |||
window.appReductionCatalogValues = { | |||
{% if formValues.users is not empty %}usersActive: false,{% endif %} | |||
{% if formValues.groupUsers is not empty %}groupUsersActive: false,{% endif %} | |||
{% if formValues.productFamilies is not empty %}productFamiliesActive: false,{% endif %} | |||
{% if formValues.productCategories is not empty %}productCategoriesActive: false,{% endif %} | |||
{% if formValues.suppliers is not empty %}suppliersActive: false,{% endif %} | |||
} | |||
</script> | |||
<div id="lc-reduction-catalog-edit" class="row"> | |||
{{ macros.startCard(6, 'Reduction.info.','light') }} | |||
{{ 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> | |||
@@ -22,35 +38,77 @@ | |||
{{ macros.endCard() }} | |||
{{ macros.startCard(6, 'Reduction.conditions.','light') }} | |||
{{ macros.startCard(6, 'ReductionCatalog.conditions','secondary') }} | |||
<div class="col-12"> | |||
<div class="form-group"> | |||
<label>Date time</label> | |||
<div class="input-group"> | |||
<div class="form-group"> | |||
{{ form_widget(form.dateActive, {"attr" : {'v-model' : 'dateActive' } }) }} | |||
</div> | |||
<div class="input-group" v-show="dateActive == 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" id="reservationtime"> | |||
<div class="hidden" style="display: none;"> | |||
{{ form_row(form.dateStart, {"attr" : {'class' : 'date-start'}}) }} | |||
{{ form_row(form.dateEnd, {"attr" : {'class' : 'date-end'}}) }} | |||
<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"> | |||
{{ form_row(form.users) }} | |||
<div class="form-group"> | |||
<div class="form-group"> | |||
{{ form_widget(form.usersActive, {"attr" : {'v-model' : 'usersActive' } }) }} | |||
</div> | |||
<div v-show="usersActive == false"> | |||
{{ form_row(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 == false"> | |||
{{ form_widget(form.groupUsers) }} | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.groupUsers) }} | |||
<div class="form-group"> | |||
<div class="form-group"> | |||
{{ form_widget(form.suppliersActive, {"attr" : {'v-model' : 'suppliersActive' } }) }} | |||
</div> | |||
<div class="form-widget" v-show="suppliersActive == false"> | |||
{{ form_widget(form.suppliers) }} | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.productFamilies) }} | |||
<div class="form-group"> | |||
<div class="form-group"> | |||
{{ form_widget(form.productCategoriesActive, {"attr" : {'v-model' : 'productCategoriesActive' } }) }} | |||
</div> | |||
<div class="form-widget" v-show="productCategoriesActive == false"> | |||
{{ form_widget(form.productCategories) }} | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.productCategories) }} | |||
<div class="form-group"> | |||
<div class="form-group"> | |||
{{ form_widget(form.productFamiliesActive, {"attr" : {'v-model' : 'productFamiliesActive' } }) }} | |||
</div> | |||
<div class="form-widget" v-show="productFamiliesActive == false"> | |||
{{ form_widget(form.productFamilies) }} | |||
</div> | |||
</div> | |||
</div> | |||
{{ macros.endCard() }} | |||
</div> |
@@ -70,14 +70,16 @@ class FrontendTwigExtension extends AbstractExtension | |||
if (substr($path, 0, 1) === '/') $path = substr($path, 1); | |||
if ($path) { | |||
if (strpos($path, $this->getFileManagerFolder()) === false) { | |||
$path = $this->getFileManagerFolder() . '/' . $path; | |||
$fileManagerFolder = substr($this->getFileManagerFolder(), 1) ; | |||
if (strpos($path, $fileManagerFolder) === false) { | |||
$path = $fileManagerFolder . '/' . $path; | |||
} | |||
return $this->liipCacheHelper->getBrowserPath($path, $thumb); | |||
} else { | |||
return $this->liipCacheHelper->getBrowserPath('assets/img/frontend/' . $default, $thumb); | |||
return $this->liipCacheHelper->getBrowserPath($this->getFileManagerFolder() . '/' . $default, $thumb); | |||
} | |||
} | |||