Sfoglia il codice sorgente

Merge branch 'develop'

master
Guillaume 4 anni fa
parent
commit
1054d4bb5c
77 ha cambiato i file con 3263 aggiunte e 1210 eliminazioni
  1. +183
    -12
      ShopBundle/Controller/Backend/AdminController.php
  2. +7
    -3
      ShopBundle/Controller/Backend/NewsController.php
  3. +141
    -77
      ShopBundle/Controller/Backend/ProductFamilyController.php
  4. +28
    -0
      ShopBundle/Controller/Backend/TicketController.php
  5. +25
    -0
      ShopBundle/Controller/Backend/UserController.php
  6. +4
    -2
      ShopBundle/Controller/Frontend/CartController.php
  7. +2
    -0
      ShopBundle/EventSubscriber/ListEventSubscriber.php
  8. +4
    -1
      ShopBundle/Form/Backend/Common/AddressType.php
  9. +137
    -0
      ShopBundle/Form/Backend/Filters/ListFilterType.php
  10. +1
    -0
      ShopBundle/Form/Backend/ProductFamily/ProductType.php
  11. +8
    -0
      ShopBundle/Form/Backend/ReductionCommon/UsersFilterType.php
  12. +14
    -0
      ShopBundle/Model/CreditHistory.php
  13. +1
    -1
      ShopBundle/Model/Document.php
  14. +1
    -1
      ShopBundle/Model/PriceTrait.php
  15. +3
    -1
      ShopBundle/Model/Product.php
  16. +14
    -0
      ShopBundle/Model/ProductCategory.php
  17. +21
    -4
      ShopBundle/Model/ProductFamily.php
  18. +1
    -0
      ShopBundle/Model/Ticket.php
  19. +6
    -1
      ShopBundle/Model/User.php
  20. +17
    -0
      ShopBundle/Model/UserMerchant.php
  21. +11
    -0
      ShopBundle/Repository/BaseRepository.php
  22. +28
    -19
      ShopBundle/Repository/OrderShopRepository.php
  23. +9
    -0
      ShopBundle/Repository/ProductCategoryRepository.php
  24. +8
    -0
      ShopBundle/Repository/ProductFamilyRepository.php
  25. +13
    -0
      ShopBundle/Repository/UserRepository.php
  26. +1
    -6
      ShopBundle/Resources/config/easy_admin/base.yaml
  27. +2
    -2
      ShopBundle/Resources/public/css/backend/adminlte/adminlte.css
  28. +8
    -0
      ShopBundle/Resources/public/css/backend/adminlte/plugins/select2/select2-bootstrap.min.css
  29. +220
    -109
      ShopBundle/Resources/public/css/backend/custom.css
  30. +1
    -0
      ShopBundle/Resources/public/js/backend/plugin/autocomplete/bootstrap-autocomplete.min.js
  31. +2
    -0
      ShopBundle/Resources/public/js/backend/plugin/select2/select2.full.min.js
  32. +37
    -20
      ShopBundle/Resources/public/js/backend/script/default/init-common.js
  33. +36
    -14
      ShopBundle/Resources/public/js/backend/script/default/init-edit.js
  34. +202
    -0
      ShopBundle/Resources/public/js/backend/script/default/init-list-datatable.js
  35. +34
    -173
      ShopBundle/Resources/public/js/backend/script/default/init-list.js
  36. +10
    -1
      ShopBundle/Resources/public/js/backend/script/default/utils.js
  37. +21
    -3
      ShopBundle/Resources/public/js/backend/script/default/vuejs-mixins.js
  38. +0
    -23
      ShopBundle/Resources/public/js/backend/script/productfamily/init-edit.js
  39. +557
    -449
      ShopBundle/Resources/public/js/backend/script/productfamily/vuejs-product-family.js
  40. +2
    -2
      ShopBundle/Resources/public/sass/backend/adminlte/_table.scss
  41. +41
    -9
      ShopBundle/Resources/public/sass/backend/custom.scss
  42. +23
    -5
      ShopBundle/Resources/translations/lcshop.fr.yaml
  43. +0
    -6
      ShopBundle/Resources/views/backend/default/action.html.twig
  44. +13
    -0
      ShopBundle/Resources/views/backend/default/block/action.html.twig
  45. +58
    -0
      ShopBundle/Resources/views/backend/default/block/actions.html.twig
  46. +1
    -1
      ShopBundle/Resources/views/backend/default/block/embed_modal.twig
  47. +2
    -0
      ShopBundle/Resources/views/backend/default/block/form_address.html.twig
  48. +6
    -1
      ShopBundle/Resources/views/backend/default/block/list_tickets.html.twig
  49. +21
    -2
      ShopBundle/Resources/views/backend/default/block/macros.html.twig
  50. +8
    -1
      ShopBundle/Resources/views/backend/default/edit.html.twig
  51. +6
    -3
      ShopBundle/Resources/views/backend/default/layout/layout.html.twig
  52. +288
    -0
      ShopBundle/Resources/views/backend/default/list-datatable.html.twig
  53. +56
    -16
      ShopBundle/Resources/views/backend/default/list-fields/field_product_family_available_quantity.html.twig
  54. +11
    -0
      ShopBundle/Resources/views/backend/default/list-fields/field_ticket_last_message.html.twig
  55. +8
    -1
      ShopBundle/Resources/views/backend/default/list-fields/field_toggle.html.twig
  56. +314
    -161
      ShopBundle/Resources/views/backend/default/list.html.twig
  57. +4
    -0
      ShopBundle/Resources/views/backend/default/new.html.twig
  58. +3
    -2
      ShopBundle/Resources/views/backend/form/ckeditor_widget.html.twig
  59. +7
    -8
      ShopBundle/Resources/views/backend/form/custom_bootstrap_4.html.twig
  60. +316
    -0
      ShopBundle/Resources/views/backend/productfamily/advanced_edition.html.twig
  61. +0
    -1
      ShopBundle/Resources/views/backend/productfamily/edit.html.twig
  62. +4
    -2
      ShopBundle/Resources/views/backend/productfamily/form.html.twig
  63. +44
    -12
      ShopBundle/Resources/views/backend/productfamily/macros.html.twig
  64. +3
    -0
      ShopBundle/Resources/views/backend/productfamily/panel_general.html.twig
  65. +1
    -1
      ShopBundle/Resources/views/backend/productfamily/panel_price.html.twig
  66. +25
    -25
      ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig
  67. +7
    -0
      ShopBundle/Resources/views/backend/productfamily/panel_stock.html.twig
  68. +6
    -9
      ShopBundle/Services/CreditUtils.php
  69. +59
    -1
      ShopBundle/Services/MerchantUtils.php
  70. +30
    -6
      ShopBundle/Services/Order/OrderUtils.php
  71. +5
    -1
      ShopBundle/Services/Order/OrderUtilsCartTrait.php
  72. +15
    -1
      ShopBundle/Services/Order/OrderUtilsStockTrait.php
  73. +4
    -0
      ShopBundle/Services/Price/ProductPriceUtils.php
  74. +1
    -1
      ShopBundle/Services/ProductFamilyUtils.php
  75. +32
    -3
      ShopBundle/Services/TicketUtils.php
  76. +4
    -2
      ShopBundle/Services/Utils.php
  77. +17
    -5
      ShopBundle/Twig/FrontendTwigExtension.php

+ 183
- 12
ShopBundle/Controller/Backend/AdminController.php Vedi File

@@ -9,14 +9,12 @@ use EasyCorp\Bundle\EasyAdminBundle\Event\EasyAdminEvents;
use FOS\UserBundle\Model\UserManagerInterface;
use Lc\ShopBundle\Context\FilterMultipleMerchantsInterface;
use Lc\ShopBundle\Context\MerchantInterface;
use Lc\ShopBundle\Context\MerchantUtilsInterface;
use Lc\ShopBundle\Context\OrderUtilsInterface;
use Lc\ShopBundle\Context\ReminderInterface;
use Lc\ShopBundle\Context\SeoInterface;
use Lc\ShopBundle\Context\StatusInterface;
use Lc\ShopBundle\Context\TreeInterface;
use Lc\ShopBundle\Form\Backend\Common\AbstractEditPositionType;
use Lc\ShopBundle\Services\Utils;
use Lc\ShopBundle\Form\Backend\Filters\ListFilterType;
use Lc\ShopBundle\Services\UtilsManager;
use Mailjet\MailjetSwiftMailer\SwiftMailer\MailjetTransport;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
@@ -26,6 +24,8 @@ use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;

@@ -39,6 +39,7 @@ class AdminController extends EasyAdminController
protected $mailjetTransport;
protected $orderUtils;
protected $translator;
protected $filtersForm = null;

public function __construct(Security $security, UserManagerInterface $userManager, EntityManagerInterface $em,
MailjetTransport $mailjetTransport, UtilsManager $utilsManager, TranslatorInterface $translator)
@@ -49,7 +50,7 @@ class AdminController extends EasyAdminController
$this->mailjetTransport = $mailjetTransport;
$this->utils = $utilsManager->getUtils();
$this->merchantUtils = $utilsManager->getMerchantUtils();
$this->orderUtils = $utilsManager->getOrderUtils() ;;
$this->orderUtils = $utilsManager->getOrderUtils();;
$this->translator = $translator;
}

@@ -68,10 +69,30 @@ class AdminController extends EasyAdminController
}


public function autocompleteAction()
{

$entityName = $this->request->query->get('entity');
$valueSearched = $this->request->query->get('q');
$field = $this->request->query->get('field');

$class = $this->entity['class'];
$repo = $this->em->getRepository($class);

$values = $repo->findByTerm($field, $valueSearched);

$response = array();
foreach ($values as $value) {
$response[] = $value[$field];
}
return new JsonResponse($response);

}

/**
* Réécriture de show action pr rediriger vers l'édition
*/
/* public function showAction()
public function showAction()
{
$id = $this->request->query->get('id');
$entity = $this->request->query->get('entity');
@@ -81,7 +102,7 @@ class AdminController extends EasyAdminController
'entity' => $entity,
'id' => $id
]);
}*/
}


/**
@@ -127,6 +148,7 @@ class AdminController extends EasyAdminController
$dqlFilter = $this->commonDqlFilterQueryBuilder($entityClass, $dqlFilter);
$queryBuilder = parent::createSearchQueryBuilder($entityClass, $searchQuery, $searchableFields, $sortField, $sortDirection, $dqlFilter);
$this->commonQueryFilter($entityClass, $queryBuilder);

return $queryBuilder;
}

@@ -135,6 +157,56 @@ class AdminController extends EasyAdminController
$dqlFilter = $this->commonDqlFilterQueryBuilder($entityClass, $dqlFilter);
$queryBuilder = parent::createListQueryBuilder($entityClass, $sortDirection, $sortField, $dqlFilter);
$this->commonQueryFilter($entityClass, $queryBuilder);

$listFields = $this->entity['list']['fields'];
$this->filtersForm = $this->createForm(ListFilterType::class, null, array(
'fields' => $listFields,
'method' => 'get'
));
$this->filtersForm->handleRequest($this->request);

if ($this->filtersForm->isSubmitted() && $this->filtersForm->isValid()) {
foreach ($listFields as $field) {
if ($this->filtersForm->has($field['property'])) {
switch ($field['dataType']) {
case 'integer':
case 'text':
case 'string':
case 'toggle':
$filter = $this->filtersForm->get($field['property'])->getData();
if ($filter !== null) {

$queryBuilder->andWhere('entity.' . $field['property'] . ' LIKE :' . $field['property'] . '');
$queryBuilder->setParameter($field['property'], '%' . $filter . '%');
}
break;
case 'association' :
$filter = $this->filtersForm->get($field['property'])->getData();
if ($filter !== null) {
if ($field['type_options']['multiple']) {
$queryBuilder->andWhere(':' . $field['property'] . ' MEMBER OF entity.' . $field['property'] . '');
} else {
$queryBuilder->andWhere('entity.' . $field['property'] . ' = :' . $field['property'] . '');
}
$queryBuilder->setParameter($field['property'], $filter);
}
break;
case 'datetime':
case 'date':
$dateStart = $this->filtersForm->get($field['property'])->get('dateStart')->getData();
$dateEnd = $this->filtersForm->get($field['property'])->get('dateEnd')->getData();


if ($dateStart) $queryBuilder->andWhere('entity.' . $field['property'] . ' >= :dateStart')->setParameter('dateStart', $dateStart);
if ($dateEnd) $queryBuilder->andWhere('entity.' . $field['property'] . ' <= :dateEnd')->setParameter('dateEnd', $dateEnd);

}


}
}
}

return $queryBuilder;
}

@@ -145,10 +217,25 @@ class AdminController extends EasyAdminController
$reminderRepo = $this->em->getRepository(ReminderInterface::class);
$easyadmin = $this->request->attributes->get('easyadmin');
$entityName = $easyadmin['entity']['name'];
$id=null;
if($easyadmin['item'])$id = $easyadmin['item']->getId();
$id = null;
if ($easyadmin['item']) $id = $easyadmin['item']->getId();

$reminders = array('reminders' => $reminderRepo->findByEasyAdminConfig($actionName, $entityName, $id));

if ($actionName == 'list') {
if ($this->filtersForm === null) {
$options['fields'] = $parameters['fields'];
$options['method'] = 'get';
$this->filtersForm = $this->createForm(ListFilterType::class, null, $options);
}
$parameters = array_merge(
$parameters,
array(
'filters_form' => $this->filtersForm->createView()
)
);
}

$reminders = array('reminders' => $reminderRepo->findByEasyAdminConfig($actionName, $entityName, $id ));

$parameters = array_merge(
$parameters,
@@ -290,9 +377,9 @@ class AdminController extends EasyAdminController

if ($entity instanceof SeoInterface) {
$formBuilder->add('metaTitle', TextType::class, array(
'required' => false,
'translation_domain' => 'lcshop'
)
'required' => false,
'translation_domain' => 'lcshop'
)
);
$formBuilder->add('metaDescription', TextareaType::class, array(
'required' => false,
@@ -415,5 +502,89 @@ class AdminController extends EasyAdminController
}
}
}

protected function editAction()
{
$this->dispatch(EasyAdminEvents::PRE_EDIT);

$id = $this->request->query->get('id');
$easyadmin = $this->request->attributes->get('easyadmin');
$entity = $easyadmin['item'];

if ($this->request->isXmlHttpRequest() && $property = $this->request->query->get('property')) {
$newValue = 'true' === mb_strtolower($this->request->query->get('newValue'));
$fieldsMetadata = $this->entity['list']['fields'];

if (!isset($fieldsMetadata[$property]) || 'toggle' !== $fieldsMetadata[$property]['dataType']) {
throw new \RuntimeException(sprintf('The type of the "%s" property is not "toggle".', $property));
}

$this->updateEntityProperty($entity, $property, $newValue);
$this->utils->addFlash('success', 'success.common.fieldChange');

$response['flashMessages'] = $this->utils->getFlashMessages();
return new Response(json_encode($response));
}

$fields = $this->entity['edit']['fields'];

$editForm = $this->executeDynamicMethod('create<EntityName>EditForm', [$entity, $fields]);
$deleteForm = $this->createDeleteForm($this->entity['name'], $id);

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

$this->dispatch(EasyAdminEvents::PRE_UPDATE, ['entity' => $entity]);
$this->executeDynamicMethod('update<EntityName>Entity', [$entity, $editForm]);
$this->dispatch(EasyAdminEvents::POST_UPDATE, ['entity' => $entity]);

return $this->redirectToReferrer();
}

$this->dispatch(EasyAdminEvents::POST_EDIT);

$parameters = [
'form' => $editForm->createView(),
'entity_fields' => $fields,
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
];

return $this->executeDynamicMethod('render<EntityName>Template', ['edit', $this->entity['templates']['edit'], $parameters]);
}

public function createNewEntity(){
$idDuplicate = $this->request->query->get('duplicate', null);
if($idDuplicate){
$easyadmin = $this->request->attributes->get('easyadmin');
$entity= $this->em->getRepository($easyadmin['entity']['class'])->find($idDuplicate);

$newProductFamily = clone $entity ;
$this->em->persist($newProductFamily) ;
$this->em->flush() ;
}else{
$entityFullyQualifiedClassName = $this->entity['class'];

return new $entityFullyQualifiedClassName();
}

}

public function duplicateAction(){
$id = $this->request->query->get('id');
$refererUrl = $this->request->query->get('referer', '');

$easyadmin = $this->request->attributes->get('easyadmin');

$entity= $this->em->getRepository($easyadmin['entity']['class'])->find($id);

$newProductFamily = clone $entity ;

$this->em->persist($newProductFamily) ;
$this->em->flush() ;

return $this->redirectToRoute('easyadmin', ['entity' => $easyadmin['entity']['name'], 'action' => 'edit', 'id' =>$newProductFamily->getId(), 'referer' =>$refererUrl ]) ;
}
}


+ 7
- 3
ShopBundle/Controller/Backend/NewsController.php Vedi File

@@ -3,14 +3,18 @@
namespace Lc\ShopBundle\Controller\Backend;

use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Lc\ShopBundle\Context\NewsInterface;
use Lc\ShopBundle\Context\UserInterface;
use Lc\ShopBundle\Services\UtilsManager;
use Mailjet\MailjetSwiftMailer\SwiftMailer\MailjetTransport;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;

class NewsController extends AdminController
{

public function sendAction()
{
$idNews = $this->request->get('id') ;
@@ -36,9 +40,9 @@ class NewsController extends AdminController
array_push($messages, $message);
}

$result = $this->mailjetTransport->bulkSend($messages);

if($countUsers > 0) {
$result = $this->mailjetTransport->bulkSend($messages);

$this->addFlash('success', 'Actualité envoyée à '.count($users).' utilisateurs.');

$news->setIsSent(true) ;

+ 141
- 77
ShopBundle/Controller/Backend/ProductFamilyController.php Vedi File

@@ -14,6 +14,7 @@ use Lc\ShopBundle\Form\Backend\ProductFamily\ProductType;
use Lc\ShopBundle\Model\ProductFamily;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Response;
@@ -38,21 +39,24 @@ class ProductFamilyController extends AdminController
$reductionCatalogRepo = $this->em->getRepository(ReductionCatalogInterface::class);

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

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


$formBuilder->add('stayOnPage', HiddenType::class, array(
'required' => false,
'mapped' => false,
));
$formBuilder->add('warningMessageType', ChoiceType::class, array(
'choices' => array(
'field.default.warningMessageTypeOptions.'.ProductFamily::WARNING_MESSAGE_TYPE_SUCCESS => ProductFamily::WARNING_MESSAGE_TYPE_SUCCESS,
'field.default.warningMessageTypeOptions.'.ProductFamily::WARNING_MESSAGE_TYPE_ERROR => ProductFamily::WARNING_MESSAGE_TYPE_ERROR,
'field.default.warningMessageTypeOptions.'.ProductFamily::WARNING_MESSAGE_TYPE_WARNING => ProductFamily::WARNING_MESSAGE_TYPE_WARNING,
'field.default.warningMessageTypeOptions.'.ProductFamily::WARNING_MESSAGE_TYPE_INFO => ProductFamily::WARNING_MESSAGE_TYPE_INFO
'field.default.warningMessageTypeOptions.' . ProductFamily::WARNING_MESSAGE_TYPE_SUCCESS => ProductFamily::WARNING_MESSAGE_TYPE_SUCCESS,
'field.default.warningMessageTypeOptions.' . ProductFamily::WARNING_MESSAGE_TYPE_ERROR => ProductFamily::WARNING_MESSAGE_TYPE_ERROR,
'field.default.warningMessageTypeOptions.' . ProductFamily::WARNING_MESSAGE_TYPE_WARNING => ProductFamily::WARNING_MESSAGE_TYPE_WARNING,
'field.default.warningMessageTypeOptions.' . ProductFamily::WARNING_MESSAGE_TYPE_INFO => ProductFamily::WARNING_MESSAGE_TYPE_INFO
),
'translation_domain' => 'lcshop',
'multiple' => false,
@@ -76,8 +80,8 @@ class ProductFamilyController extends AdminController
$formBuilder->add('behaviorAddToCart', ChoiceType::class, array(
'data' => $entity->getBehaviorAddToCart() ? $entity->getBehaviorAddToCart() : 'simple',
'choices' => array(
'field.ProductFamily.behaviorAddToCartOptions.'.ProductFamily::BEHAVIOR_ADD_TO_CART_SIMPLE => ProductFamily::BEHAVIOR_ADD_TO_CART_SIMPLE,
'field.ProductFamily.behaviorAddToCartOptions.'.ProductFamily::BEHAVIOR_ADD_TO_CART_MULTIPLE => ProductFamily::BEHAVIOR_ADD_TO_CART_MULTIPLE
'field.ProductFamily.behaviorAddToCartOptions.' . ProductFamily::BEHAVIOR_ADD_TO_CART_SIMPLE => ProductFamily::BEHAVIOR_ADD_TO_CART_SIMPLE,
'field.ProductFamily.behaviorAddToCartOptions.' . ProductFamily::BEHAVIOR_ADD_TO_CART_MULTIPLE => ProductFamily::BEHAVIOR_ADD_TO_CART_MULTIPLE
),
'translation_domain' => 'lcshop',
'multiple' => false,
@@ -87,8 +91,8 @@ class ProductFamilyController extends AdminController
$formBuilder->add('behaviorPrice', ChoiceType::class, array(
'empty_data' => 'by-piece',
'choices' => array(
'field.ProductFamily.behaviorPriceOptions.'.ProductFamily::BEHAVIOR_PRICE_BY_PIECE => ProductFamily::BEHAVIOR_PRICE_BY_PIECE,
'field.ProductFamily.behaviorPriceOptions.'.ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT => ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT
'field.ProductFamily.behaviorPriceOptions.' . ProductFamily::BEHAVIOR_PRICE_BY_PIECE => ProductFamily::BEHAVIOR_PRICE_BY_PIECE,
'field.ProductFamily.behaviorPriceOptions.' . ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT => ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT
),
'translation_domain' => 'lcshop',
'multiple' => false,
@@ -96,15 +100,15 @@ class ProductFamilyController extends AdminController
));

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

$formBuilder->add('propertyOrganicLabel', ChoiceType::class, array(
'choices' => array(
'field.ProductFamily.organicLabelOptions.'.ProductFamily::PROPERTY_ORGANIC_LABEL_AB => ProductFamily::PROPERTY_ORGANIC_LABEL_AB,
'field.ProductFamily.organicLabelOptions.'.ProductFamily::PROPERTY_ORGANIC_LABEL_NP => ProductFamily::PROPERTY_ORGANIC_LABEL_NP,
'field.ProductFamily.organicLabelOptions.'.ProductFamily::PROPERTY_ORGANIC_LABEL_HVE => ProductFamily::PROPERTY_ORGANIC_LABEL_HVE
'field.ProductFamily.organicLabelOptions.' . ProductFamily::PROPERTY_ORGANIC_LABEL_AB => ProductFamily::PROPERTY_ORGANIC_LABEL_AB,
'field.ProductFamily.organicLabelOptions.' . ProductFamily::PROPERTY_ORGANIC_LABEL_NP => ProductFamily::PROPERTY_ORGANIC_LABEL_NP,
'field.ProductFamily.organicLabelOptions.' . ProductFamily::PROPERTY_ORGANIC_LABEL_HVE => ProductFamily::PROPERTY_ORGANIC_LABEL_HVE
),
'translation_domain' => 'lcshop',
'multiple' => false,
@@ -114,37 +118,37 @@ class ProductFamilyController extends AdminController

$formBuilder->add('typeExpirationDate', ChoiceType::class, array(
'choices' => array(
'field.default.'.ProductFamily::TYPE_EXPIRATION_DATE_DLC => ProductFamily::TYPE_EXPIRATION_DATE_DLC,
'field.default.'.ProductFamily::TYPE_EXPIRATION_DATE_DDM => ProductFamily::TYPE_EXPIRATION_DATE_DDM,
'field.default.'.ProductFamily::TYPE_EXPIRATION_DATE_DLUO => ProductFamily::TYPE_EXPIRATION_DATE_DLUO
'field.default.' . ProductFamily::TYPE_EXPIRATION_DATE_DLC => ProductFamily::TYPE_EXPIRATION_DATE_DLC,
'field.default.' . ProductFamily::TYPE_EXPIRATION_DATE_DDM => ProductFamily::TYPE_EXPIRATION_DATE_DDM,
'field.default.' . ProductFamily::TYPE_EXPIRATION_DATE_DLUO => ProductFamily::TYPE_EXPIRATION_DATE_DLUO
),
'translation_domain' => 'lcshop',
'multiple' => false,
'expanded' => true,
'required'=>false
'required' => false
));

$formBuilder->add('behaviorStockWeek', ChoiceType::class, array(
'choices' => array(
'field.ProductFamily.behaviorStockWeekOptions.'.ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE => ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE,
'field.ProductFamily.behaviorStockWeekOptions.'.ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE_VALIDATION => ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE_VALIDATION,
'field.ProductFamily.behaviorStockWeekOptions.'.ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE => ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE
'field.ProductFamily.behaviorStockWeekOptions.' . ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE => ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE,
'field.ProductFamily.behaviorStockWeekOptions.' . ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE_VALIDATION => ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE_VALIDATION,
'field.ProductFamily.behaviorStockWeekOptions.' . ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE => ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE
),
'translation_domain' => 'lcshop',
'multiple' => false,
'expanded' => true,
'required'=>true
'required' => true
));

$formBuilder->add('behaviorExpirationDate', ChoiceType::class, array(
'choices' => array(
'field.ProductFamily.behaviorExpirationDateOptions.'.ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT_FAMILY => ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT_FAMILY,
'field.ProductFamily.behaviorExpirationDateOptions.'.ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT => ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT
'field.ProductFamily.behaviorExpirationDateOptions.' . ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT_FAMILY => ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT_FAMILY,
'field.ProductFamily.behaviorExpirationDateOptions.' . ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT => ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT
),
'translation_domain' => 'lcshop',
'multiple' => false,
'expanded' => true,
'required'=>false
'required' => false
));


@@ -163,13 +167,14 @@ class ProductFamilyController extends AdminController
return $formBuilder;
}

public function updateProductFamilyEntity($entity, $editForm)
public function updateProductFamilyEntity($entity, $editForm = false)
{
$this->processReductionCatalog($entity, $editForm);
$this->processCategories($entity);
$this->processProducts($entity);
$this->processPrice($entity);

if ($editForm) {
$this->processReductionCatalog($entity, $editForm);
$this->processCategories($entity);
$this->processProducts($entity);
$this->processPrice($entity);
}
parent::updateEntity($entity);
}

@@ -184,10 +189,11 @@ class ProductFamilyController extends AdminController
$this->em->flush();
}

protected function processReductionCatalog($entity, $editForm){
protected function processReductionCatalog($entity, $editForm)
{
$reductionCatalog = $editForm->get('reductionCatalog')->getData();
if($reductionCatalog instanceof ReductionCatalogInterface ) {
if($reductionCatalog->getValue() && $reductionCatalog->getBehaviorTaxRate() && $reductionCatalog->getUnit()){
if ($reductionCatalog instanceof ReductionCatalogInterface) {
if ($reductionCatalog->getValue() && $reductionCatalog->getBehaviorTaxRate() && $reductionCatalog->getUnit()) {
$reductionCatalog->setMerchant($entity->getMerchant());
$reductionCatalog->setStatus($editForm->get('activeReductionCatalog')->getData());
$reductionCatalog->setProductFamily($entity);
@@ -196,17 +202,18 @@ class ProductFamilyController extends AdminController
}
}

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

protected function processProducts($entity)
protected function processProducts($entity, $clone = false)
{
//si il existe un et un seul produit pour ce product family n'ajoute rien supprime rien
if (count($entity->getProducts()) == 0) {
@@ -215,10 +222,17 @@ class ProductFamilyController extends AdminController
$this->em->persist($product);
$entity->addProduct($product);
} else {
foreach ($entity->getProducts() as $i=>$product) {
$product->setProductFamily($entity);
$this->em->persist($product);
$entity->addProduct($product);
foreach ($entity->getProducts() as $i => $product) {
if ($clone) {
$newProduct = clone $product;
$newProduct->setProductFamily($entity);
$this->em->persist($newProduct);
$entity->addProduct($newProduct);
} else {
$product->setProductFamily($entity);
$this->em->persist($product);
$entity->addProduct($product);
}
}
}

@@ -254,25 +268,6 @@ class ProductFamilyController extends AdminController
$easyadmin = $this->request->attributes->get('easyadmin');
$entity = $easyadmin['item'];




$orderShopRepo = $this->em->getRepository(OrderShopInterface::class);

$totalProductOrdered = array();
foreach ($entity->getProducts() as $product) {
$currentWeekNumber = $this->orderUtils->getWeekNumberCurrent();
//Les commandes sont ouvertes ont récupèrent les commandes en cours et celle de la semaine dernière
if($this->orderUtils->isOpenSale()) {
$totalProductOrdered[$product->getId()][$currentWeekNumber] = $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber, $product->getId());
$totalProductOrdered[$product->getId()][$currentWeekNumber - 1] = $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber - 1, $product->getId());
}else{
$totalProductOrdered[$product->getId()][$currentWeekNumber] = $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber, $product->getId());
}
}



if ($this->request->isXmlHttpRequest() && $property = $this->request->query->get('property')) {
$newValue = 'true' === mb_strtolower($this->request->query->get('newValue'));
$fieldsMetadata = $this->entity['list']['fields'];
@@ -282,9 +277,10 @@ class ProductFamilyController extends AdminController
}

$this->updateEntityProperty($entity, $property, $newValue);
$this->utils->addFlash('success', 'success.common.fieldChange');

// cast to integer instead of string to avoid sending empty responses for 'false'
return new Response((int)$newValue);
$response['flashMessages'] = $this->utils->getFlashMessages();
return new Response(json_encode($response));
}

$fields = $this->entity['edit']['fields'];
@@ -300,11 +296,10 @@ class ProductFamilyController extends AdminController

$editForm->handleRequest($this->request);

if( $editForm->isSubmitted() && count($entity->getProductCategories()) == 0){
if ($editForm->isSubmitted() && count($entity->getProductCategories()) == 0) {
$editForm->get('productCategories')->addError(new FormError('Vous devez choisir au moins une catégorie'));
}

if ($editForm->isSubmitted() && $editForm->isValid() && count($entity->getProductCategories())>0) {
if ($editForm->isSubmitted() && $editForm->isValid() && count($entity->getProductCategories()) > 0) {

$this->processUploadedFiles($editForm);

@@ -312,8 +307,15 @@ class ProductFamilyController extends AdminController
$this->executeDynamicMethod('update<EntityName>Entity', [$entity, $editForm]);
$this->dispatch(EasyAdminEvents::POST_UPDATE, ['entity' => $entity]);

$this->utils->addFlash('success', 'Produit sauvegardé') ;
return $this->redirectToRoute('easyadmin', ['entity' => 'ProductFamily', 'action' => 'edit', 'id' => $id]) ;
$this->utils->addFlash('success', 'Produit sauvegardé');

if ($editForm->get('stayOnPage')->getData() != "false" || $this->request->get('submitAndStay') !== null) {
$refererUrl = $this->request->query->get('referer', '');
return $this->redirectToRoute('easyadmin', ['entity' => 'ProductFamily', 'action' => 'edit', 'id' => $id, 'referer' => $refererUrl]);
} else {
return $this->redirectToReferrer();
}

}

$this->dispatch(EasyAdminEvents::POST_EDIT);
@@ -324,7 +326,7 @@ class ProductFamilyController extends AdminController
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
'sortableProductsField' => $sortableProductsField,
'totalProductOrdered' => $totalProductOrdered
'totalProductOrdered' => $this->getTotalProductOrdered($entity)
];

return $this->executeDynamicMethod('render<EntityName>Template', ['edit', $this->entity['templates']['edit'], $parameters]);
@@ -347,18 +349,22 @@ class ProductFamilyController extends AdminController
$newForm->handleRequest($this->request);


if( $newForm->isSubmitted() && array_search(true, $newForm->get('productCategories')->getData()->toArray())===false){
if ($newForm->isSubmitted() && array_search(true, $newForm->get('productCategories')->getData()->toArray()) === false) {
$newForm->get('productCategories')->addError(new FormError('Vous devez choisir au moins une catégorie'));
}

if ($newForm->isSubmitted() && $newForm->isValid() && array_search(true, $newForm->get('productCategories')->getData()->toArray())!==false) {
if ($newForm->isSubmitted() && $newForm->isValid() && array_search(true, $newForm->get('productCategories')->getData()->toArray()) !== false) {
$this->processUploadedFiles($newForm);

$this->dispatch(EasyAdminEvents::PRE_PERSIST, ['entity' => $entity]);
$this->executeDynamicMethod('persist<EntityName>Entity', [$entity, $newForm]);
$this->dispatch(EasyAdminEvents::POST_PERSIST, ['entity' => $entity]);

return $this->redirectToReferrer();
if ($newForm->get('stayOnPage')->getData() != "false" || $this->request->get('submitAndStay') !== null) {
return $this->redirectToRoute('easyadmin', ['entity' => 'ProductFamily', 'action' => 'edit', 'id' => $entity->getId()]);
} else {
return $this->redirectToReferrer();
}
}

$this->dispatch(EasyAdminEvents::POST_NEW, [
@@ -382,4 +388,62 @@ class ProductFamilyController extends AdminController
return $this->executeDynamicMethod('render<EntityName>Template', ['new', $this->entity['templates']['new'], $parameters]);
}

public function duplicateAction()
{
$id = $this->request->query->get('id');
$refererUrl = $this->request->query->get('referer', '');

$easyadmin = $this->request->attributes->get('easyadmin');

$entity = $this->em->getRepository($easyadmin['entity']['class'])->find($id);

$newProductFamily = clone $entity;
if ($easyadmin['entity']['name'] == "ProductFamily") {
$this->processProducts($newProductFamily, true);
}
$this->em->persist($newProductFamily);
$this->em->flush();

return $this->redirectToRoute('easyadmin', ['entity' => $easyadmin['entity']['name'], 'action' => 'edit', 'id' => $newProductFamily->getId(), 'referer' => $refererUrl]);
}


public function getTotalProductOrdered($entity)
{
$orderShopRepo = $this->em->getRepository(OrderShopInterface::class);
$totalProductOrdered = array();
$currentWeekNumber = $this->orderUtils->getWeekNumberCurrent();
$totalProductOrdered['total'][$currentWeekNumber +1] = 0;
$totalProductOrdered['total'][$currentWeekNumber ] = 0;

foreach ($entity->getProducts() as $product) {
//Les commandes sont ouvertes ont récupèrent les commandes en cours et celle de la semaine dernière
if ($this->orderUtils->isOpenSale()) {
$totalProductOrdered[$product->getId()][$currentWeekNumber +1] = $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber +1, $product->getId());
$totalProductOrdered[$product->getId()][$currentWeekNumber] = $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber, $product->getId());

if ($entity->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
$ratioByMeasure = $product->getQuantity() / $product->getUnitInherited()->getCoefficient();
$totalProductOrdered['total'][$currentWeekNumber +1] += $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber +1, $product->getId()) * $ratioByMeasure;
$totalProductOrdered['total'][$currentWeekNumber] += $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber, $product->getId()) * $ratioByMeasure;
} else {
$totalProductOrdered['total'][$currentWeekNumber +1] += $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber+1, $product->getId());
$totalProductOrdered['total'][$currentWeekNumber] += $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber, $product->getId());
}

} else {
$totalProductOrdered[$product->getId()][$currentWeekNumber +1] = $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber+1, $product->getId());
if ($entity->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
$ratioByMeasure = $product->getQuantity() / $product->getUnitInherited()->getCoefficient();
$totalProductOrdered['total'][$currentWeekNumber+1] += $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber+1, $product->getId()) * $ratioByMeasure;
}else{
$totalProductOrdered['total'][$currentWeekNumber+1] += $orderShopRepo->countValidOrderProductsOfWeekByProduct($currentWeekNumber+1, $product->getId());
}
}

}
return $totalProductOrdered;
}

}


+ 28
- 0
ShopBundle/Controller/Backend/TicketController.php Vedi File

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

use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Event\EasyAdminEvents;
use FOS\UserBundle\Model\UserManagerInterface;
use Lc\ShopBundle\Form\Backend\Ticket\TicketMessageType;
use Lc\ShopBundle\Form\Backend\Ticket\TicketStatusType;
@@ -22,6 +23,33 @@ class TicketController extends AdminController

}


public function showAction()
{
$this->dispatch(EasyAdminEvents::PRE_SHOW);

$id = $this->request->query->get('id');
$easyadmin = $this->request->attributes->get('easyadmin');
$entity = $easyadmin['item'];

$fields = $this->entity['show']['fields'];
$deleteForm = $this->createDeleteForm($this->entity['name'], $id);

$this->dispatch(EasyAdminEvents::POST_SHOW, [
'deleteForm' => $deleteForm,
'fields' => $fields,
'entity' => $entity,
]);

$parameters = [
'entity' => $entity,
'fields' => $fields,
'delete_form' => $deleteForm->createView(),
];

return $this->executeDynamicMethod('render<EntityName>Template', ['show', $this->entity['templates']['show'], $parameters]);
}

/**
* The method that is executed when the user performs a 'show' action on an entity.
*

+ 25
- 0
ShopBundle/Controller/Backend/UserController.php Vedi File

@@ -28,5 +28,30 @@ class UserController extends AdminController
parent::updateEntity($user);
}

public function removeEntity($user)
{
// désactivation UserMerchant
if($user->getUserMerchants()) {
$merchant = $this->merchantUtils->getMerchantCurrent() ;
foreach($user->getUserMerchants() as $userMerchant) {
if($userMerchant->getMerchant() == $merchant) {
$userMerchant->setActive(false) ;
$this->em->persist($userMerchant);
$this->em->flush() ;
$this->addFlash('success', 'Utilisateur supprimé du hub');
}
}
}
}

protected function createUserListQueryBuilder($entityClass, $sortDirection, $sortField = null, $dqlFilter = null)
{
$queryBuilder = parent::createListQueryBuilder($entityClass, $sortDirection, $sortField, $dqlFilter) ;

$queryBuilder->innerJoin('entity.userMerchants', 'um') ;
$queryBuilder->andWhere('um.merchant = :merchant AND um.active = 1') ;
$queryBuilder->setParameter('merchant', $this->merchantUtils->getMerchantCurrent()) ;

return $queryBuilder ;
}
}

+ 4
- 2
ShopBundle/Controller/Frontend/CartController.php Vedi File

@@ -74,8 +74,10 @@ class CartController extends BaseController
$data = $form->getData() ;
foreach($data as $orderProduct) {
if($orderProduct instanceof OrderProductInterface) {
$addOrderProduct = $this->orderUtils->addOrderProduct($orderShop, $orderProduct) ;
if($addOrderProduct && $orderProduct->getQuantityOrder() > 0) {
if($orderProduct->getQuantityOrder() > 0) {
$addOrderProduct = $this->orderUtils->addOrderProduct($orderShop, $orderProduct) ;
}
if(isset($addOrderProduct) && $addOrderProduct && $orderProduct->getQuantityOrder() > 0) {
$this->orderProducts[] = $orderProduct ;
}
}

+ 2
- 0
ShopBundle/EventSubscriber/ListEventSubscriber.php Vedi File

@@ -60,5 +60,7 @@ class ListEventSubscriber implements EventSubscriberInterface
}
}
}
$paginator->nbResultsTotal = $entityRepo->count(array());

}
}

+ 4
- 1
ShopBundle/Form/Backend/Common/AddressType.php Vedi File

@@ -5,6 +5,7 @@ namespace Lc\ShopBundle\Form\Backend\Common;
use Lc\ShopBundle\Model\Address;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Doctrine\ORM\EntityManagerInterface;
@@ -60,7 +61,9 @@ class AddressType extends AbstractType
])
->add('company', TextType::class, ['required' => false])
->add('siret', TextType::class, ['required' => false])
->add('tva', TextType::class, ['required' => false]);
->add('tva', TextType::class, ['required' => false])
->add('country', HiddenType::class, ['data' => 'France'])
;

}


+ 137
- 0
ShopBundle/Form/Backend/Filters/ListFilterType.php Vedi File

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

namespace Lc\ShopBundle\Form\Backend\Filters;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;


class ListFilterType extends AbstractType
{
protected $em;

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

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

foreach ($options['fields'] as $field) {

switch ($field['dataType']) {
case 'integer':
$builder->add($field['property'], TextType::class, array(
'required' => false,
'attr'=>array(
'class'=> ' input-sm',
'form'=> 'filters-form'
)
));
break;
case 'string':
$builder->add($field['property'], TextType::class, array(
'required' => false,
'attr'=>array(
'class'=> ' input-sm',
'form'=> 'filters-form'
)
));
break;
case 'toggle':
$builder->add($field['property'], ChoiceType::class, array(
'choices'=> array(
'Oui' => 1,
'Non' => 0,
),
'placeholder'=> '--',
'required'=>false,
'attr'=>array(
'class'=> 'select2 input-sm',
'form'=> 'filters-form'
)
));
break;
case 'datetime':
case 'date':
$builder->add(
$builder->create($field['property'], FormType::class, array('inherit_data' => true))
->add('dateStart', DateType::class, array(
'widget' => 'single_text',
'required' => false,
))
->add('dateEnd', DateType::class, array(
'widget' => 'single_text',
'required' => false,

))
);
break;
case 'association':
$classImplements = class_implements($field['targetEntity']);
$builder->add($field['property'], EntityType::class, array(
'class' => $field['targetEntity'],
'placeholder'=> '--',
'query_builder' => function (EntityRepository $repo) use ($classImplements) {
if (in_array('Lc\ShopBundle\Context\FilterMerchantInterface', $classImplements)) {
return $repo->findByMerchantQuery();
}else{
return $repo->createQueryBuilder('entity');
}

},
'required' => false,
'attr'=>array(
'class'=> 'select2 input-sm',
'form'=> 'filters-form'
)


));
break;
case 'dateinterval':

break;
case 'float':

break;
}


}
/* $builder
->add('title', TextType::class, [
'label' => 'Titre',
'required' => false,
])
->add('behaviorTaxRate', BehaviorTaxRateType::class)
->add('unit', UnitType::class)
->add('value', ValueType::class)
->add('permanent', PermanentType::class)
->add('dateStart', DateStartType::class)
->add('dateEnd', DateEndType::class)
->add('users', UsersFilterType::class)
->add('groupUsers', GroupUsersFilterType::class);*/
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'label' => false,
'csrf_protection'=> false,
'translation_domain' => 'lcshop',
'fields' => false
]);
}
}

+ 1
- 0
ShopBundle/Form/Backend/ProductFamily/ProductType.php Vedi File

@@ -120,6 +120,7 @@ class ProductType extends AbstractType
));

$builder->add('position', HiddenType::class);
$builder->add('status', HiddenType::class);
$builder->add('exportTitle', TextType::class, array(
'required' =>false
));

+ 8
- 0
ShopBundle/Form/Backend/ReductionCommon/UsersFilterType.php Vedi File

@@ -4,6 +4,7 @@ namespace Lc\ShopBundle\Form\Backend\ReductionCommon;

use Doctrine\ORM\EntityManagerInterface;

use Doctrine\ORM\EntityRepository;
use Lc\ShopBundle\Context\ReductionCatalogInterface;
use Lc\ShopBundle\Context\UserInterface;
use Lc\ShopBundle\Repository\GroupUserRepository;
@@ -42,6 +43,13 @@ class UsersFilterType extends AbstractType
$builder->add('users', EntityType::class, [
'class' => $userClass->name,
'required' => false,
'query_builder'=> function (EntityRepository $er) {
$query = $er->findByMerchantQuery()
->leftJoin('e.groupUsers', 'groupUsers')->addSelect('groupUsers')
->leftJoin('e.supplier', 'supplier')->addSelect('supplier')
;
return $query;
},
'expanded' => false,
'multiple' => true,
'translation_domain'=>'lcshop',

+ 14
- 0
ShopBundle/Model/CreditHistory.php Vedi File

@@ -10,6 +10,7 @@ use Lc\ShopBundle\Context\OrderPaymentInterface;
use Lc\ShopBundle\Context\OrderRefundInterface;
use Lc\ShopBundle\Context\PayoffInterface;
use Lc\ShopBundle\Context\UserMerchantInterface;
use Gedmo\Mapping\Annotation as Gedmo;

/**
* @ORM\MappedSuperclass()
@@ -47,6 +48,19 @@ abstract class CreditHistory extends AbstractEntity implements PayoffInterface
*/
protected $orderRefund;

/**
* @Gedmo\Blameable(on="create")
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\UserInterface")
* @ORM\JoinColumn(nullable=true)
*/
protected $createdBy;

/**
* @Gedmo\Blameable(on="update")
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\UserInterface")
* @ORM\JoinColumn(nullable=true)
*/
protected $updatedBy;

public function getAmount(): ?float
{

+ 1
- 1
ShopBundle/Model/Document.php Vedi File

@@ -47,7 +47,7 @@ abstract class Document extends AbstractDocumentEntity implements FilterMerchant

/**
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\AddressInterface")
* @ORM\JoinColumn(nullable=false)
* @ORM\JoinColumn(nullable=true)
*/
protected $buyerAddress;


+ 1
- 1
ShopBundle/Model/PriceTrait.php Vedi File

@@ -75,7 +75,7 @@ trait PriceTrait
return $this->unit;
}

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


+ 3
- 1
ShopBundle/Model/Product.php Vedi File

@@ -20,6 +20,7 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod
{
use SortableTrait;
use ProductPropertyTrait;
use StatusTrait;

/**
* @Gedmo\Blameable(on="create")
@@ -36,7 +37,7 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod
protected $updatedBy;

/**
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface", inversedBy="products")
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface", inversedBy="products", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
protected $productFamily;
@@ -50,6 +51,7 @@ abstract class Product extends AbstractEntity implements SortableInterface, Prod
public function __construct()
{
$this->orderProducts = new ArrayCollection();
$this->status = 1;
}

public function getBuyingPriceInherited()

+ 14
- 0
ShopBundle/Model/ProductCategory.php Vedi File

@@ -29,6 +29,7 @@ abstract class ProductCategory extends AbstractDocumentEntity implements TreeInt

/**
* @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\ProductCategoryInterface", mappedBy="parent" , fetch="EAGER"))
* @ORM\OrderBy({"position" = "ASC"})
*/
protected $childrens;

@@ -129,6 +130,19 @@ abstract class ProductCategory extends AbstractDocumentEntity implements TreeInt
return $this;
}

public function countProductFamilies($status = null)
{
$count = 0 ;

foreach($this->getProductFamilies() as $productFamily) {
if($status === null || ($status !== null && $productFamily->getStatus() == $status)) {
$count ++ ;
}
}

return $count ;
}

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

+ 21
- 4
ShopBundle/Model/ProductFamily.php Vedi File

@@ -97,6 +97,7 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr

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

@@ -320,6 +321,20 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
return $this->products;
}

public function getProductsOnline(): Collection
{
$products = $this->getProducts() ;
$productsOnlineArray = new ArrayCollection() ;

foreach($products as $product) {
if($product->getStatus() == 1) {
$productsOnlineArray[] = $product ;
}
}

return $productsOnlineArray ;
}

public function addProduct(ProductInterface $product): self
{
if (!$this->products->contains($product)) {
@@ -758,11 +773,13 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
$products = $this->getProducts();

foreach ($products as $product) {
$titleProduct = $product->getTitleInherited();
if (!isset($arrayProductsGroupByTitle[$titleProduct])) {
$arrayProductsGroupByTitle[$titleProduct] = [];
if($product->getStatus() == 1) {
$titleProduct = $product->getTitleInherited();
if (!isset($arrayProductsGroupByTitle[$titleProduct])) {
$arrayProductsGroupByTitle[$titleProduct] = [];
}
$arrayProductsGroupByTitle[$titleProduct][] = $product;
}
$arrayProductsGroupByTitle[$titleProduct][] = $product;
}

return $arrayProductsGroupByTitle;

+ 1
- 0
ShopBundle/Model/Ticket.php Vedi File

@@ -94,6 +94,7 @@ abstract class Ticket extends AbstractEntity implements FilterMerchantInterface

/**
* @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\TicketMessageInterface", mappedBy="ticket", orphanRemoval=true)
* @ORM\OrderBy({"id" = "ASC"})
*/
protected $ticketMessages;


+ 6
- 1
ShopBundle/Model/User.php Vedi File

@@ -101,6 +101,11 @@ abstract class User extends UserModelFOS
$this->userMerchants = new ArrayCollection();
}

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

public function getSummary()
{
return '#'.$this->getId().' '.strtoupper($this->getLastname()).' '.$this->getFirstname(). ' ('.$this->getEmail().')';
@@ -108,7 +113,7 @@ abstract class User extends UserModelFOS

public function getName()
{
return $this->getFirstname().' '.strtoupper($this->getLastname());
return (string) ucfirst(strtolower($this->getFirstname())). ' '.strtoupper($this->getLastname());
}

public function setEmail($email)

+ 17
- 0
ShopBundle/Model/UserMerchant.php Vedi File

@@ -42,6 +42,11 @@ abstract class UserMerchant implements FilterMerchantInterface
*/
protected $creditHistories;

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

public function __construct()
{
$this->creditHistories = new ArrayCollection();
@@ -130,4 +135,16 @@ abstract class UserMerchant implements FilterMerchantInterface

return $this;
}

public function getActive(): ?bool
{
return $this->active;
}

public function setActive(bool $active): self
{
$this->active = $active;

return $this;
}
}

+ 11
- 0
ShopBundle/Repository/BaseRepository.php Vedi File

@@ -25,6 +25,17 @@ class BaseRepository extends EntityRepository implements ServiceEntityRepository
}


public function findByTerm($field, $term, $limit=10){
$qb = $this->findByMerchantQuery();
$qb->select('e.'.$field);
$qb->andWhere(
$qb->expr()->like('e.'.$field, ':term'));
$qb->setParameter('term', '%'.$term.'%');
$qb->setMaxResults($limit);

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

}
public function findByMerchantQuery() :QueryBuilder
{
return $this->createQueryBuilder('e')

+ 28
- 19
ShopBundle/Repository/OrderShopRepository.php Vedi File

@@ -81,17 +81,6 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
return $query;
}

public function filterIsOffCircuit($query, $isOffCircuit)
{
if ($isOffCircuit) {
$query->andWhere('e.isOffCircuit = 1');
} else {
$query->andWhere('e.isOffCircuit IS NULL OR e.isOffCircuit = 0');
}

return $query;
}

public function findCartCurrent($params)
{
$query = $this->findByMerchantQuery();
@@ -150,10 +139,20 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
$query = $this->filterOrderValid($query);
}

if (isset($params['orderStatus'])) {
$query->leftJoin('e.orderStatus', 'os');
$query->andWhere('os.alias LIKE :alias');
$query->setParameter('alias', $params['orderStatus']);
}

if (isset($params['user'])) {
$query->andWhere('e.user = :user')->setParameter('user', $params['user']);
}

if(isset($params['address'])) {
$query->andWhere('e.deliveryAddress = :address OR e.invoiceAddress = :address')->setParameter('address', $params['address']);
}

if (isset($params['mergeComplementaryOrderShops'])) {
$query->andWhere('e.mainOrderShop IS NULL');
$query->leftJoin('e.complementaryOrderShops', 'complementaryOrderShops');
@@ -167,20 +166,28 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
$query->andWhere('e.mainOrderShop IS NULL');
}

if (isset($params['isOffCircuit'])) {
$query = $this->filterIsOffCircuit($query, true);
}
$setParameterHorsTournee = false ;

if (isset($params['isCircuit'])) {
$query = $this->filterIsOffCircuit($query, false);
$query->leftJoin('e.deliveryPointSale', 'pointSale');
$query->andWhere('e.deliveryPointSale IS NULL OR pointSale.isDepository = 0');
$query->andWhere('e.deliveryPointSale IS NULL OR (pointSale.isDepository = 0 AND (pointSale.devAlias IS NULL OR pointSale.devAlias != :devAliasHorsTournee))');
$setParameterHorsTournee = true ;
}

if (isset($params['isDepository'])) {
$query = $this->filterIsOffCircuit($query, false);
$query->innerJoin('e.deliveryPointSale', 'pointSale');
$query->andWhere('pointSale.isDepository = 1');
$query->andWhere('pointSale IS NOT NULL AND pointSale.isDepository = 1 AND (pointSale.devAlias IS NULL OR pointSale.devAlias != :devAliasHorsTournee)');
$setParameterHorsTournee = true ;
}

if (isset($params['isOffCircuit'])) {
$query->innerJoin('e.deliveryPointSale', 'pointSale');
$query->andWhere('pointSale IS NOT NULL AND pointSale.devAlias = :devAliasHorsTournee');
$setParameterHorsTournee = true ;
}

if($setParameterHorsTournee) {
$query->setParameter('devAliasHorsTournee', 'horstournee') ;
}

if (isset($params['deliveryAvailability'])) {
@@ -226,6 +233,7 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
$query = $this->findByMerchantQuery();
$query = $this->filterOrderValid($query);
$query->andWhere('e.weekNumber = :weekNumber');
$query->andWhere('e.mainOrderShop = false OR e.mainOrderShop IS NULL');
$query->setParameter('weekNumber', $weekNumber);
$query->orderBy('e.validationDate', 'DESC');
$query->setMaxResults(1);
@@ -245,7 +253,8 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
$query->setParameter('product', $productId);
$query->select('SUM(orderProduct.quantityOrder) as quantity');

return $query->getQuery()->getOneOrNullResult();
$result = $query->getQuery()->getOneOrNullResult();
return $result['quantity'];

}
}

+ 9
- 0
ShopBundle/Repository/ProductCategoryRepository.php Vedi File

@@ -28,6 +28,13 @@ class ProductCategoryRepository extends BaseRepository implements DefaultReposit
->orderBy('e.position', 'ASC');
}

public function findOneBySlug($slug)
{
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.slug = :slug')->setParameter('slug',$slug) ;
return $query->getQuery()->getOneOrNullResult() ;
}

public function findAllParents($withOffline = false)
{
$query = $this->findByMerchantQuery()
@@ -35,6 +42,8 @@ class ProductCategoryRepository extends BaseRepository implements DefaultReposit

if ($withOffline) $query->andWhere('e.status >= 0');
else $query->andWhere('e.status = 1');
$query->leftJoin('e.productFamilies','productFamilies') ;

$query->orderBy('e.position', 'ASC');


+ 8
- 0
ShopBundle/Repository/ProductFamilyRepository.php Vedi File

@@ -36,6 +36,14 @@ class ProductFamilyRepository extends BaseRepository implements DefaultRepositor
return $query->getQuery()->getResult() ;
}

public function findOneBySlug($slug)
{
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.slug = :slug')->setParameter('slug',$slug) ;
$query->andWhere('e.status = 1');
return $query->getQuery()->getOneOrNullResult() ;
}

public function getProductFamiliesByCategory($category){
$query = $this->findByMerchantQuery() ;
$query = $this->joinRelations($query) ;

+ 13
- 0
ShopBundle/Repository/UserRepository.php Vedi File

@@ -2,6 +2,7 @@

namespace Lc\ShopBundle\Repository;

use Doctrine\ORM\QueryBuilder;
use Lc\ShopBundle\Context\DefaultRepositoryInterface;
use Lc\ShopBundle\Context\UserInterface;

@@ -18,11 +19,23 @@ class UserRepository extends BaseRepository implements DefaultRepositoryInterfac
return UserInterface::class;
}

public function findByMerchantQuery() :QueryBuilder
{
return $this->createQueryBuilder('e')
->innerJoin('e.userMerchants', "userMerchants")
->andWhere('userMerchants.merchant = :currentMerchant')
->setParameter('currentMerchant', $this->merchantUtils->getMerchantCurrent()->getId()) ;
}

public function findAllByNewsletter($newsletter)
{
return $this->createQueryBuilder('e')
->where(':newsletter MEMBER OF e.newsletters')
->setParameter('newsletter', $newsletter->getId())
->andWhere('e.enabled = 1')
->innerJoin('e.userMerchants', 'um')
->andWhere('um.merchant = :merchant AND um.active = 1')
->setParameter('merchant', $newsletter->getMerchant())
->getQuery()
->getResult();
}

+ 1
- 6
ShopBundle/Resources/config/easy_admin/base.yaml Vedi File

@@ -3,6 +3,7 @@ easy_admin:
design:
templates:
list: '@LcShop/backend/default/list.html.twig'
#list: '@LcShop/backend/default/list-datatable.html.twig'
layout: '@LcShop/backend/default/layout/layout.html.twig'
menu: '@LcShop/backend/default/menu.html.twig'
edit: '@LcShop/backend/default/edit.html.twig'
@@ -14,15 +15,9 @@ easy_admin:
- '/bundles/lcshop/js/backend/script/custom.js'
css:
- '/bundles/lcshop/css/backend/jquery-ui.min.css'
- '/bundles/lcshop/css/backend/custom.css'
form_theme:
- '@LcShop/backend/form/custom_bootstrap_4.html.twig'
- '@LcShop/backend/form/ckeditor_widget.html.twig'
list:
max_results: 30
actions:
- { name: 'edit', icon: 'pencil'}
- { name: 'delete', icon: 'trash'}
formats:
date: 'd/m/Y'
time: 'h:i A e'

+ 2
- 2
ShopBundle/Resources/public/css/backend/adminlte/adminlte.css Vedi File

@@ -20706,14 +20706,14 @@ html.maximized-card {
.card-body.p-0 .table thead > tr > td:first-of-type,
.card-body.p-0 .table tbody > tr > th:first-of-type,
.card-body.p-0 .table tbody > tr > td:first-of-type {
padding-left: 1.5rem;
padding-left: 1rem;
}
/* line 69, ../../../sass/backend/adminlte/_table.scss */
.card-body.p-0 .table thead > tr > th:last-of-type,
.card-body.p-0 .table thead > tr > td:last-of-type,
.card-body.p-0 .table tbody > tr > th:last-of-type,
.card-body.p-0 .table tbody > tr > td:last-of-type {
padding-right: 1.5rem;
padding-right: 0.5rem;
}

/* line 6, ../../../sass/backend/adminlte/_carousel.scss */

+ 8
- 0
ShopBundle/Resources/public/css/backend/adminlte/plugins/select2/select2-bootstrap.min.css
File diff soppresso perché troppo grande
Vedi File


+ 220
- 109
ShopBundle/Resources/public/css/backend/custom.css Vedi File

@@ -57,123 +57,176 @@ body {
margin-bottom: 0px;
}

/* line 32, ../../sass/backend/custom.scss */
a.link-as-text {
color: #333;
}

/***************************************** ADMIN SIDEBAR ***************************************/
/* line 34, ../../sass/backend/custom.scss */
/* line 36, ../../sass/backend/custom.scss */
.main-sidebar p {
font-size: 0.8rem;
}

/* line 35, ../../sass/backend/custom.scss */
/* line 37, ../../sass/backend/custom.scss */
.main-sidebar .sidebar {
padding-left: 0px;
padding-right: 0px;
margin-top: 57px;
padding-top: 114px;
}

/* line 36, ../../sass/backend/custom.scss */
/* line 38, ../../sass/backend/custom.scss */
.main-sidebar .nav-link {
padding: .4rem .5rem .4rem .7rem;
}

/* line 40, ../../sass/backend/custom.scss */
body#pdl-body .wrapper .main-sidebar {
bottom: 0;
float: none;
height: 100vh;
left: 0;
position: fixed;
top: 0;
}

/* line 41, ../../sass/backend/custom.scss */
body#pdl-body .wrapper .content-wrapper {
margin-top: 0;
padding-top: 57px;
}

/* line 42, ../../sass/backend/custom.scss */
.sidebar {
overflow-y: auto;
}

/* line 45, ../../sass/backend/custom.scss */
#lc-flash-messages {
display: none;
}

/* line 43, ../../sass/backend/custom.scss */
/* line 47, ../../sass/backend/custom.scss */
.main-sidebar .logo-long {
padding: 8px 0;
text-align: center;
}

/* line 44, ../../sass/backend/custom.scss */
/* line 48, ../../sass/backend/custom.scss */
.main-sidebar .logo-long img {
height: 40px;
display: inline-block;
}

/* line 45, ../../sass/backend/custom.scss */
/* line 49, ../../sass/backend/custom.scss */
.sidebar-collapse .main-sidebar .logo-long span {
display: none;
}

/* line 46, ../../sass/backend/custom.scss */
/* line 50, ../../sass/backend/custom.scss */
.sidebar-collapse .main-sidebar:hover .logo-long span {
display: inline-block;
}

/* line 48, ../../sass/backend/custom.scss */
/* line 52, ../../sass/backend/custom.scss */
.table.datatable-simple .highlight {
background: var(--teal);
}

/* line 49, ../../sass/backend/custom.scss */
/* line 53, ../../sass/backend/custom.scss */
.datatable-field-search.small {
width: 50px;
}

/* line 51, ../../sass/backend/custom.scss */
/* line 55, ../../sass/backend/custom.scss */
.dataTables_length, .dataTables_filter {
padding: .75rem 1.25rem 0.25rem;
}

/* line 53, ../../sass/backend/custom.scss */
/* line 57, ../../sass/backend/custom.scss */
table.fixedHeader-floating {
margin-top: 0px !important;
}

/* line 54, ../../sass/backend/custom.scss */
/* line 58, ../../sass/backend/custom.scss */
table th.sorting_asc, table th.sorting_desc {
border-top: 3px solid var(--success);
}

/* line 55, ../../sass/backend/custom.scss */
/* line 59, ../../sass/backend/custom.scss */
.card-body table.lc-table-list th.sorted, table th.sorting_asc, table th.sorting_desc {
border-top: 2px solid var(--success);
}

/*.card-body table.lc-table-list th{border-top:3px solid var(--success);}*/
/* line 61, ../../sass/backend/custom.scss */
table th.filtered {
border-top: 3px solid var(--primary);
}

/* line 57, ../../sass/backend/custom.scss */
td.actions {
/* line 64, ../../sass/backend/custom.scss */
.lc-table-list thead a {
color: #212529;
}

/* line 65, ../../sass/backend/custom.scss */
.table-filters-line th {
font-weight: 400;
position: relative;
}

/* line 67, ../../sass/backend/custom.scss */
#list_filter_id {
width: 60px;
}

/* line 68, ../../sass/backend/custom.scss */
.lc-table-list .date-range {
width: 130px;
}

/* line 70, ../../sass/backend/custom.scss */
th.actions, td.actions {
white-space: nowrap;
text-align: right;
}

/* line 59, ../../sass/backend/custom.scss */
/* line 72, ../../sass/backend/custom.scss */
.table td, .table th {
padding: 0.35rem;
}

/* line 60, ../../sass/backend/custom.scss */
/* line 73, ../../sass/backend/custom.scss */
.delivery-field .form-group {
display: inline-block;
margin-bottom: 0px;
margin-right: 15px;
}

/* line 61, ../../sass/backend/custom.scss */
/* line 74, ../../sass/backend/custom.scss */
.delivery-field .form-group .form-control {
width: 150px;
}

/* line 63, ../../sass/backend/custom.scss */
/* line 76, ../../sass/backend/custom.scss */
table th input {
width: auto;
}

/* line 64, ../../sass/backend/custom.scss */
/* line 77, ../../sass/backend/custom.scss */
table th .select2-container--default .select2-selection--single {
padding: 0.3rem 0.4rem;
}

/************************ LOGIN PAGE *********************/
/* line 67, ../../sass/backend/custom.scss */
/* line 80, ../../sass/backend/custom.scss */
.login-logo {
display: block;
margin: auto;
}

/************************ form error *********************/
/* line 70, ../../sass/backend/custom.scss */
/* line 83, ../../sass/backend/custom.scss */
.form-sent .form-control:invalid {
border-color: #dc3545;
padding-right: 2.25rem;
@@ -183,19 +236,19 @@ table th .select2-container--default .select2-selection--single {
background-size: calc(.75em + .375rem) calc(.75em + .375rem);
}

/* line 71, ../../sass/backend/custom.scss */
/* line 84, ../../sass/backend/custom.scss */
.form-sent select.form-control:invalid + .select2 .select2-selection {
border-color: #dc3545;
}

/* line 72, ../../sass/backend/custom.scss */
/* line 85, ../../sass/backend/custom.scss */
.form-sent select.form-control:invalid + .select2 .select2-selection b {
border-color: #dc3545 transparent transparent transparent;
}

/*CUSTOM Checkbox
/* Customize the label (the container) */
/* line 77, ../../sass/backend/custom.scss */
/* line 90, ../../sass/backend/custom.scss */
.form-check-label {
display: block;
position: relative;
@@ -208,7 +261,7 @@ table th .select2-container--default .select2-selection--single {
}

/* Hide the browser's default checkbox */
/* line 79, ../../sass/backend/custom.scss */
/* line 92, ../../sass/backend/custom.scss */
.form-check-label input {
position: absolute;
opacity: 0;
@@ -218,22 +271,22 @@ table th .select2-container--default .select2-selection--single {
}

/* Create a custom checkbox */
/* line 82, ../../sass/backend/custom.scss */
/* line 95, ../../sass/backend/custom.scss */
.form-check {
padding-left: 0px;
}

/* line 84, ../../sass/backend/custom.scss */
/* line 97, ../../sass/backend/custom.scss */
.form-sent .form-check-label input:invalid ~ .checkmark {
border-color: #dc3545;
}

/* line 85, ../../sass/backend/custom.scss */
/* line 98, ../../sass/backend/custom.scss */
.form-check-label input:disabled ~ .checkmark {
display: none;
}

/* line 86, ../../sass/backend/custom.scss */
/* line 99, ../../sass/backend/custom.scss */
.form-check-label input ~ .checkmark {
position: absolute;
top: 0;
@@ -244,36 +297,36 @@ table th .select2-container--default .select2-selection--single {
border: 1px solid var(--primary);
}

/* line 87, ../../sass/backend/custom.scss */
/* line 100, ../../sass/backend/custom.scss */
.form-check-label.big input ~ .checkmark {
height: 21px;
width: 21px;
}

/* line 88, ../../sass/backend/custom.scss */
/* line 101, ../../sass/backend/custom.scss */
.form-check-label input[type="checkbox"] ~ .checkmark {
top: 2px;
}

/* line 89, ../../sass/backend/custom.scss */
/* line 102, ../../sass/backend/custom.scss */
.form-check-label input[type="radio"] ~ .checkmark {
top: 3px;
border-radius: 50%;
}

/* line 90, ../../sass/backend/custom.scss */
/* line 103, ../../sass/backend/custom.scss */
.form-check-label:hover input ~ .checkmark {
background-color: #ccc;
}

/* When the checkbox is checked, add a blue background */
/* line 92, ../../sass/backend/custom.scss */
/* line 105, ../../sass/backend/custom.scss */
.form-check-label input:checked ~ .checkmark {
background-color: var(--primary);
}

/* Create the checkmark/indicator (hidden when not checked) */
/* line 94, ../../sass/backend/custom.scss */
/* line 107, ../../sass/backend/custom.scss */
.form-check-label .checkmark:after {
content: "";
position: absolute;
@@ -281,13 +334,13 @@ table th .select2-container--default .select2-selection--single {
}

/* Show the checkmark when checked */
/* line 96, ../../sass/backend/custom.scss */
/* line 109, ../../sass/backend/custom.scss */
.form-check-label input:checked ~ .checkmark:after {
display: block;
}

/* Style the checkmark/indicator */
/* line 98, ../../sass/backend/custom.scss */
/* line 111, ../../sass/backend/custom.scss */
.form-check-label .checkmark:after {
left: 7px;
top: 3px;
@@ -300,7 +353,7 @@ table th .select2-container--default .select2-selection--single {
transform: rotate(45deg);
}

/* line 99, ../../sass/backend/custom.scss */
/* line 112, ../../sass/backend/custom.scss */
.form-check-label input[type="checkbox"] ~ .checkmark:after {
left: 6px;
top: 2px;
@@ -313,7 +366,7 @@ table th .select2-container--default .select2-selection--single {
transform: rotate(45deg);
}

/* line 100, ../../sass/backend/custom.scss */
/* line 113, ../../sass/backend/custom.scss */
.form-check-label input[type="radio"] ~ .checkmark:after {
top: 4px;
left: 4px;
@@ -323,7 +376,7 @@ table th .select2-container--default .select2-selection--single {
background: white;
}

/* line 102, ../../sass/backend/custom.scss */
/* line 115, ../../sass/backend/custom.scss */
.form-check-label.big input[type="checkbox"] ~ .checkmark:after {
left: 7px;
top: 3px;
@@ -332,100 +385,101 @@ table th .select2-container--default .select2-selection--single {
}

/* Create a custom radio button */
/* line 106, ../../sass/backend/custom.scss */
/* line 119, ../../sass/backend/custom.scss */
.product-categories .parent .form-group.field-checkbox .form-check-label {
padding-left: 0px;
font-style: italic;
}

/* line 107, ../../sass/backend/custom.scss */
/* line 120, ../../sass/backend/custom.scss */
.product-categories .children .form-group.field-checkbox {
margin-left: 20px;
}

/* line 108, ../../sass/backend/custom.scss */
/* line 121, ../../sass/backend/custom.scss */
.product-categories .form-group {
margin-bottom: 0.15rem;
}

/* line 109, ../../sass/backend/custom.scss */
/* line 122, ../../sass/backend/custom.scss */
.lc-deleted-field {
display: none;
}

/* line 110, ../../sass/backend/custom.scss */
/* line 123, ../../sass/backend/custom.scss */
.lc-offline-field {
opacity: 0.5;
}

/* line 111, ../../sass/backend/custom.scss */
/* line 124, ../../sass/backend/custom.scss */
.lc-offline-field label::after {
content: ' [hors ligne]';
}

/* Général */
/* line 117, ../../sass/backend/custom.scss */
.btn.btn-primary.action-save {
/* line 130, ../../sass/backend/custom.scss */
.btn.action-save {
float: right;
margin-left: 10px;
}

/* line 118, ../../sass/backend/custom.scss */
/* line 131, ../../sass/backend/custom.scss */
.button-action a.float-right {
margin-left: 10px;
}

/* line 120, ../../sass/backend/custom.scss */
/* line 133, ../../sass/backend/custom.scss */
.input-group-text {
padding: 0.25rem 0.75rem;
}

/* line 124, ../../sass/backend/custom.scss */
/* line 137, ../../sass/backend/custom.scss */
.col-form-label {
font-weight: bold;
}

/* line 126, ../../sass/backend/custom.scss */
/* line 139, ../../sass/backend/custom.scss */
#toast-container.toast-top-right {
top: 60px;
}

/* SIDEBAR */
/* line 129, ../../sass/backend/custom.scss */
/* line 142, ../../sass/backend/custom.scss */
.main-header.navbar {
padding: 0;
min-height: 57px;
}

/* line 130, ../../sass/backend/custom.scss */
/* line 143, ../../sass/backend/custom.scss */
.lc-navbar li {
border-left: 1px solid #e0e0e0;
padding: 0.5rem 1.5rem;
}

/* line 131, ../../sass/backend/custom.scss */
/* line 144, ../../sass/backend/custom.scss */
.lc-navbar li label {
margin-bottom: 0;
vertical-align: middle;
font-weight: normal !important;
}

/* line 133, ../../sass/backend/custom.scss */
/* line 146, ../../sass/backend/custom.scss */
#switch-merchant {
min-width: 170px;
}

/* Sortable */
/* line 139, ../../sass/backend/custom.scss */
/* line 152, ../../sass/backend/custom.scss */
.ui-sortable-helper {
display: table;
}

/* line 140, ../../sass/backend/custom.scss */
/* line 153, ../../sass/backend/custom.scss */
.ui-state-highlight {
background: #eee;
}

/* line 141, ../../sass/backend/custom.scss */
/* line 154, ../../sass/backend/custom.scss */
.lc-sortable div:last-child {
display: none;
}
@@ -442,13 +496,13 @@ table th .select2-container--default .select2-selection--single {
.lc-ckfinder-wrap .lc-ckfinder-button{width: 100%; bottom: 0px; left: 0; position: absolute;}
*/
/* VUES JS */
/* line 156, ../../sass/backend/custom.scss */
/* line 169, ../../sass/backend/custom.scss */
.nav-item .btn {
padding-right: 15px;
position: relative;
}

/* line 157, ../../sass/backend/custom.scss */
/* line 170, ../../sass/backend/custom.scss */
.nav-item .btn .invalid-form {
display: none;
position: absolute;
@@ -460,67 +514,67 @@ table th .select2-container--default .select2-selection--single {
font-size: 1.2rem;
}

/* line 158, ../../sass/backend/custom.scss */
/* line 171, ../../sass/backend/custom.scss */
.nav-item.has-invalid .btn .invalid-form {
display: inline-block;
z-index: 2;
}

/* ProductFamily */
/* line 163, ../../sass/backend/custom.scss */
/* line 176, ../../sass/backend/custom.scss */
.field-unit-quantity {
border-bottom: 2px dotted #eee;
padding-bottom: 10px;
margin-bottom: 20px;
}

/* line 164, ../../sass/backend/custom.scss */
/* line 177, ../../sass/backend/custom.scss */
.field-reduction-apply {
border-top: 2px dotted #eee;
padding-top: 10px;
margin-top: 20px;
}

/* line 166, ../../sass/backend/custom.scss */
/* line 179, ../../sass/backend/custom.scss */
.new-productfamily #nav-params,
.edit-productfamily #nav-params {
margin-bottom: 30px;
}

/* line 171, ../../sass/backend/custom.scss */
/* line 184, ../../sass/backend/custom.scss */
.new-productfamily #nav-params .btn,
.edit-productfamily #nav-params .btn {
margin-left: 20px;
}

/* line 176, ../../sass/backend/custom.scss */
/* line 189, ../../sass/backend/custom.scss */
.new-productfamily #product-categories .row,
.edit-productfamily #product-categories .row {
padding: 10px;
}

/* line 181, ../../sass/backend/custom.scss */
/* line 194, ../../sass/backend/custom.scss */
.new-productfamily #product-categories .form-group,
.edit-productfamily #product-categories .form-group {
width: 100%;
padding: 4px;
}

/* line 187, ../../sass/backend/custom.scss */
/* line 200, ../../sass/backend/custom.scss */
.new-productfamily #product-categories .children,
.edit-productfamily #product-categories .children {
margin-left: 20px;
width: 100%;
}

/* line 193, ../../sass/backend/custom.scss */
/* line 206, ../../sass/backend/custom.scss */
.new-productfamily ul.products,
.edit-productfamily ul.products {
padding: 0px;
list-style-type: none;
}

/* line 199, ../../sass/backend/custom.scss */
/* line 212, ../../sass/backend/custom.scss */
.new-productfamily ul.products li.product,
.edit-productfamily ul.products li.product {
padding: 0px;
@@ -528,25 +582,55 @@ table th .select2-container--default .select2-selection--single {
position: relative;
}

/* line 206, ../../sass/backend/custom.scss */
/* line 219, ../../sass/backend/custom.scss */
.new-productfamily ul.products li.add,
.edit-productfamily ul.products li.add {
text-align: right;
}

/* line 211, ../../sass/backend/custom.scss */
/* line 224, ../../sass/backend/custom.scss */
.autoresize textarea {
height: auto;
min-height: 38px;
}

/* line 226, ../../sass/backend/custom.scss */
.field-price .input-group.buyingPrice input, .field-price .input-group.buyingPrice .input-group-text {
font-weight: bold;
border-color: #222;
}

/* line 227, ../../sass/backend/custom.scss */
.field-price .input-group.buyingPriceByRefUnit input, .field-price .input-group.buyingPriceByRefUnit .input-group-text {
font-weight: bold;
border-color: #222;
}

/* line 228, ../../sass/backend/custom.scss */
.field-price .input-group.priceWithTax input, .field-price .input-group.priceWithTax .input-group-text {
font-weight: bold;
border-color: #222;
}

/* line 229, ../../sass/backend/custom.scss */
.field-price .input-group.priceByRefUnitWithTax input, .field-price .input-group.priceByRefUnitWithTax .input-group-text {
font-weight: bold;
border-color: #222;
}

/* line 230, ../../sass/backend/custom.scss */
.input-group.multiplyingFactor input, .input-group.multiplyingFactor .input-group-text {
font-weight: bold;
border-color: #222;
}

/* ORDER */
/* line 217, ../../sass/backend/custom.scss */
/* line 236, ../../sass/backend/custom.scss */
.table-order-summary {
width: 100%;
}

/* line 220, ../../sass/backend/custom.scss */
/* line 239, ../../sass/backend/custom.scss */
.order-product-item.redelivery {
background: rgba(18, 104, 253, 0.38) !important;
}
@@ -554,36 +638,36 @@ table th .select2-container--default .select2-selection--single {
/*.select2-container--bootstrap .select2-selection{max-width: none;}*/
/*.order-product-item{margin: 15px 0; padding: 0;}*/
/* Product */
/* line 225, ../../sass/backend/custom.scss */
/* line 244, ../../sass/backend/custom.scss */
.product-form-modal {
display: none;
}

/* line 226, ../../sass/backend/custom.scss */
/* line 245, ../../sass/backend/custom.scss */
.product-form.modal .form-check-label {
font-style: italic;
color: #666;
text-align: left;
}

/* line 227, ../../sass/backend/custom.scss */
/* line 246, ../../sass/backend/custom.scss */
.products-collection-table .inherited {
color: #888;
font-style: italic;
font-weight: initial;
}

/* line 228, ../../sass/backend/custom.scss */
/* line 247, ../../sass/backend/custom.scss */
.products-collection-table td {
position: relative;
}

/* line 229, ../../sass/backend/custom.scss */
/* line 248, ../../sass/backend/custom.scss */
.card-body.p-0 .products-collection-table tbody > tr > td:first-of-type, .card-body.p-0 .products-collection-table tbody > tr > th:first-of-type, .card-body.p-0 .products-collection-table thead > tr > td:first-of-type, .card-body.p-0 .products-collection-table thead > tr > th:first-of-type {
padding-left: 0.35rem;
}

/* line 230, ../../sass/backend/custom.scss */
/* line 249, ../../sass/backend/custom.scss */
.products-collection-table .btn-empty-field {
position: absolute;
right: 3px;
@@ -592,61 +676,65 @@ table th .select2-container--default .select2-selection--single {
padding: 0px;
}

/* line 231, ../../sass/backend/custom.scss */
/* line 250, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table {
table-layout: fixed;
/* background-clip: padding-box;*/
border-collapse: collapse;
}

/* line 232, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table tr {
border-bottom: 1px solid #dee2e6;
}

/* line 233, ../../sass/backend/custom.scss */
/* line 251, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table th {
font-size: 13px;
border-left: 1px solid #dee2e6;
border-top: 1px solid #dee2e6;
text-align: center;
border-bottom: 2px solid #dee2e6;
}

/* line 234, ../../sass/backend/custom.scss */
/* line 252, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table tfoot th {
border-top: 2px solid #dee2e6;
}

/* line 253, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table th span {
white-space: initial;
}

/* line 235, ../../sass/backend/custom.scss */
/* line 254, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table th:last-child {
border-right: 1px solid #dee2e6;
}

/* line 236, ../../sass/backend/custom.scss */
/* line 255, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table td {
border-left: 1px solid #dee2e6;
text-align: center;
font-size: 13px;
border-bottom: 1px solid #dee2e6;
}

/* line 237, ../../sass/backend/custom.scss */
/* line 256, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table td:last-child {
border-right: 1px solid #dee2e6;
white-space: nowrap;
}

/* line 238, ../../sass/backend/custom.scss */
/* line 257, ../../sass/backend/custom.scss */
#lc-product-family-edit .btn-add-product {
margin: 20px 0;
float: right;
}

/* line 239, ../../sass/backend/custom.scss */
/* line 258, ../../sass/backend/custom.scss */
#lc-product-family-edit .inherited {
color: #888;
font-style: italic;
font-weight: initial;
}

/* line 240, ../../sass/backend/custom.scss */
/* line 259, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table td .value {
min-width: 80%;
margin: auto;
@@ -654,62 +742,79 @@ table th .select2-container--default .select2-selection--single {
cursor: pointer;
}

/* line 241, ../../sass/backend/custom.scss */
/* line 260, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table td .modal {
text-align: left;
}

/* line 261, ../../sass/backend/custom.scss */
table.products-collection-table th.main-info, td.buyingPrice, td.multiplyingFactor, td.priceWithTax {
background: #eeeeee;
background-clip: padding-box;
text-decoration: underline;
}

/* line 263, ../../sass/backend/custom.scss */
table.products-collection-table tr.disabled {
opacity: 0.5;
}

/* line 264, ../../sass/backend/custom.scss */
.table-striped tbody .tr-sep {
border-top: 2px solid #888;
}

/* DeliveryZone */
/* line 245, ../../sass/backend/custom.scss */
/* line 268, ../../sass/backend/custom.scss */
#autocomplete-cities {
position: relative;
}

/* line 249, ../../sass/backend/custom.scss */
/* line 272, ../../sass/backend/custom.scss */
#autocomplete-cities .ui-autocomplete {
left: 30%;
top: 41px;
margin-left: 18px;
}

/* line 255, ../../sass/backend/custom.scss */
/* line 278, ../../sass/backend/custom.scss */
.head-reminders {
margin-top: 15px;
}

/* TABLEAU DE BORD */
/* line 258, ../../sass/backend/custom.scss */
/* line 281, ../../sass/backend/custom.scss */
.todo-list > li {
position: relative;
}

/* line 259, ../../sass/backend/custom.scss */
/* line 282, ../../sass/backend/custom.scss */
.todo-list > li .text {
margin-left: 30px;
}

/* line 260, ../../sass/backend/custom.scss */
/* line 283, ../../sass/backend/custom.scss */
.todo-list > li .tools {
position: absolute;
top: 4px;
right: 15px;
}

/* line 262, ../../sass/backend/custom.scss */
/* line 285, ../../sass/backend/custom.scss */
#addTicketMessageForm {
margin-top: 30px;
border-top: 2px dotted #eee;
padding-top: 30px;
}

/* line 264, ../../sass/backend/custom.scss */
/* line 287, ../../sass/backend/custom.scss */
#dashboard .list-btn-statistic {
display: flex;
flex-wrap: wrap;
justify-content: center;
}

/* line 265, ../../sass/backend/custom.scss */
/* line 288, ../../sass/backend/custom.scss */
#dashboard .btn-statistic {
width: 120px;
height: 70px;
@@ -718,13 +823,19 @@ table th .select2-container--default .select2-selection--single {
line-height: 1rem;
}

/* line 266, ../../sass/backend/custom.scss */
/* line 289, ../../sass/backend/custom.scss */
#dashboard .btn-statistic small {
margin-bottom: 10px;
display: block;
}

/* line 267, ../../sass/backend/custom.scss */
/* line 290, ../../sass/backend/custom.scss */
#dashboard .btn-statistic .value {
display: block;
}

/* Tickets */
/* line 296, ../../sass/backend/custom.scss */
#ticket-list .btn-sm {
display: block;
}

+ 1
- 0
ShopBundle/Resources/public/js/backend/plugin/autocomplete/bootstrap-autocomplete.min.js
File diff soppresso perché troppo grande
Vedi File


+ 2
- 0
ShopBundle/Resources/public/js/backend/plugin/select2/select2.full.min.js
File diff soppresso perché troppo grande
Vedi File


+ 37
- 20
ShopBundle/Resources/public/js/backend/script/default/init-common.js Vedi File

@@ -51,9 +51,9 @@ function setBootstrapSwitch($checkbox) {

function initAdminLtePlugin() {

$(".checkbox-switch input").each(function () {
/*$(".checkbox-switch input").each(function () {
setBootstrapSwitch($(this));
});
});*/

$('[data-toggle="tooltip"]').tooltip();

@@ -70,6 +70,7 @@ function initAdminLtePlugin() {
})

if ($('.select2, select.form-control').length) {

$('form .form-widget>select.form-control, .select2').each(function (i, elm) {
if (!$(this).hasClass('disable-select2')) {
setSelect2($(elm));
@@ -97,14 +98,11 @@ function initAdminLtePlugin() {
});


$('.date-time-range').each(function (i, picker) {
//log(moment('2020-04-05 20:00:00').format( "DD/MM/YYYY HH:mm"))
$('.date-time-range, .date-range').each(function (i, picker) {
options = {
timePicker: true,
timePickerIncrement: 30,
timePicker24Hour: true,
autoUpdateInput: false,
locale: {
"format": "DD/MM/YYYY HH:mm",
"format": "DD/MM/YY",
"separator": " - ",
"applyLabel": "Appliquer",
"cancelLabel": "Annuler",
@@ -116,19 +114,38 @@ function initAdminLtePlugin() {
"firstDay": 1
}
};

if ($(picker).hasClass('date-time-range')){
options = Object.assign(options, {
timePicker: true,
timePickerIncrement: 30,
timePicker24Hour: true,
locale: {
"format": "DD/MM/YYYY HH:mm",
}
});
}
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());
options.autoUpdateInput = true;
}
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());
options.autoUpdateInput = true;
}
$(picker).daterangepicker(options);
$(picker).on('apply.daterangepicker', function (ev, pickerElm) {
log($(picker).nextAll('.date-time-range-fields').find('.date-start'));
log(pickerElm.startDate.format('YYYY-MM-DD HH:mm'));
$(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'));
if ($(picker).hasClass('date-time-range')) {
$(this).val(pickerElm.startDate.format('DD/MM/YY HH:mm') + ' - ' + pickerElm.endDate.format(options.locale.format));
}else{
$(this).val(pickerElm.startDate.format('DD/MM/YY') + ' - ' + pickerElm.endDate.format(options.locale.format));
}
if ($(picker).hasClass('date-time-range')) {
$(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'));
}else{
$(picker).nextAll('.date-time-range-fields').find('.date-start').val(pickerElm.startDate.format('YYYY-MM-DD'));
$(picker).nextAll('.date-time-range-fields').find('.date-end').val(pickerElm.endDate.format('YYYY-MM-DD'));
}
});
});

@@ -160,6 +177,7 @@ function setSelect2($select) {
$select.data('init', 'set')
var options = {
width: "100%",
theme: "bootstrap",
dropdownAutoWidth: false,
allowClear: true,
minimumResultsForSearch: 8
@@ -193,8 +211,7 @@ function setSelect2($select) {
}



function initBtnEditReminder(){
function initBtnEditReminder() {
$('.btn-edit-reminder, .btn-add-reminder ').on('click', function () {
$btn = $(this);
var url = $(this).data('url');
@@ -205,7 +222,7 @@ function initBtnEditReminder(){
dataType: "json",
success: function (response) {
$('body').append(response.data);
if($btn.hasClass('btn-add-reminder')) {
if ($btn.hasClass('btn-add-reminder')) {
$('#reminder_entityName').val(getUrlParameter('entity'));
$('#reminder_entityId').val(getUrlParameter('id'));
$('#reminder_entityAction').val(getUrlParameter('action'));
@@ -218,10 +235,10 @@ function initBtnEditReminder(){

$('.checkbox-valid-reminder').on('change', function () {
var url = $(this).data('url');
if($(this).is(':checked')){
url = url+'&done=true'
}else{
url = url+'&done=false'
if ($(this).is(':checked')) {
url = url + '&done=true'
} else {
url = url + '&done=false'
}
$.ajax({
url: url,

+ 36
- 14
ShopBundle/Resources/public/js/backend/script/default/init-edit.js Vedi File

@@ -1,5 +1,4 @@
jQuery(document).ready(function () {
initLcCkEditor();
//generateNotice('error', 'Ceci est une notice');
$('.action-delete').on('click', function(e) {
e.preventDefault();
@@ -13,9 +12,13 @@ jQuery(document).ready(function () {
deleteForm.trigger('submit');
});
});
});


});

window.addEventListener('load', (event) => {
initLcCkEditor();
});
/* CKEditor */

function initLcCkEditor(){
@@ -23,18 +26,37 @@ function initLcCkEditor(){

if(elements.length) {
for (var i = 0; i < elements.length; ++i) {
var editor = CKEDITOR.replace(elements[i], {
"toolbar": [
{
name: "styles",
items: ["Format", 'Bold', 'Italic', 'Underline', 'Strike', "Link", "BulletedList"]
},
{name: 'paragraph', items: ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock']},
{name: 'insert', items: ['Image', 'SpecialChar']},
{name: "document", items: ["Source"]},
],
"language": "fr"
});
if($(elements[i]).data('config')==='simple_config'){
CKEDITOR.replace(elements[i], {
"toolbar": [
{
items: ['Bold', 'Italic', 'Underline', 'Strike']
},
{
items: ["TextColor"]
}
],
"language": "fr",
'height': 100
});
}else{
CKEDITOR.replace(elements[i], {
"toolbar": [
{
name: "styles",
items: ["Format", 'Bold', 'Italic', 'Underline', 'Strike', "Link", "BulletedList"]
},
{
items: ["TextColor"]
},
{name: 'paragraph', items: ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock']},
{name: 'insert', items: ['Image', 'SpecialChar']},
{name: "document", items: ["Source"]},
],
"language": "fr"
});
}

}
}
}

+ 202
- 0
ShopBundle/Resources/public/js/backend/script/default/init-list-datatable.js Vedi File

@@ -0,0 +1,202 @@
jQuery(document).ready(function () {
initDeleteAction();

initDataTable();


alert('niche');
});

function initDeleteAction() {

$('.action-delete').each(function (){
$(this).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');
});
});
});
}


function initDataTable() {
if ($(".table.datatable-simple").length > 0) {
//$(".table.datatable-simple thead tr").clone(true).appendTo( '.table.datatable-simple tfoot' );

$(".table.datatable-simple thead tr").clone(true).appendTo('.table.datatable-simple thead');
$(".table.datatable-simple thead tr:eq(1) th").each(function (i) {
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 + '" />');

$('input', this).on('keyup change', function () {
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')
}
if (table.column(i).search() !== this.value) {
table
.column(i)
.search(this.value)
.draw();
var searchVal = this.value;
var body = $(table.table().body());

body.unhighlight();
body.highlight(searchVal);
}
});
}else if ($(this).data('searchable') == "date") {
/* var title = $(this).text();

$(this).html('<input type="date" class="datatable-field-date date-start" /> <input type="date" class="datatable-field-date date-end" /> ');

$dateStart = $(this).find('.date-start');
$dateEnd = $(this).find('.date-end');
$('input', this).on('keyup change', function () {
table.draw();
});

$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
if($dateStart.val()!=="" || $dateEnd.val()!=="" ) {


var dateStart = parseInt(Date.parse($dateStart.val()));
var dateEnd = parseInt(Date.parse($dateEnd.val()));

currentDate = parseInt($('td.date').eq(dataIndex).find('time').data('timestamp'));
log(dateStart);
log(currentDate);
log($('td.date').eq(dataIndex));

return true;
if (((dateStart !== null && currentDate >= dateStart) || dateStart == null) && ((dateEnd !== null && dateEnd >= currentDate) || dateEnd == null)) {
return true;
} else {
return false;
}
}else{
return true;
}
}
);*/


/*$('input', this).on('keyup change', function () {
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')
}
if (table.column(i).search() !== this.value) {
table
.column(i)
.search(this.value)
.draw();
var searchVal = this.value;
var body = $( table.table().body() );

body.unhighlight();
body.highlight(searchVal);
}
});*/
} 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
} else {
$(this).html('')
}
});

var table = $(".table.datatable-simple").DataTable({
orderCellsTop: true,
pageLength: 50,
fixedHeader: {
header: true,
headerOffset: $('.main-header').outerHeight(),
},
paging: true,
//responsive: true,
initComplete: function () {
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) {
select = $('.table.datatable-simple thead tr:eq(1) th:eq(' + i + ') select.list-text');
}
if(select.length) {
column.data().unique().sort().each(function (d, j) {
values = d.split('\n');
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) {
column.data().unique().sort().each(function (d, j) {
$(d).each(function (k, val) {

select.append('<option value="' + $(val).text().trim() + '">' + $(val).text().trim() + '</option>')
});
});
setSelect2(select);
select.on( 'change', function () {
var val = $(this).val();
if(val=="all"){
$('.table.datatable-simple thead tr:eq(0) th:eq('+i+')').removeClass('filtered')
column.search('').draw();
}else {
$('.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",
"sLoadingRecords": "Chargement...",
"sProcessing": "Traitement...",
"sSearch": "Rechercher :",
"sZeroRecords": "Aucun élément correspondant trouvé",
"oPaginate": {
"sFirst": "Premier",
"sLast": "Dernier",
"sNext": "Suivant",
"sPrevious": "Précédent"
},
"oAria": {
"sSortAscending": ": activer pour trier la colonne par ordre croissant",
"sSortDescending": ": activer pour trier la colonne par ordre décroissant"
},
"select": {
"rows": {
"_": "%d lignes sélectionnées",
"0": "Aucune ligne sélectionnée",
"1": "1 ligne sélectionnée"
}
}
},
});
}
}

+ 34
- 173
ShopBundle/Resources/public/js/backend/script/default/init-list.js Vedi File

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

initDataTable();

initResetFilters();

initAutocompleteField();

initDropdown();
});

function initDeleteAction() {

$('.action-delete').each(function (){
$('.action-delete').each(function () {
$(this).on('click', function (e) {
e.preventDefault();
const id = $(this).parents('tr').first().data('id');
@@ -26,177 +27,37 @@ function initDeleteAction() {
}


function initDataTable() {
if ($(".table.datatable-simple").length > 0) {
//$(".table.datatable-simple thead tr").clone(true).appendTo( '.table.datatable-simple tfoot' );

$(".table.datatable-simple thead tr").clone(true).appendTo('.table.datatable-simple thead');
$(".table.datatable-simple thead tr:eq(1) th").each(function (i) {
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 + '" />');

$('input', this).on('keyup change', function () {
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')
}
if (table.column(i).search() !== this.value) {
table
.column(i)
.search(this.value)
.draw();
var searchVal = this.value;
var body = $(table.table().body());

body.unhighlight();
body.highlight(searchVal);
}
});
}else if ($(this).data('searchable') == "date") {
/* var title = $(this).text();

$(this).html('<input type="date" class="datatable-field-date date-start" /> <input type="date" class="datatable-field-date date-end" /> ');

$dateStart = $(this).find('.date-start');
$dateEnd = $(this).find('.date-end');
$('input', this).on('keyup change', function () {
table.draw();
});

$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
if($dateStart.val()!=="" || $dateEnd.val()!=="" ) {


var dateStart = parseInt(Date.parse($dateStart.val()));
var dateEnd = parseInt(Date.parse($dateEnd.val()));

currentDate = parseInt($('td.date').eq(dataIndex).find('time').data('timestamp'));
log(dateStart);
log(currentDate);
log($('td.date').eq(dataIndex));

return true;
if (((dateStart !== null && currentDate >= dateStart) || dateStart == null) && ((dateEnd !== null && dateEnd >= currentDate) || dateEnd == null)) {
return true;
} else {
return false;
}
}else{
return true;
}
}
);*/


/*$('input', this).on('keyup change', function () {
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')
}
if (table.column(i).search() !== this.value) {
table
.column(i)
.search(this.value)
.draw();
var searchVal = this.value;
var body = $( table.table().body() );

body.unhighlight();
body.highlight(searchVal);
}
});*/
} 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
} else {
$(this).html('')
function initResetFilters() {
$('.lc-reset-filters').on('click', function () {
$(this).parents('form').find('.form-control').val('').trigger('change');

})

}

function initAutocompleteField() {


var autocompleteFields = $('[data-lc-autocomplete-url]');

autocompleteFields.each(function () {
var $this = $(this),
url = $this.data('lc-autocomplete-url');

$this.autoComplete({
noResultsText: 'Aucun résultat n\'a été trouvé.',
resolverSettings: {
url: url
}
});
});
}

var table = $(".table.datatable-simple").DataTable({
orderCellsTop: true,
pageLength: 50,
fixedHeader: {
header: true,
headerOffset: $('.main-header').outerHeight(),
},
paging: true,
//responsive: true,
initComplete: function () {
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) {
select = $('.table.datatable-simple thead tr:eq(1) th:eq(' + i + ') select.list-text');
}
if(select.length) {
column.data().unique().sort().each(function (d, j) {
values = d.split('\n');
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) {
column.data().unique().sort().each(function (d, j) {
$(d).each(function (k, val) {

select.append('<option value="' + $(val).text().trim() + '">' + $(val).text().trim() + '</option>')
});
});
setSelect2(select);
select.on( 'change', function () {
var val = $(this).val();
if(val=="all"){
$('.table.datatable-simple thead tr:eq(0) th:eq('+i+')').removeClass('filtered')
column.search('').draw();
}else {
$('.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",
"sLoadingRecords": "Chargement...",
"sProcessing": "Traitement...",
"sSearch": "Rechercher :",
"sZeroRecords": "Aucun élément correspondant trouvé",
"oPaginate": {
"sFirst": "Premier",
"sLast": "Dernier",
"sNext": "Suivant",
"sPrevious": "Précédent"
},
"oAria": {
"sSortAscending": ": activer pour trier la colonne par ordre croissant",
"sSortDescending": ": activer pour trier la colonne par ordre décroissant"
},
"select": {
"rows": {
"_": "%d lignes sélectionnées",
"0": "Aucune ligne sélectionnée",
"1": "1 ligne sélectionnée"
}
}
},
});
}

function initDropdown(){
$('.dropdown-toggle').hover(function() {
$(this).find('.dropdown-menu').stop(true, true).delay(50).fadeIn();
}, function() {
$(this).find('.dropdown-menu').stop(true, true).delay(50).fadeOut();
});
}

+ 10
- 1
ShopBundle/Resources/public/js/backend/script/default/utils.js Vedi File

@@ -25,7 +25,7 @@ function getMargin(price, buyingPrice){
}

function getMarginPercent(price, buyingPrice){
return parseFloat(((price - buyingPrice) / buyingPrice) * 100).toFixed(2);
return parseFloat(((price - buyingPrice) / price) * 100).toFixed(2);
}

function applyReductionPercent(price, percentage)
@@ -188,3 +188,12 @@ function checkFormValidity(formId){
return true;
}
}


function arrayRemove(arr, value) { return arr.filter(function(ele){ return ele != value; });}

const scratchDiv = document.createElement('div');
function toPlainText(html) {
scratchDiv.innerHTML = html;
return scratchDiv.textContent;
}

+ 21
- 3
ShopBundle/Resources/public/js/backend/script/default/vuejs-mixins.js Vedi File

@@ -18,10 +18,18 @@ let mixinPrice = {
},
computed: {
marginProfit: function () {
return getMargin(this.priceValue,this.buyingPriceValue);
if (this.behaviorPriceValue == 'by-piece') {
return getMargin(this.priceValue,this.buyingPriceValue);
} else if (this.behaviorPriceValue == 'by-reference-unit') {
return getMargin(this.finalPrice,this.finalBuyingPrice);
}
},
marginProfitPercent:function () {
return getMarginPercent(this.priceValue, this.buyingPriceValue);
if (this.behaviorPriceValue == 'by-piece') {
return getMarginPercent(this.priceValue,this.buyingPriceValue);
} else if (this.behaviorPriceValue == 'by-reference-unit') {
return getMarginPercent(this.finalPrice,this.finalBuyingPrice);
}
},
marginProfitWithReduction: function () {
var price = this.$parent.applyReduction(this.priceValue, this.priceWithTaxValue, this.taxRateValue, false);
@@ -31,11 +39,17 @@ let mixinPrice = {
var price = this.$parent.applyReduction(this.priceValue, this.priceWithTaxValue, this.taxRateValue, false);
return getMarginPercent(price, this.buyingPriceValue);
},
finalPrice: function () {
return parseFloat((this.priceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(4);
},
finalPriceWithTax: function () {
return getPriceWithTax(parseFloat((this.priceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(4), this.taxRateValue);
},
finalPriceWithTaxAndReduction(){
return this.$parent.applyReduction(this.priceValue, this.priceWithTaxValue, this.taxRateValue, true);
},
finalBuyingPrice:function () {
return parseFloat((this.buyingPriceByRefUnitValue * this.quantityValue) / this.unitCoefficient).toFixed(4);
}

},
@@ -140,6 +154,7 @@ let mixinPrice = {


unitUpdated: function () {

this.quantityUpdated();
},
quantityUpdated: function () {
@@ -149,11 +164,13 @@ let mixinPrice = {
if (this.behaviorPriceValue == 'by-piece') {
this.setBuyingPriceByRefUnit();
this.setBuyingPriceByRefUnitWithTax();
log('ncihe');
this.setPriceByRefUnit();
this.setPriceByRefUnitWithTax();
} else if (this.behaviorPriceValue == 'by-reference-unit') {
this.setPriceFromPriceByRefUnit();
this.setPriceWithTax();

this.setBuyingPriceFromBuyingPriceByRefUnit();
this.setBuyingPriceWithTax();
}
@@ -253,7 +270,8 @@ let mixinPrice = {
this.priceInherited = true;
}
},
watch: {}
watch: {
}

}
;

+ 0
- 23
ShopBundle/Resources/public/js/backend/script/productfamily/init-edit.js Vedi File

@@ -1,23 +0,0 @@
jQuery(document).ready(function () {
initLcSortableProductsList();
});

function initLcSortableProductsList() {
if ($('.lc-sortable-products').length > 0) {
$('.lc-sortable-products tbody').sortable({
placeholder: "ui-state-highlight"
});
$('.lc-sortable-products tbody').on("sortupdate", function (event, ui) {
updateSortableProducts();
});
}
}


function updateSortableProducts() {
if ($('.lc-sortable-products').length > 0) {
$('.lc-sortable-products tr.lc-draggable').each(function (index, li) {
$(li).find('.field-position').val(index);
});
}
}

+ 557
- 449
ShopBundle/Resources/public/js/backend/script/productfamily/vuejs-product-family.js
File diff soppresso perché troppo grande
Vedi File


+ 2
- 2
ShopBundle/Resources/public/sass/backend/adminlte/_table.scss Vedi File

@@ -63,11 +63,11 @@
tbody > tr > th,
tbody > tr > td {
&:first-of-type {
padding-left: map-get($spacers, 4);
padding-left: map-get($spacers, 3);
}

&:last-of-type {
padding-right: map-get($spacers, 4);
padding-right: map-get($spacers,2);
}
}
}

+ 41
- 9
ShopBundle/Resources/public/sass/backend/custom.scss Vedi File

@@ -29,13 +29,17 @@ body{font-size: 0.9rem;}

.card-tools h5{margin-bottom: 0px;}

a.link-as-text{color:#333;}


/***************************************** ADMIN SIDEBAR ***************************************/
.main-sidebar p{font-size: 0.8rem;}
.main-sidebar .sidebar{padding-left: 0px; padding-right: 0px; margin-top: 57px;}
.main-sidebar .sidebar{padding-left: 0px; padding-right: 0px; padding-top: 114px;}
.main-sidebar .nav-link{padding: .4rem .5rem .4rem .7rem;}


body#pdl-body .wrapper .main-sidebar{bottom: 0; float: none; height: 100vh; left: 0; position: fixed; top: 0;}
body#pdl-body .wrapper .content-wrapper{margin-top: 0; padding-top: 57px;}
.sidebar{overflow-y: auto;}


#lc-flash-messages{display: none;}
@@ -52,9 +56,18 @@ body{font-size: 0.9rem;}

table.fixedHeader-floating{margin-top: 0px !important;}
table th.sorting_asc, table th.sorting_desc{border-top:3px solid var(--success);}
.card-body table.lc-table-list th.sorted, table th.sorting_asc, table th.sorting_desc{border-top:2px solid var(--success);}
/*.card-body table.lc-table-list th{border-top:3px solid var(--success);}*/
table th.filtered{border-top:3px solid var(--primary);}

td.actions{white-space: nowrap; text-align: right;}

.lc-table-list thead a{color: #212529}
.table-filters-line th {font-weight: 400; position: relative;}
.table-filters-line th input{}
#list_filter_id{width: 60px;}
.lc-table-list .date-range{width: 130px;}

th.actions, 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;}
@@ -114,7 +127,7 @@ table th .select2-container--default .select2-selection--single{padding:0.3rem 0


/* Général */
.btn.btn-primary.action-save{float: right;}
.btn.action-save{float: right; margin-left: 10px;}
.button-action a.float-right{margin-left: 10px;}

.input-group-text {
@@ -210,9 +223,15 @@ table th .select2-container--default .select2-selection--single{padding:0.3rem 0

.autoresize textarea{height: auto; min-height: 38px;}

.field-price .input-group.buyingPrice input,.field-price .input-group.buyingPrice .input-group-text{font-weight: bold; border-color: #222 }
.field-price .input-group.buyingPriceByRefUnit input,.field-price .input-group.buyingPriceByRefUnit .input-group-text{font-weight: bold; border-color: #222 }
.field-price .input-group.priceWithTax input,.field-price .input-group.priceWithTax .input-group-text{font-weight: bold; border-color: #222 }
.field-price .input-group.priceByRefUnitWithTax input,.field-price .input-group.priceByRefUnitWithTax .input-group-text{font-weight: bold; border-color: #222 }
.input-group.multiplyingFactor input,.input-group.multiplyingFactor .input-group-text{font-weight: bold; border-color: #222 }



/* ORDER */
/* ORDER */

.table-order-summary{width: 100%;}

@@ -228,17 +247,21 @@ table th .select2-container--default .select2-selection--single{padding:0.3rem 0
.products-collection-table td{position: relative;}
.card-body.p-0 .products-collection-table tbody > tr > td:first-of-type, .card-body.p-0 .products-collection-table tbody > tr > th:first-of-type, .card-body.p-0 .products-collection-table thead > tr > td:first-of-type, .card-body.p-0 .products-collection-table thead > tr > th:first-of-type{padding-left: 0.35rem;}
.products-collection-table .btn-empty-field{position: absolute; right: 3px; font-size: 0.7rem; top: 5px; padding: 0px;}
#lc-product-family-edit .products-collection-table {table-layout:fixed;}
#lc-product-family-edit .products-collection-table tr{border-bottom: 1px solid #dee2e6;}
#lc-product-family-edit .products-collection-table th{font-size:13px; border-left: 1px solid #dee2e6; border-top: 1px solid #dee2e6; text-align: center;}
#lc-product-family-edit .products-collection-table {table-layout:fixed;/* background-clip: padding-box;*/ border-collapse: collapse;}
#lc-product-family-edit .products-collection-table th{font-size:13px; border-left: 1px solid #dee2e6; border-top: 1px solid #dee2e6; text-align: center; border-bottom: 2px solid #dee2e6;}
#lc-product-family-edit .products-collection-table tfoot th{border-top: 2px solid #dee2e6;}
#lc-product-family-edit .products-collection-table th span {white-space: initial;}
#lc-product-family-edit .products-collection-table th:last-child{border-right: 1px solid #dee2e6;}
#lc-product-family-edit .products-collection-table td{border-left: 1px solid #dee2e6; text-align: center; font-size: 13px;}
#lc-product-family-edit .products-collection-table td{border-left: 1px solid #dee2e6; text-align: center; font-size: 13px; border-bottom: 1px solid #dee2e6;}
#lc-product-family-edit .products-collection-table td:last-child{border-right: 1px solid #dee2e6; white-space: nowrap; }
#lc-product-family-edit .btn-add-product {margin: 20px 0; float: right;}
#lc-product-family-edit .inherited {color: #888; font-style: italic; font-weight: initial;}
#lc-product-family-edit .products-collection-table td .value {min-width: 80%; margin: auto; min-height: 35px; cursor: pointer;}
#lc-product-family-edit .products-collection-table td .modal {text-align: left;}
table.products-collection-table th.main-info, td.buyingPrice, td.multiplyingFactor, td.priceWithTax{background: #eeeeee; background-clip: padding-box; text-decoration: underline;}

table.products-collection-table tr.disabled{opacity: 0.5}
.table-striped tbody .tr-sep{border-top: 2px solid #888; }

/* DeliveryZone */

@@ -265,3 +288,12 @@ table th .select2-container--default .select2-selection--single{padding:0.3rem 0
#dashboard .btn-statistic{ width: 120px; height: 70px; text-align: center; border: 1px solid black; line-height: 1rem; }
#dashboard .btn-statistic small{margin-bottom: 10px; display: block;}
#dashboard .btn-statistic .value{display: block;}


/* Tickets */

#ticket-list {
.btn-sm {
display: block ;
}
}

+ 23
- 5
ShopBundle/Resources/translations/lcshop.fr.yaml Vedi File

@@ -3,6 +3,7 @@ edit:
list:
title: Liste des %label%
nbResults: Total d'élements
nbResultsFiltered: Total d'élements filtrés
nbResultsOnline: Total d'élements en ligne
nbResultsOffline: Total d'élements hors ligne
nbResultsDeleted: Total d'élements supprimé
@@ -10,6 +11,8 @@ list:
edit: Éditer
delete: Supprimer
send: Envoyer
duplicate: Dupliquer
duplicateOtherHub: Dupliquer sur un autre hub

group:
main: Général
@@ -99,6 +102,10 @@ success:
ticket:
statusChange: Le status a bien été modifié
addMessage: Le message a bien été envoyé
common:
fieldChange: Le champ a bien été modifié
productFamily:
editStock: Le stock a bien été modifié
error:
form:
submitted: Une erreur est survenue à la soumission du formulaire
@@ -122,10 +129,11 @@ error:
groupUser: Le(s) groupe(s) utilisateurs ne correspondent pas
user: L'utilisateur ne correspond pas
combinable: La réduction n'est pas cumulable avec celle dejà appliqué
amountMin: Le montant minimum de commandes n'est pas respecté
amountMin: Le montant minimum de commande n'est pas respecté
qauntity: La réduction n'est plus disponible
quantityPerUser: La reduction n'est plus disponible pour cet utilisateur
alreadyInCart: La réduction a déjà été ajoutée à votre panier
quantity: La reduction n'est plus disponible
reductionCredit:
userNotAllow: Cet avoir n'est pas disponible pour cet utilisateur
alreadyUse: Cet avoir a déjà été utilisé
@@ -134,6 +142,8 @@ error:
debited: Une erreur est survenue, le crédit n'a pas été débité
notEnoughCredit: Le compte prépayé n'est pas suffisament allimenté
notAdded: Le crédit n'a pas été ajouté
productFamily:
editStock: Le stock n'a pas été modifié, une erreur est survenue
field:
default:
placeholder: Choisissez une option
@@ -306,8 +316,8 @@ field:
non-renewable: Non renouvelable
organicLabelOptions:
ab: Agriculture biologique
hVE: Haute valeur environnementale
natureProgres: Nature & progrès
hve: Haute valeur environnementale
nature-progres: Nature & progrès
behaviorExpirationDate: Gèrer
behaviorExpirationDateOptions:
by-product-family: Par produit
@@ -380,7 +390,7 @@ field:
quantityProduct: Quantité (en rapport à l'unité)
unit: Unité
redeliverySupplier: Erreur producteur
redeliverySupplierOrder: À rappeler au prochain bon de commande producteur
redeliverySupplierOrder: A recommander au producteur
deliveryType: Type de livraison
deliveryTypeOptions:
point-sale: En ambassade
@@ -427,22 +437,30 @@ field:


action:
apply: Appliquer
new: Créer %entity_label%
reset: Réinitialiser
switchMerchant: Votre hub
show: Voir
choiceFile: Parcourir
send: Envoyer
edit: Éditer
saveAndStay: Sauvegarder (rester sur la page)
search: Rechercher
delete: Supprimer
change: Modifier
save: Sauvegarder les modifications
save: Sauvegarder
saveGotoList: Sauvegarder (retour liste)
cancel: Annuler
continue: Continuer
list: Retour à la liste
deselect: Désélectionner
form.empty_value: Aucun(e)
add: Ajouter
valid: Valider
product:
editStock: Gérer les stocks
editProductFamily: Éditer le produit
user:
account: Mon compte
logout: Me déconnecter

+ 0
- 6
ShopBundle/Resources/views/backend/default/action.html.twig Vedi File

@@ -1,6 +0,0 @@

<a class="btn {{ is_dropdown|default(false) ? 'dropdown-item' }} {{ action.css_class|default('btn-default') }}" data-toggle="tooltip"
title="{{ action.label|trans(arguments = trans_parameters|merge({ '%entity_id%': item_id }), domain = translation_domain) }}"
href="{{ action_href }}" target="{{ action.target }}">
{%- if action.icon %}<i class="fa fa-fw fa-{{ action.icon }}"></i> {% endif -%}
</a>

+ 13
- 0
ShopBundle/Resources/views/backend/default/block/action.html.twig Vedi File

@@ -0,0 +1,13 @@

{% if is_dropdown %}
<a class="btn dropdown-item {{ action.css_class|default('btn-default') }}" href="{{ action_href }}" target="{{ action.target }}">
{%- if action.icon %}<i class="fa fa-fw fa-{{ action.icon }}"></i> {% endif -%}
{{ action.label|trans(arguments = trans_parameters|merge({ '%entity_id%': item_id }), domain = translation_domain) }}
</a>
{% else %}
<a class="btn {{ is_dropdown|default(false) ? 'dropdown-item' }} {{ action.css_class|default('btn-default') }}" data-toggle="tooltip"
title="{{ action.label|trans(arguments = trans_parameters|merge({ '%entity_id%': item_id }), domain = translation_domain) }}"
href="{{ action_href }}" target="{{ action.target }}">
{%- if action.icon %}<i class="fa fa-fw fa-{{ action.icon }}"></i> {% endif -%}
</a>
{% endif %}

+ 58
- 0
ShopBundle/Resources/views/backend/default/block/actions.html.twig Vedi File

@@ -0,0 +1,58 @@
{% set dropdownAction ={} %}
{% for action in actions %}


{% if action.group is defined and action.group==true %}
{% set dropdownAction = dropdownAction|merge({(loop.index0): action}) %}
{% else %}
{% if 'list' == action.name %}
{% set action_href = request_parameters.referer|default('') ? request_parameters.referer|easyadmin_urldecode : path('easyadmin', request_parameters|merge({ action: 'list' })) %}
{% elseif 'method' == action.type %}
{% set action_href = path('easyadmin', request_parameters|merge({ action: action.name, id: item_id })) %}
{% elseif 'route' == action.type %}
{% set action_href = path(action.name, request_parameters|merge({ action: action.name, id: item_id })) %}
{% endif %}

{{ include(action.template, {
action: action,
action_href: action_href,
is_dropdown: is_dropdown|default(false),
item: item,
item_id: item_id,
request_parameters: request_parameters,
translation_domain: translation_domain,
trans_parameters: trans_parameters,
}, with_context = false) }}
{% endif %}
{% endfor %}
{% if dropdownAction|length > 0 %}
<div class="btn-group">
<button type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-icon" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
<div class="dropdown-menu dropdown-menu-right" role="menu">
{% for action in dropdownAction %}

{% if 'list' == action.name %}
{% set action_href = request_parameters.referer|default('') ? request_parameters.referer|easyadmin_urldecode : path('easyadmin', request_parameters|merge({ action: 'list' })) %}
{% elseif 'method' == action.type %}
{% set action_href = path('easyadmin', request_parameters|merge({ action: action.name, id: item_id })) %}
{% elseif 'route' == action.type %}
{% set action_href = path(action.name, request_parameters|merge({ action: action.name, id: item_id })) %}
{% endif %}

{{ include(action.template, {
action: action,
action_href: action_href,
is_dropdown: true,
item: item,
item_id: item_id,
request_parameters: request_parameters,
translation_domain: translation_domain,
trans_parameters: trans_parameters,
}, with_context = false) }}
{% endfor %}
</div>
</button>
</div>

{% endif %}

+ 1
- 1
ShopBundle/Resources/views/backend/default/block/embed_modal.twig Vedi File

@@ -4,7 +4,7 @@
{% block form_start %}{% endblock %}
<div class="modal-content">
<div class="modal-header">
<h4>{% block title %}{% endblock %}</h4>
<h5>{% block title %}{% endblock %}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>

+ 2
- 0
ShopBundle/Resources/views/backend/default/block/form_address.html.twig Vedi File

@@ -57,4 +57,6 @@
{{ form_row(form.deliveryInfos) }}
</div>

{{ form_row(form.country) }}

</div>

+ 6
- 1
ShopBundle/Resources/views/backend/default/block/list_tickets.html.twig Vedi File

@@ -1,8 +1,9 @@
<table class="table table-condensed">
<table class="table table-condensed" id="ticket-list">
<thead>
<tr>
<th>Sujet</th>
<th>Statut</th>
<th>Dernier message</th>
<th></th>
</tr>
</thead>
@@ -14,6 +15,10 @@
{% set value = ticket.status %}
{% include '@LcShop/backend/default/list-fields/field_ticket_status.html.twig' %}
</td>
<td>
{% set item = ticket %}
{% include '@LcShop/backend/default/list-fields/field_ticket_last_message.html.twig' %}
</td>
<td>
<a class="btn-sm btn-success" href="{{ path('easyadmin', {id: ticket.id, entity: 'Ticket', action: 'show'}) }}">
<i class="fas fa-eye"></i>

+ 21
- 2
ShopBundle/Resources/views/backend/default/block/macros.html.twig Vedi File

@@ -61,6 +61,7 @@


{% macro priceField(field, fieldTax, fieldName, behaviorPriceValue) %}

<div class="form-group field-price col-12" v-show="behaviorPrice == '{{ behaviorPriceValue }}'">
<div class="row">
<div class="col-12">
@@ -68,7 +69,7 @@
</div>
<div class="col-6">
<div class="form-widget">
<div class="input-group">
<div class="input-group {{ fieldName }}">
{{ form_widget(field, {'attr' : {'v-model': fieldName, '@change' : fieldName~'Updated'}}) }}
<div class="input-group-append">
<span class="input-group-text">€ HT
@@ -79,7 +80,7 @@
</div>
</div>
<div class="col-6">
<div class="input-group">
<div class="input-group {{ fieldName }}WithTax">
{{ form_widget(fieldTax, {'attr' : {'v-model': fieldName ~ 'WithTax', '@change' : fieldName~'WithTaxUpdated'}}) }}
<div class="input-group-append">
<span class="input-group-text">€ TTC
@@ -242,6 +243,24 @@
{% endmacro box_info %}


{% macro form_row_append(field, append) %}
<div class="form-group">
{{ form_label(field) }}
{{ _self.form_widget_append(field, append) }}
</div>
{% endmacro form_row_append %}
{% macro form_widget_append(field, append) %}
<div class="form-widget">
<div class="input-group">
{{ form_widget(field) }}
<div class="input-group-append">
<span class="input-group-text">{{ append }}</span>
</div>
</div>
{{ form_help(field) }}
</div>
{% endmacro form_widget_append %}

{#{% macro modal(title, form) %}
{% embed '@LcShop/backend/default/block/embed_modal.twig' %}
{% trans_default_domain 'lcshop' %}

+ 8
- 1
ShopBundle/Resources/views/backend/default/edit.html.twig Vedi File

@@ -22,7 +22,7 @@
{% endapply %}
{% endblock %}

{% block content_footer_wrapper '' %}

{% block main %}
{% block entity_form %}
@@ -51,6 +51,13 @@
{% block plugin_javascript %}
{{ parent() }}
<script src="{{ asset('bundles/lcshop/js/backend/plugin/jquery-ui/jquery-ui.min.js') }}"></script>
<script type="text/javascript">
var CKEDITOR_BASEPATH = "{{ ckeditor_base_path("/bundles/fosckeditor/") }}";
</script>
<script type="text/javascript" src="{{ asset('bundles/fosckeditor/ckeditor.js') }}"></script>
{#{% if jquery %}
<script type="text/javascript" src="{{ ckeditor_js_path(jquery_path) }}"></script>
{% endif %}#}
{% endblock %}

{% block script_javascript %}

+ 6
- 3
ShopBundle/Resources/views/backend/default/layout/layout.html.twig Vedi File

@@ -19,6 +19,8 @@
href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/datatables/responsive.bootstrap4.min.css') }}">
<link rel="stylesheet"
href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/select2/select2.min.css') }}">
<link rel="stylesheet"
href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/select2/select2-bootstrap.min.css') }}">
<link rel="stylesheet"
href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/bootstrap/bootstrap-switch.min.css') }}">

@@ -53,7 +55,7 @@
</head>

{% block body %}
<body class="{% block body_class %}sidebar-mini layout-navbar-fixed {% endblock %}{% block body_class_extend %}{% endblock %}">
<body id="pdl-body" class="{% block body_class %}sidebar-mini layout-navbar-fixed{% endblock %} {% block body_class_extend %}{% endblock %}">
{# <script>
document.body.classList.add(
'easyadmin-content-width-' + (localStorage.getItem('easyadmin/content/width') || 'normal'),
@@ -211,7 +213,7 @@
</section>

{% block content_footer_wrapper %}
<section class="content-footer">
<section class="content-footer content">
{% block content_footer %}{% endblock %}
</section>
{% endblock %}
@@ -239,7 +241,8 @@
<!-- Bootstrap 4 -->
<script src="{{ asset('bundles/lcshop/js/backend/plugin/bootstrap/bootstrap.bundle.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/toastr/toastr.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/select2/select2.min.js') }}"></script>
{#<script src="{{ asset('bundles/lcshop/js/backend/plugin/select2/select2.min.js') }}"></script>#}
<script src="{{ asset('bundles/lcshop/js/backend/plugin/select2/select2.full.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/bootstrap/bootstrap-switch.min.js') }}"></script>
<!-- AdminLTE App -->
<script src="{{ asset('bundles/lcshop/js/backend/plugin/adminlte.min.js') }}"></script>

+ 288
- 0
ShopBundle/Resources/views/backend/default/list-datatable.html.twig Vedi File

@@ -0,0 +1,288 @@
{% set _entity_config = easyadmin_entity(app.request.query.get('entity')) %}
{% trans_default_domain _entity_config.translation_domain %}
{% set _trans_parameters = { '%entity_name%': _entity_config.name|trans, '%entity_label%': _entity_config.label|trans } %}

{% extends _entity_config.templates.layout %}

{% set _request_parameters = app.request.query.all|merge(_request_parameters|default({}))|merge({
action: app.request.get('action'),
entity: _entity_config.name,
menuIndex: app.request.get('menuIndex'),
submenuIndex: app.request.get('submenuIndex'),
sortField: app.request.get('sortField'),
sortDirection: app.request.get('sortDirection'),
page: app.request.get('page', 1),
filters: app.request.get('filters', []),
referer: null
}) %}

{% if 'search' == app.request.get('action') %}
{% set _request_parameters = _request_parameters|merge({
query: app.request.get('query')|default(''),
}) %}
{% endif %}

{% set _request_parameters = _request_parameters|merge({ referer: path('easyadmin', _request_parameters)|url_encode }) %}
{% set _has_batch_actions = batch_form is defined and batch_form.vars.batch_actions|length > 0 %}
{% set _has_filters = _entity_config.list.filters|default(false) %}

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


{% block content_title %}
{% apply spaceless %}
{% if 'search' == app.request.get('action') %}
{% set _default_title = 'search.page_title'|transchoice(paginator.nbResults, {}, 'EasyAdminBundle') %}
{{ (_entity_config.search.title is defined ? _entity_config.search.title|transchoice(paginator.nbResults) : _default_title)|raw }}
{% else %}
{{ 'list.title'|trans({"%label%" : _entity_config.label_plural is defined ? _entity_config.label_plural : _entity_config.label}, 'lcshop') }}

{#{% set _default_title = 'list.page_title'|trans(_trans_parameters, 'EasyAdminBundle') %}
{{ dump(_default_title) }}
{{ (_entity_config.list.title is defined ? _entity_config.list.title|trans(_trans_parameters) : _default_title)|raw }}#}
{% endif %}

{% if app.request.get('action') == 'listChildren' and app.request.get('entity') == 'ProductCategory' %}
: {{ entity.title }}
{% endif %}
{% endapply %}
{% endblock %}

{% block global_actions %}


{% endblock global_actions %}

{% block batch_actions %}
{% if _has_batch_actions %}
<div class="batch-actions" style="display: none">
{% form_theme batch_form with easyadmin_config('design.form_theme') only %}
{{ form(batch_form) }}

{{ include('@EasyAdmin/default/includes/_batch_action_modal.html.twig', {
_translation_domain: _entity_config.translation_domain,
_trans_parameters: _trans_parameters,
_entity_config: _entity_config,
}, with_context = false) }}
</div>
{% endif %}
{% endblock batch_actions %}

{% block content_header %}
{{ parent() }}
{{ block('batch_actions') }}
{% if _has_filters %}
{{ include('@EasyAdmin/default/includes/_filters_modal.html.twig') }}
{% endif %}
{% endblock content_header %}

{% block main %}

{% set _fields_visible_by_user = fields|filter((metadata, field) => easyadmin_is_granted(metadata.permission)) %}
{% set _number_of_hidden_results = 0 %}
{% set _list_item_actions = easyadmin_get_actions_for_list_item(_entity_config.name) %}
<div class="row">
<div class="col-12">
<div class="card card-outline card-primary">
<div class="card-header">
<h2 class="card-title text-lg ">
{#{{ "list.title"|trans({'%label%' : _entity_config['label']|lower }) }}#}
<span data-toggle="tooltip" title="{{ "list.nbResults"|trans }}" class="badge badge-primary">{{ paginator.nbResults }} <i class="fa fa-bars"></i> </span>
{% if paginator.nbResultsOnline is defined %}<span data-toggle="tooltip" title="{{ "list.nbResultsOnline"|trans }}" class="badge badge-success">{{ paginator.nbResultsOnline }} <i class="fa fa-check"></i> </span>{% endif %}
{% if paginator.nbResultsOffline is defined %}<span data-toggle="tooltip" title="{{ "list.nbResultsOffline"|trans }}" class="badge badge-warning">{{ paginator.nbResultsOffline }} <i class="fa fa-pen"></i></span>{% endif %}
{% if is_granted('ROLE_SUPER_ADMIN') and paginator.nbResultsDeleted is defined %}<span data-toggle="tooltip" title="{{ "list.nbResultsDeleted"|trans }}" class="badge badge-danger">{{ paginator.nbResultsDeleted }} <i class="fa fa-trash"></i></span>{% endif %}

</h2>
{% if easyadmin_action_is_enabled_for_list_view('new', _entity_config.name) %}
{% set _action = easyadmin_get_action_for_list_view('new', _entity_config.name) %}
{% block new_action %}
<div class="button-action">
<a class="float-right {{ _action.css_class|default('') }}" href="{{ path('easyadmin', _request_parameters|merge({ action: _action.name })) }}" target="{{ _action.target }}">
<i class="fa fa-fw fa-plus"></i>
{{ _action.label is defined and not _action.label is empty ? _action.label|trans(_trans_parameters) }}
</a>

{% if _entity_config['list']['edit_position'] is defined %}
<a class="float-right btn-sm btn-success action-sort"
href="{{ path('easyadmin', _request_parameters|merge({ action: 'sort' })) }}"
target="{{ _action.target }}">
<i class="fa fa-sort"></i> Modifier position
</a>
{% endif %}

{% if app.request.get('action') == 'listChildren' and app.request.get('entity') == 'ProductCategory' %}
<a class="float-right btn-sm btn-primary" href="{{ path('easyadmin', {action: 'list', entity: 'ProductCategory'}) }}">
<i class="fa fa-chevron-left"></i> Retour à la catégorie parente
</a>
{% endif %}

</div>
{% endblock new_action %}
{% endif %}
</div>
<div class="card-body p-0">

<table class="table datatable-simple table-bordered table-hover table-striped">

<thead>
{% block table_head %}

<tr>
{% set i=0 %}
{% if _has_batch_actions %}
<th data-index="{{ i }}" width="1px"><span><input type="checkbox" class="form-batch-checkbox-all"></span></th>
{% set i=1 %}
{% endif %}

{% for field, metadata in _fields_visible_by_user %}

{% set isSortingField = (metadata.property == app.request.get('sortField')) or ('association' == metadata.type and app.request.get('sortField') starts with metadata.property ~ '.') %}
{% set nextSortDirection = isSortingField ? (app.request.get('sortDirection') == 'DESC' ? 'ASC' : 'DESC') : 'DESC' %}
{% set _column_icon = isSortingField ? (nextSortDirection == 'DESC' ? 'fa-arrow-up' : 'fa-arrow-down') : 'fa-sort' %}

{% set searchable = ''%}

{% if metadata.type == 'integer' or metadata.type =="string" or metadata.type == 'text'%}
{% set searchable = 'input'%}
{% elseif metadata.type == 'association' %}
{% set searchable= "select" %}
{% elseif metadata.type == 'date' %}
{% set searchable= "date" %}
{% elseif metadata.type=="toggle" %}
{% set searchable= "select" %}
{% endif %}

{#<th class="{{ isSortingField ? 'sorted' }} {{ metadata.virtual ? 'virtual' }} {{ metadata.dataType|lower }} {{ metadata.css_class }}" >#}
<th data-index="{{ i }}" class="{{ isSortingField ? 'sorted' }}" data-searchable="{{ searchable }}" >

{% if metadata.sortable %}
{{ metadata.fieldName|lc_trad(_entity_config['name']) }}
{% else %}
<span>{{ metadata.fieldName|lc_trad(_entity_config['name']) }}</span>
{% endif %}
</th>
{% set i= i +1 %}
{% endfor %}

{% if _list_item_actions|length > 0 %}
<th data-orderable="false" {% if _entity_config.list.collapse_actions %}width="10px"{% endif %} {{ easyadmin_config('design.rtl') ? 'dir="rtl"' }}>
{{ 'list.row_actions'|trans(_trans_parameters, 'EasyAdminBundle') }}
</th>
{% endif %}
</tr>

{% endblock table_head %}
</thead>
<tbody>
{% block table_body %}
{% for item in paginator.currentPageResults %}
{% if not easyadmin_is_granted(_entity_config.list.item_permission, item) %}
{% set _number_of_hidden_results = _number_of_hidden_results + 1 %}
{% else %}
{# the empty string concatenation is needed when the primary key is an object (e.g. an Uuid object) #}
{% set _item_id = '' ~ attribute(item, _entity_config.primary_key_field_name) %}
<tr draggable="true" rel="{{ _item_id }}" data-id="{{ _item_id }}">
{% if _has_batch_actions %}
<td><input type="checkbox" class="form-batch-checkbox" value="{{ _item_id }}"></td>
{% endif %}

{% for field, metadata in _fields_visible_by_user %}

{% set isSortingField = metadata.property == app.request.get('sortField') %}
{% set _column_label = (metadata.label ?: field|humanize)|trans(_trans_parameters) %}

<td class="{{ isSortingField ? 'sorted' }} {{ metadata.dataType|lower }} {{ metadata.css_class }}" {{ easyadmin_config('design.rtl') ? 'dir="rtl"' }}>
{{ easyadmin_render_field_for_list_view(_entity_config.name, item, metadata) }}
</td>
{% endfor %}

{% if _list_item_actions|length > 0 %}
{% set _column_label = 'list.row_actions'|trans(_trans_parameters, 'EasyAdminBundle') %}
<td class="actions">
{% block item_actions %}
{% set _actions_template = _entity_config.list.collapse_actions
? '@EasyAdmin/default/includes/_actions_dropdown.html.twig'
: '@EasyAdmin/default/includes/_actions.html.twig'
%}
{{ include(_actions_template, {
actions: _list_item_actions,
entity_config: _entity_config,
request_parameters: _request_parameters,
translation_domain: _entity_config.translation_domain,
trans_parameters: _trans_parameters,
item_id: _item_id,
item: item
}, with_context = false) }}
{% endblock item_actions %}
</td>
{% endif %}
</tr>
{% endif %}
{% else %}
<tr>
<td class="no-results" colspan="{{ _fields_visible_by_user|length + 1 }}">
{{ 'search.no_results'|trans(_trans_parameters, 'EasyAdminBundle') }}
</td>
</tr>
{% endfor %}

{% if _number_of_hidden_results > 0 %}
<tr class="datagrid-row-empty">
<td class="text-center" colspan="{{ _fields_visible_by_user|length + 1 }}">
<span class="datagrid-row-empty-message"><i class="fa fa-lock mr-1"></i> {{ 'security.list.hidden_results'|trans({}, 'EasyAdminBundle') }}</span>
</td>
</tr>
{% endif %}
{% endblock table_body %}
</tbody>
<tfoot></tfoot>
</table>
{% block delete_form %}
{% set referer = paginator.currentPage == paginator.nbPages and 1 != paginator.currentPage and 1 == paginator.currentPageResults|length
? path('easyadmin', app.request.query|merge({ page: app.request.query.get('page') - 1 }))
: app.request.requestUri
%}

{{ include('@EasyAdmin/default/includes/_delete_form.html.twig', {
view: 'list',
referer: referer,
delete_form: delete_form_template,
_translation_domain: _entity_config.translation_domain,
_trans_parameters: _trans_parameters,
_entity_config: _entity_config,
}, with_context = false) }}
{% endblock delete_form %}
</div>
</div>
</div>
</div>


{% endblock main %}
{#
{% block content_footer %}
{% block paginator %}
{{ include(_entity_config.templates.paginator) }}
{% endblock paginator %}
{% endblock %}#}
{% block head_stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/datatables/fixedHeader.dataTables.min.css') }}">
<link rel="stylesheet"
href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/datatables/dataTables.bootstrap4.min.css') }}">
{% endblock %}
{% block plugin_javascript %}
{{ parent() }}

<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/jquery.dataTables.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/dataTables.bootstrap4.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/dataTables.responsive.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/jquery.highlight.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/responsive.bootstrap4.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/dataTables.fixedHeader.min.js') }}"></script>
{% endblock %}

{% block script_javascript %}
{{ parent() }}
<script src="{{ asset('bundles/lcshop/js/backend/script/default/init-list-datatable.js') }}"></script>
{% endblock %}

+ 56
- 16
ShopBundle/Resources/views/backend/default/list-fields/field_product_family_available_quantity.html.twig Vedi File

@@ -1,22 +1,62 @@
{% if value is defined and value is not null %}
{% set value_is_set = value is defined and value is not null %}
{% if item.getBehaviorCountStock() == constant("Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE") %}
{% if value_is_set %}
{{ _self.badge_stock_start(value) }}
{{ _self.badge_stock_renewable(item.behaviorStockWeek) }}
{{ value }} {{ item.getUnit().getUnit() }}
{{ _self.badge_stock_end() }}
{% else %}
{{ _self.no_stock(item.behaviorStockWeek) }}
{% endif %}
{% elseif item.getBehaviorCountStock() == constant("Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY") %}
{% if value_is_set %}
{{ _self.badge_stock_start(value) }}
{{ _self.badge_stock_renewable(item.behaviorStockWeek) }}
{{ value }} pièce{% if value > 1 %}s{% endif %}
{{ _self.badge_stock_end() }}
{% else %}
{{ _self.no_stock(item.behaviorStockWeek) }}
{% endif %}
{% elseif item.getBehaviorCountStock() == constant("Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT") %}
{% set available_quantity_products = item.getAvailableQuantityInherited() %}
{% if available_quantity_products > 0 %}
{{ _self.badge_stock_start(available_quantity_products) }}
{{ _self.badge_stock_renewable(item.behaviorStockWeek) }}
{{ available_quantity_products }} pièce{% if available_quantity_products > 1 %}s{% endif %} (déclinaisons)
{{ _self.badge_stock_end() }}
{% else %}
{{ _self.no_stock(item.behaviorStockWeek) }}
{% endif %}
{% elseif item.getBehaviorCountStock() == constant("Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_UNLIMITED") %}
<span class="badge badge-success">Illimité</span>
{% endif %}

{% macro no_stock(behaviorStockWeek) %}
<span class="badge badge-danger">
{{ _self.badge_stock_renewable(behaviorStockWeek) }}
Pas de stock
</span>
{% endmacro %}

{% macro badge_stock_renewable(behaviorStockWeek) %}
{% if behaviorStockWeek == constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE') %}
R
{% elseif behaviorStockWeek == constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE_VALIDATION') %}
RV
{% elseif behaviorStockWeek == constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE') %}
NR
{% endif %}
{% endmacro %}

{% macro badge_stock_start(value) %}
{% if value > 0 %}
{% set badge_class = 'badge-success' %}
{% else %}
{% set badge_class = 'badge-danger' %}
{% endif %}
<span class="badge {{ badge_class }}">
{% if item.getBehaviorCountStock() == constant("Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE") %}
{{ value }} {{ item.getUnit().getUnit() }}
{% elseif item.getBehaviorCountStock() == constant("Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY") %}
{{ value }} pièce{% if value > 1 %}s{% endif %}
{% elseif item.getBehaviorCountStock() == constant("Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT") %}
{{ item.getAvailableQuantityInherited() }} pièce{% if value > 1 %}s{% endif %} (déclinaisons)
{% endif %}
<span class="badge {{ badge_class }}">
{% endmacro %}

{% macro badge_stock_end() %}
</span>
{% else %}
{% if item.getBehaviorCountStock() == constant("Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_UNLIMITED") %}
<span class="badge badge-success">Illimité</span>
{% else %}
<span class="badge badge-danger">Pas de stock</span>
{% endif %}
{% endif %}
{% endmacro %}

+ 11
- 0
ShopBundle/Resources/views/backend/default/list-fields/field_ticket_last_message.html.twig Vedi File

@@ -0,0 +1,11 @@
{% if item.ticketMessages %}
{% for message in item.ticketMessages %}
{% if loop.last %}
{% if message.answerByAdmin %}
Place du Local
{% else %}
Client
{% endif %}
{% endif %}
{% endfor %}
{% endif %}

+ 8
- 1
ShopBundle/Resources/views/backend/default/list-fields/field_toggle.html.twig Vedi File

@@ -1,7 +1,14 @@
{% trans_default_domain 'EasyAdminBundle' %}

{% if value == true %}
<div class="custom-control custom-switch" data-propertyname="{{ field_options.property }}">
<input type="checkbox" class="custom-control-input" id="customSwitch{{ item.id }}-{{ field_options.property }}" {{ value == true ? 'checked' }}>
<label class="custom-control-label" for="customSwitch{{ item.id }}-{{ field_options.property }}">{{ 'label.true'|trans }}</label>
</div>
{#

{% if value == true %}
<span class="badge badge-success">{{ 'label.true'|trans }}</span>
{% else %}
<span class="badge badge-danger">{{ 'label.false'|trans }}</span>
{% endif %}
#}

+ 314
- 161
ShopBundle/Resources/views/backend/default/list.html.twig Vedi File

@@ -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 %}
@@ -35,22 +35,26 @@
{% set _default_title = 'search.page_title'|transchoice(paginator.nbResults, {}, 'EasyAdminBundle') %}
{{ (_entity_config.search.title is defined ? _entity_config.search.title|transchoice(paginator.nbResults) : _default_title)|raw }}
{% else %}
{{ 'list.title'|trans({"%label%" : _entity_config.label_plural is defined ? _entity_config.label_plural : _entity_config.label}, 'lcshop') }}

{#{% set _default_title = 'list.page_title'|trans(_trans_parameters, 'EasyAdminBundle') %}
{{ dump(_default_title) }}
{{ (_entity_config.list.title is defined ? _entity_config.list.title|trans(_trans_parameters) : _default_title)|raw }}#}
{% endif %}

{% if app.request.get('action') == 'listChildren' and app.request.get('entity') == 'ProductCategory' %}
: {{ entity.title }}
{% set _default_title = 'list.page_title'|trans(_trans_parameters, 'EasyAdminBundle') %}
{{ (_entity_config.list.title is defined ? _entity_config.list.title|trans(_trans_parameters) : _default_title)|raw }}
{% endif %}
{% endapply %}
{% endblock %}

{% block global_actions %}


{#{% if easyadmin_action_is_enabled_for_list_view('new', _entity_config.name) %}
{% set _action = easyadmin_get_action_for_list_view('new', _entity_config.name) %}
{% block new_action %}
<div class="button-action">
<a class="{{ _action.css_class|default('') }}"
href="{{ path('easyadmin', _request_parameters|merge({ action: _action.name })) }}"
target="{{ _action.target }}">
{% if _action.icon %}<i class="fa fa-fw fa-{{ _action.icon }}"></i>{% endif %}
{{ _action.label is defined and not _action.label is empty ? _action.label|trans(_trans_parameters) }}
</a>
</div>
{% endblock new_action %}
{% endif %}#}
{% endblock global_actions %}

{% block batch_actions %}
@@ -77,6 +81,7 @@
{% endblock content_header %}

{% block main %}
{% block main_append %}{% endblock %}

{% set _fields_visible_by_user = fields|filter((metadata, field) => easyadmin_is_granted(metadata.permission)) %}
{% set _number_of_hidden_results = 0 %}
@@ -85,163 +90,276 @@
<div class="col-12">
<div class="card card-outline card-primary">
<div class="card-header">
<h2 class="card-title text-lg ">
{#{{ "list.title"|trans({'%label%' : _entity_config['label']|lower }) }}#}
<span data-toggle="tooltip" title="{{ "list.nbResults"|trans }}" class="badge badge-primary">{{ paginator.nbResults }} <i class="fa fa-bars"></i> </span>
{% if paginator.nbResultsOnline is defined %}<span data-toggle="tooltip" title="{{ "list.nbResultsOnline"|trans }}" class="badge badge-success">{{ paginator.nbResultsOnline }} <i class="fa fa-check"></i> </span>{% endif %}
{% if paginator.nbResultsOffline is defined %}<span data-toggle="tooltip" title="{{ "list.nbResultsOffline"|trans }}" class="badge badge-warning">{{ paginator.nbResultsOffline }} <i class="fa fa-pen"></i></span>{% endif %}
{% if is_granted('ROLE_SUPER_ADMIN') and paginator.nbResultsDeleted is defined %}<span data-toggle="tooltip" title="{{ "list.nbResultsDeleted"|trans }}" class="badge badge-danger">{{ paginator.nbResultsDeleted }} <i class="fa fa-trash"></i></span>{% endif %}

</h2>
{% if easyadmin_action_is_enabled_for_list_view('new', _entity_config.name) %}
{% set _action = easyadmin_get_action_for_list_view('new', _entity_config.name) %}
{% block new_action %}
<div class="button-action">
<a class="float-right {{ _action.css_class|default('') }}" href="{{ path('easyadmin', _request_parameters|merge({ action: _action.name })) }}" target="{{ _action.target }}">
<i class="fa fa-fw fa-plus"></i>
{{ _action.label is defined and not _action.label is empty ? _action.label|trans(_trans_parameters) }}
</a>

{% if _entity_config['list']['edit_position'] is defined %}
<a class="float-right btn-sm btn-success action-sort"
href="{{ path('easyadmin', _request_parameters|merge({ action: 'sort' })) }}"
target="{{ _action.target }}">
<i class="fa fa-sort"></i> Modifier position
</a>
{% block card_header %}

<h2 class="card-title text-lg ">
{% block paginator_nb_results %}
{#{{ "list.title"|trans({'%label%' : _entity_config['label']|lower }) }}#}
{% if paginator.nbResultsTotal != paginator.nbResults %}
<span data-toggle="tooltip" title="{{ "list.nbResultsFiltered"|trans }}"
class="badge badge-info">{{ paginator.nbResults }} <i
class="fa fa-search"></i> </span>
|
{% endif %}

{% if app.request.get('action') == 'listChildren' and app.request.get('entity') == 'ProductCategory' %}
<a class="float-right btn-sm btn-primary" href="{{ path('easyadmin', {action: 'list', entity: 'ProductCategory'}) }}">
<i class="fa fa-chevron-left"></i> Retour à la catégorie parente
<span data-toggle="tooltip" title="{{ "list.nbResults"|trans }}"
class="badge badge-primary">{{ paginator.nbResultsTotal }} <i
class="fa fa-bars"></i> </span>
{% if paginator.nbResultsOnline is defined %}<span data-toggle="tooltip"
title="{{ "list.nbResultsOnline"|trans }}"
class="badge badge-success">{{ paginator.nbResultsOnline }}
<i class="fa fa-check"></i> </span>{% endif %}
{% if paginator.nbResultsOffline is defined %}<span data-toggle="tooltip"
title="{{ "list.nbResultsOffline"|trans }}"
class="badge badge-warning">{{ paginator.nbResultsOffline }}
<i class="fa fa-pen"></i></span>{% endif %}
{% if is_granted('ROLE_SUPER_ADMIN') and paginator.nbResultsDeleted is defined %}<span
data-toggle="tooltip" title="{{ "list.nbResultsDeleted"|trans }}"
class="badge badge-danger">{{ paginator.nbResultsDeleted }} <i
class="fa fa-trash"></i>
</span>{% endif %}
{% endblock %}

</h2>
{% if easyadmin_action_is_enabled_for_list_view('new', _entity_config.name) %}
{% set _action = easyadmin_get_action_for_list_view('new', _entity_config.name) %}
{% block new_action %}
<div class="button-action">
<a class="float-right {{ _action.css_class|default('') }}"
href="{{ path('easyadmin', _request_parameters|merge({ action: _action.name })) }}"
target="{{ _action.target }}">
<i class="fa fa-fw fa-plus"></i>
{{ _action.label is defined and not _action.label is empty ? _action.label|trans(_trans_parameters) }}
</a>
{% endif %}

</div>
{% endblock new_action %}
{% endif %}
</div>
<div class="card-body p-0">

<table class="table datatable-simple table-bordered table-hover table-striped">
{% if _entity_config['list']['btn_init_export_purchase_order'] is defined %}
<a class="float-right btn-sm btn-success action-sort"
href="{{ path('easyadmin', { entity: 'Supplier', action: 'initExportPurchaseOrder' }) }}"
target="{{ _action.target }}">
<i class="fa fa-undo"></i> Réinitialiser export bons de commande
</a>
{% endif %}

<thead>
{% block table_head %}
{% if _entity_config['list']['edit_position'] is defined %}
<a class="float-right btn-sm btn-success action-sort"
href="{{ path('easyadmin', _request_parameters|merge({ action: 'sort' })) }}"
target="{{ _action.target }}">
<i class="fa fa-sort"></i> Modifier position
</a>
{% endif %}

<tr>
{% set i=0 %}
{% if _has_batch_actions %}
<th data-index="{{ i }}" width="1px"><span><input type="checkbox" class="form-batch-checkbox-all"></span></th>
{% set i=1 %}
{% endif %}
{% if app.request.get('action') == 'listChildren' and app.request.get('entity') == 'ProductCategory' %}
<a class="float-right btn-sm btn-primary"
href="{{ path('easyadmin', {action: 'list', entity: 'ProductCategory'}) }}">
<i class="fa fa-chevron-left"></i> Retour à la catégorie parente
</a>
{% endif %}

{% for field, metadata in _fields_visible_by_user %}
</div>
{% endblock new_action %}
{% endif %}
{% endblock card_header %}

{% set isSortingField = (metadata.property == app.request.get('sortField')) or ('association' == metadata.type and app.request.get('sortField') starts with metadata.property ~ '.') %}
{% set nextSortDirection = isSortingField ? (app.request.get('sortDirection') == 'DESC' ? 'ASC' : 'DESC') : 'DESC' %}
{% set _column_icon = isSortingField ? (nextSortDirection == 'DESC' ? 'fa-arrow-up' : 'fa-arrow-down') : 'fa-sort' %}
</div>

{% set searchable = ''%}

{% if metadata.type == 'integer' or metadata.type =="string" or metadata.type == 'text'%}
{% set searchable = 'input'%}
{% elseif metadata.type == 'association' %}
{% set searchable= "select" %}
{% elseif metadata.type == 'date' %}
{% set searchable= "date" %}
{% elseif metadata.type=="toggle" %}
{% set searchable= "select" %}
<div class="card-body p-0">
{% block table %}
<table class="table lc-table-list datagrid table-bordered table-hover table-striped ">
<thead>
{% block table_head %}
<tr>
{% if _has_batch_actions %}
<th width="1px"><span><input type="checkbox"
class="form-batch-checkbox-all"></span>
</th>
{% endif %}

{#<th class="{{ isSortingField ? 'sorted' }} {{ metadata.virtual ? 'virtual' }} {{ metadata.dataType|lower }} {{ metadata.css_class }}" >#}
<th data-index="{{ i }}" class="{{ isSortingField ? 'sorted' }}" data-searchable="{{ searchable }}" >

{% if metadata.sortable %}
{{ metadata.fieldName|lc_trad(_entity_config['name']) }}
{% else %}
<span>{{ metadata.fieldName|lc_trad(_entity_config['name']) }}</span>
{% endif %}
</th>
{% set i= i +1 %}
{% endfor %}

{% if _list_item_actions|length > 0 %}
<th data-orderable="false" {% if _entity_config.list.collapse_actions %}width="10px"{% endif %} {{ easyadmin_config('design.rtl') ? 'dir="rtl"' }}>
{{ 'list.row_actions'|trans(_trans_parameters, 'EasyAdminBundle') }}
</th>
{% endif %}
</tr>

{% endblock table_head %}
</thead>
<tbody>
{% block table_body %}
{% for item in paginator.currentPageResults %}
{% if not easyadmin_is_granted(_entity_config.list.item_permission, item) %}
{% set _number_of_hidden_results = _number_of_hidden_results + 1 %}
{% else %}
{# the empty string concatenation is needed when the primary key is an object (e.g. an Uuid object) #}
{% set _item_id = '' ~ attribute(item, _entity_config.primary_key_field_name) %}
<tr draggable="true" rel="{{ _item_id }}" data-id="{{ _item_id }}">
{% for field, metadata in _fields_visible_by_user %}
{% set isSortingField = (metadata.property == app.request.get('sortField')) or ('association' == metadata.type and app.request.get('sortField') starts with metadata.property ~ '.') %}
{% set nextSortDirection = isSortingField ? (app.request.get('sortDirection') == 'DESC' ? 'ASC' : 'DESC') : 'DESC' %}
{% set _column_label = metadata.label|trans(_trans_parameters) %}
{% set _column_icon = isSortingField ? (nextSortDirection == 'DESC' ? 'fa-arrow-up' : 'fa-arrow-down') : 'fa-sort' %}

<th class="{{ isSortingField ? 'sorted' }} {{ metadata.virtual ? 'virtual' }} {{ metadata.dataType|lower }} {{ metadata.css_class }}" {{ easyadmin_config('design.rtl') ? 'dir="rtl"' }}>
{% if metadata.sortable %}
<a href="{{ path('easyadmin', _request_parameters|merge({ page: 1, sortField: metadata.property, sortDirection: nextSortDirection })) }}">
{{ _column_label|raw }} <i class="fa fa-fw {{ _column_icon }}"></i>
</a>
{% else %}
<span>{{ _column_label|raw }}</span>
{% endif %}
</th>
{% endfor %}

{% if _list_item_actions|length > 0 %}
<th {% if _entity_config.list.collapse_actions %}width="10px"{% endif %} {{ easyadmin_config('design.rtl') ? 'dir="rtl"' }}>
<span class="sr-only">{{ 'list.row_actions'|trans(_trans_parameters, 'EasyAdminBundle') }}</span>
</th>
{% endif %}
</tr>
{% endblock table_head %}
{% block table_filters %}
{% if filters_form is defined %}
<tr class="table-filters-line">
{% if _has_batch_actions %}
<td><input type="checkbox" class="form-batch-checkbox" value="{{ _item_id }}"></td>
{% endif %}

<th></th>{% endif %}
{% for field, metadata in _fields_visible_by_user %}

{% set isSortingField = metadata.property == app.request.get('sortField') %}
{% set _column_label = (metadata.label ?: field|humanize)|trans(_trans_parameters) %}

<td class="{{ isSortingField ? 'sorted' }} {{ metadata.dataType|lower }} {{ metadata.css_class }}" {{ easyadmin_config('design.rtl') ? 'dir="rtl"' }}>
{{ easyadmin_render_field_for_list_view(_entity_config.name, item, metadata) }}
</td>
<th>

{% if filters_form[field] is defined %}
{% if metadata['dataType'] == 'datetime' or metadata['dataType'] == 'date' %}
<div class="input-group input-group-sm">
<input type="text"
class="form-control input-sm float-right date-range">
<div class="hidden date-time-range-fields"
style="display: none;">
{{ form_widget(filters_form[field]['dateStart'], {"attr" : {'class' : 'date-start', 'form': 'filters-form'}}) }}
{{ form_widget(filters_form[field]['dateEnd'], {"attr" : {'class' : 'date-end', 'form': 'filters-form'}}) }}
</div>
</div>
{% else %}
<div class="form-widget input-group-sm">
{% if metadata.dataType == 'integer' or metadata.dataType== 'string' %}
{{ form_widget(filters_form[field], {'attr': {'autocomplete': 'off', 'data-lc-autocomplete-url' : path('easyadmin', {
action: 'autocomplete',
field: field,
entity: _entity_config.name,
})|raw }}) }}
{% else %}
{{ form_widget(filters_form[field]) }}
{% endif %}
</div>
{% endif %}

{% endif %}


</th>
{% endfor %}

{% if _list_item_actions|length > 0 %}
{% set _column_label = 'list.row_actions'|trans(_trans_parameters, 'EasyAdminBundle') %}
<td class="actions">
{% block item_actions %}
{% set _actions_template = _entity_config.list.collapse_actions
? '@EasyAdmin/default/includes/_actions_dropdown.html.twig'
: '@EasyAdmin/default/includes/_actions.html.twig'
%}
{{ include(_actions_template, {
actions: _list_item_actions,
entity_config: _entity_config,
request_parameters: _request_parameters,
translation_domain: _entity_config.translation_domain,
trans_parameters: _trans_parameters,
item_id: _item_id,
item: item
}, with_context = false) }}
{% endblock item_actions %}
</td>
<th class="actions">
<button type="submit" form="filters-form" class="btn btn-sm btn-info"
data-toggle="tooltip"
title="{{ "action.apply"|trans({}, 'lcshop') }}"
aria-label="{{ "action.apply"|trans({}, 'lcshop') }}">
<i class="fa fa-search"></i>
</button>
{% if filters_form.vars.submitted %}
<a href="{{ path('easyadmin', {action: app.request.get('action'), entity: _entity_config.name}) }}"
class="btn btn-sm btn-warning lc-reset-filters"
data-toggle="tooltip"
title="{{ "action.reset"|trans({}, 'lcshop') }}"
aria-label="{{ "action.reset"|trans({}, 'lcshop') }}">
<i class="fa fa-eraser"></i>
</a>
{% endif %}


</th>
{% endif %}

</tr>
{% endif %}
{% else %}
<tr>
<td class="no-results" colspan="{{ _fields_visible_by_user|length + 1 }}">
{{ 'search.no_results'|trans(_trans_parameters, 'EasyAdminBundle') }}
</td>
</tr>
{% endfor %}

{% if _number_of_hidden_results > 0 %}
<tr class="datagrid-row-empty">
<td class="text-center" colspan="{{ _fields_visible_by_user|length + 1 }}">
<span class="datagrid-row-empty-message"><i class="fa fa-lock mr-1"></i> {{ 'security.list.hidden_results'|trans({}, 'EasyAdminBundle') }}</span>
</td>
</tr>
{% endif %}
{% endblock table_body %}
</tbody>
<tfoot></tfoot>
</table>
{% endblock table_filters %}
{% block table_search %}

{% endblock %}

</thead>

<tbody>
{% block table_body %}
{% for item in paginator.currentPageResults %}
{% if not easyadmin_is_granted(_entity_config.list.item_permission, item) %}
{% set _number_of_hidden_results = _number_of_hidden_results + 1 %}
{% else %}
{# the empty string concatenation is needed when the primary key is an object (e.g. an Uuid object) #}
{% set _item_id = '' ~ attribute(item, _entity_config.primary_key_field_name) %}
<tr data-id="{{ _item_id }}">
{% if _has_batch_actions %}
<td><input type="checkbox" class="form-batch-checkbox"
value="{{ _item_id }}"></td>
{% endif %}

{% for field, metadata in _fields_visible_by_user %}
{% set isSortingField = metadata.property == app.request.get('sortField') %}
{% set _column_label = (metadata.label ?: field|humanize)|trans(_trans_parameters) %}


<td class="{{ isSortingField ? 'sorted' }} {{ metadata.dataType|lower }} {{ metadata.css_class }}" {{ easyadmin_config('design.rtl') ? 'dir="rtl"' }}>
{% if (field == 'title' or field== 'id') and (metadata.dataType=="string" or metadata.dataType=="integer") %}
<a class="link-as-text"
href="{{ path('easyadmin', {'action':'edit', 'entity':_entity_config.name, 'id': item.id}) }}">
{{ easyadmin_render_field_for_list_view(_entity_config.name, item, metadata) }}
</a>
{% else %}
{{ easyadmin_render_field_for_list_view(_entity_config.name, item, metadata) }}
{% endif %}
</td>
{% endfor %}

{% if _list_item_actions|length > 0 %}
{% set _column_label = 'list.row_actions'|trans(_trans_parameters, 'EasyAdminBundle') %}
<td class="actions">
{% block item_actions %}
{% set _actions_template = '@LcShop/backend/default/block/actions.html.twig' %}
{{ include(_actions_template, {
actions: _list_item_actions,
entity_config: _entity_config,
request_parameters: _request_parameters,
translation_domain: _entity_config.translation_domain,
trans_parameters: _trans_parameters,
item_id: _item_id,
item: item
}, with_context = false) }}
{% endblock item_actions %}
</td>
{% endif %}
</tr>
{% endif %}
{% else %}
<tr>
<td class="no-results" colspan="{{ _fields_visible_by_user|length + 1 }}">
{{ 'search.no_results'|trans(_trans_parameters, 'EasyAdminBundle') }}
</td>
</tr>
{% endfor %}

{% if _number_of_hidden_results > 0 %}
<tr class="datagrid-row-empty">
<td class="text-center" colspan="{{ _fields_visible_by_user|length + 1 }}">
<span class="datagrid-row-empty-message"><i
class="fa fa-lock mr-1"></i> {{ 'security.list.hidden_results'|trans({}, 'EasyAdminBundle') }}</span>
</td>
</tr>
{% endif %}
{% endblock table_body %}
</tbody>
</table>
{% endblock table %}

{% block filters_form %}
{% if filters_form is defined %}
{{ form_start(filters_form, {'attr' :{'id' : 'filters-form'}}) }}
{% form_theme filters_form '@LcShop/backend/form/custom_bootstrap_4.html.twig' %}

<input type="hidden" name="entity" value="{{ _entity_config.name }}">
<input type="hidden" name="menuIndex" value="{{ app.request.get('menuIndex') }}">
<input type="hidden" name="submenuIndex" value="{{ app.request.get('submenuIndex') }}">
<input type="hidden" name="sortField" value="{{ app.request.get('sortField', '') }}">
<input type="hidden" name="sortDirection"
value="{{ app.request.get('sortDirection', 'DESC') }}">
<input type="hidden" name="action" value="{{ app.request.get('action') }}">
{{ form_end(filters_form) }}
{% endif %}
{% endblock filters_form %}


{% block delete_form %}
{% set referer = paginator.currentPage == paginator.nbPages and 1 != paginator.currentPage and 1 == paginator.currentPageResults|length
? path('easyadmin', app.request.query|merge({ page: app.request.query.get('page') - 1 }))
: app.request.requestUri
%}
: app.request.requestUri %}

{{ include('@EasyAdmin/default/includes/_delete_form.html.twig', {
view: 'list',
@@ -252,37 +370,72 @@
_entity_config: _entity_config,
}, with_context = false) }}
{% endblock delete_form %}

</div>

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


{% endblock main %}
{#
{% block content_footer %}
{% block paginator %}
{{ include(_entity_config.templates.paginator) }}
{% endblock paginator %}
{% endblock %}#}
<div class="container-fluid">
{% block paginator %}
{{ include(_entity_config.templates.paginator) }}
{% endblock paginator %}
</div>
{% endblock %}


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

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

<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/jquery.dataTables.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/dataTables.bootstrap4.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/dataTables.responsive.min.js') }}"></script>
<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>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/jquery.highlight.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/responsive.bootstrap4.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/dataTables.fixedHeader.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/autocomplete/bootstrap-autocomplete.min.js') }}"></script>
{#<script src="{{ asset('bundles/lcshop/js/backend/plugin/datatables/responsive.bootstrap4.min.js') }}"></script>#}
{% endblock %}

{% block script_javascript %}
{{ parent() }}
<script src="{{ asset('bundles/lcshop/js/backend/script/default/init-list.js') }}"></script>


<script type="text/javascript">
$(document).ready(function () {
const toggles = document.querySelectorAll('.custom-switch input[type="checkbox"]');
for (i = 0; i < toggles.length; i++) {
toggles[i].addEventListener('change', function () {
const toggle = this;
const newValue = this.checked;
const oldValue = !newValue;
const propertyName = this.closest('.custom-switch').dataset.propertyname;
const toggleUrl = "{{ path('easyadmin', { action: 'edit', entity: _entity_config.name, view: 'list' })|raw }}"
+ "&id=" + this.closest('tr').dataset.id
+ "&property=" + propertyName
+ "&newValue=" + newValue.toString();

let toggleRequest = $.ajax({type: "GET", url: toggleUrl, data: {}, dataType: 'json'});

toggleRequest.done(function (response) {
setFlashMessages(response.flashMessages);
});

toggleRequest.fail(function () {
// in case of error, restore the original value and disable the toggle
toggle.checked = oldValue;
toggle.disabled = true;
toggle.closest('.checkbox-switch').classList.add('disabled');
});
});
}
});
</script>
{% endblock %}

+ 4
- 0
ShopBundle/Resources/views/backend/default/new.html.twig Vedi File

@@ -32,6 +32,10 @@
{% block plugin_javascript %}
{{ parent() }}
<script src="{{ asset('bundles/lcshop/js/backend/plugin/jquery-ui/jquery-ui.min.js') }}"></script>
<script type="text/javascript">
var CKEDITOR_BASEPATH = "{{ ckeditor_base_path("/bundles/fosckeditor/") }}";
</script>
<script type="text/javascript" src="{{ asset('bundles/fosckeditor/ckeditor.js') }}"></script>
{% endblock %}

{% block script_javascript %}

+ 3
- 2
ShopBundle/Resources/views/backend/form/ckeditor_widget.html.twig Vedi File

@@ -15,7 +15,8 @@
{% endblock %}

{% block _ckeditor_javascript %}
{% if autoload %}

{# {% if autoload %}
<script type="text/javascript">
var CKEDITOR_BASEPATH = "{{ ckeditor_base_path(base_path) }}";
</script>
@@ -23,7 +24,7 @@
{% if jquery %}
<script type="text/javascript" src="{{ ckeditor_js_path(jquery_path) }}"></script>
{% endif %}
{% endif %}
{% endif %}#}
{#<script type="text/javascript">
{% if jquery %}
$(function () {

+ 7
- 8
ShopBundle/Resources/views/backend/form/custom_bootstrap_4.html.twig Vedi File

@@ -5,14 +5,6 @@
{# TODO à corriger le theme requiert des infos easyAdmin il devrait être possible de ne pas en utiliser #}










{% block form_widget -%}
{{ parent() }}

@@ -234,6 +226,11 @@
<button type="submit" name="save_and_leave" class="btn btn-primary action-save">
<span class="btn-label">{{ 'action.save'|trans(_trans_parameters, _translation_domain) }}</span>
</button>
{% if easyadmin.entity.name =='ProductFamily' %}
<button name="submitAndStay" value="1" type="submit" class="btn btn-success action-save">
<span class="btn-label">{{ 'action.saveAndStay'|trans(_trans_parameters, _translation_domain) }}</span>
</button>
{% endif %}

{% set _entity_actions = (easyadmin.view == 'new')
? easyadmin_get_actions_for_new_item(easyadmin.entity.name)
@@ -256,6 +253,8 @@
}, with_context = false) }}
{% endblock item_actions %}



{#

{% block _user_niche_row %}

+ 316
- 0
ShopBundle/Resources/views/backend/productfamily/advanced_edition.html.twig Vedi File

@@ -0,0 +1,316 @@
{% extends '@LcShop/backend/default/list.html.twig' %}
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %}
{% import '@LcShop/backend/productfamily/macros.html.twig' as product_family_macros %}

{% block table %}
<script>
window.mixinUnitValues = {
unitsList: {{ getUnitsList()|json_encode|raw }}
};
window.mixinPriceValues = {
taxRatesList: {{ getTaxRatesList()|json_encode|raw }}
};
window.appProductFamilyValues = {};
window.productUnitPriceValues = {};
window.productForm ={};
window.formProductTemplate = {};

</script>

<ul id="product-family-advanced-types-list">
{% for i,advancedType in advancedTypes %}
{% set formValues = advancedType.vars.value %}
{% set productFamily = paginator.currentPageResults[i] %}
<script>
window.appProductFamilyValues[{{ i }}] = {
title: "{{ productFamily.title }}",
behaviorCountStock: "{{ productFamily.behaviorCountStock }}",
behaviorStockWeek: "{{ productFamily.behaviorStockWeek }}",
availableQuantity: "{{ productFamily.availableQuantity }}",
availableQuantityDefault: "{{ productFamily.availableQuantityDefault }}",
{% if productFamily.propertyNoveltyExpirationDate %}propertyNoveltyExpirationDate: {{ productFamily.propertyNoveltyExpirationDate }},{% endif %}
typeExpirationDate: "{{ productFamily.typeExpirationDate }}",
behaviorExpirationDate: "{{ productFamily.behaviorExpirationDate }}",
propertyExpirationDate: "{{ productFamily.propertyExpirationDate }}",
{% if productFamily.activeProducts %}activeProducts: {{ productFamily.activeProducts }},{% endif %}
};

window.productUnitPriceValues[{{ i }}] = {
{% if productFamily.activeProducts %}activeProducts: {{ productFamily.activeProducts }},{% endif %}
behaviorPrice: "{{ productFamily.behaviorPrice }}",
unit: parseInt({{ productFamily.unit.id }}),
{% if productFamily.taxRate %}taxRate: parseInt({{ productFamily.taxRate.id }}),{% endif %}
{% if productFamily.supplierTaxRate %}supplierTaxRate: parseInt({{ productFamily.supplierTaxRate.id }}),{% endif %}
quantity: "{{ productFamily.quantity }}",
price: parseFloat({{ productFamily.price }}).toFixed(3),
priceByRefUnit: parseFloat({{ productFamily.priceByRefUnit }}).toFixed(3),
buyingPrice: parseFloat({{ productFamily.buyingPrice }}).toFixed(3),
buyingPriceByRefUnit: parseFloat({{ productFamily.buyingPriceByRefUnit }}).toFixed(3),
}
</script>

<li class="product-family-advanced-type-item">
<div id="product-family-advanced-type-{{ i }}" class="product-family-advanced-type">
{{ form_start(advancedType, {"attr": {"ref": 'advanced-type'}}) }}

<product-unit-price ref="productUnitPrice" inline-template key-form="productfamily">
<div class="row">
{{ form_row(advancedType.unit, {"attr":{'v-model': 'unit', '@change': "unitUpdated"}}) }}


<div class="input-group">
{{ form_widget(advancedType.quantity, {'attr' : {'v-model': 'quantity', '@change': "quantityUpdated"}}) }}
<div class="input-group-append">
<span class="input-group-text">${ unitWording }</span>
</div>
</div>

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

{{ macros.priceField(advancedType.buyingPriceByRefUnit, advancedType.buyingPriceByRefUnitWithTax, 'buyingPriceByRefUnit', 'by-reference-unit') }}


<div class="input-group">
{{ form_widget(advancedType.multiplyingFactor, {'attr': {'v-model':'multiplyingFactor', '@change' : 'multiplyingFactorUpdated'}}) }}
<div class="input-group-append">
<span class="input-group-text">X</span>
</div>
</div>

{{ macros.priceField(advancedType.price, advancedType.priceWithTax, 'price', 'by-piece') }}
{{ macros.priceField(advancedType.priceByRefUnit, advancedType.priceByRefUnitWithTax, 'priceByRefUnit', 'by-reference-unit') }}

</div>
</product-unit-price>


<table class="table datagrid sortable lc-sortable-products products-collection-table"
:data-index="formProducts.length"
data-prototype="{{ product_family_macros.product_row(advancedType.products.vars.prototype)|e('html_attr') }}">
<thead>
<tr>
<th>
</th>
<th colspan="4" class="string">
Titre
</th>
<th colspan="2" class="string ">
Quantité
</th>
<th colspan="2" class="quantity">
Unité
</th>
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="buyingPriceByRefUnit">
PA HT / ${ getUnitReference() }
</th>
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="priceByRefUnit">
PA TTC / ${ getUnitReference() }
</th>

<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
PA HT
</th>
<th colspan="3" class="price">
PA TTC
</th>
<th colspan="3" class="">
Coef
</th>


<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="">
PV HT / ${ getUnitReference() }
</th>
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="price">
PV TTC / ${ getUnitReference() }
</th>

<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
PV HT
</th>
<th colspan="3" class="price">
PV TTC
</th>
<th colspan="2">
Marge HT
</th>

<th colspan="2" class=""
v-show="behaviorExpirationDate== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT') }}'">
<span style="text-transform: uppercase"> ${typeExpirationDate}</span>
</th>
<th colspan="2"
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}'">
Stock
</th>
<th colspan="2"
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' && behaviorStockWeek!= '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE') }}'">
Stock par défaut
</th>
<th colspan="2"
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' || behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}'">
Semaine / Commandés
</th>

<th colspan="2" class="">
Action
</th>
</tr>
</thead>
<tbody class="products-collection">

<template>
<product-form v-for="(formProduct, blop) in formProducts" v-bind:key="formProductKey[blop]"
:key-form="formProductKey[blop]" ref="productForm" v-bind:product-family="productFamily"
:template="formProduct"></product-form>
</template>
</tbody>
<tfoot>
<th>
Rappel
</th>
<th colspan="4" class="string">
${title}
</th>
<th colspan="2" class="string ">
${productFamily.quantity}
</th>
<th colspan="2" class="quantity">
${productFamily.unitWording}
</th>
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="buyingPriceByRefUnit">
${productFamily.buyingPriceByRefUnit}
</th>
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="priceByRefUnit">
${productFamily.buyingPriceByRefUnitWithTax}
</th>

<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
${productFamily.buyingPrice}
</th>
<th colspan="3" class="price">
${productFamily.buyingPriceWithTax}
</th>
<th colspan="3" class="">
${productFamily.multiplyingFactor}
</th>


<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="">
${productFamily.priceByRefUnit}
</th>
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="price">
${productFamily.priceByRefUnitWithTax}
</th>

<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
${productFamily.price}
</th>
<th colspan="3" class="price">
${productFamily.priceWithTax}
</th>
<th colspan="2" class="price">
${productFamily.marginProfit}€<br/>
${productFamily.marginProfitPercent}%
</td>

<th colspan="2" class=""
v-show="behaviorExpirationDate== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT') }}'">
${propertyExpirationDate}
</th>

<th colspan="2"
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}'">
</th>
<th colspan="2"
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' && behaviorStockWeek!= '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE') }}'">
</th>
<th colspan="2"
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' || behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}'">
</th>

<th colspan="2" class="">

</th>
</tfoot>
</table>

<button type="button" class="add_tag_link btn-add-product btn btn-default" @click="addProductForm"><span
class="fa fa-plus"></span> Ajouter une déclinaison
</button>
<p>
<strong>Aide à l'utilisation - Raccourci clavier</strong>
<ul>
<li><strong>TAB</strong> : Champ suivant</li>
<li><strong>SHIFT + TAB</strong> : Champ précédent</li>
<li><strong>FLÈCHE BAS</strong> : Déclinaison suivante</li>
<li><strong>FLÈCHE HAUT</strong> : Déclinaison précédente</li>
<li><strong>SHIFT + [+]</strong> : Ajout d'une nouvelle déclinaison</li>
</ul>
</p>

<div class="clearfix"></div>

{% do advancedType.products.setRendered %}
<script>
window.productForm[{{ i }}] ={};
window.formProductTemplate[{{ i }}] = {};

{% for keyForm,y in sortableProductsField[i] %}
{% set product = advancedType.products[y] %}


window.productForm[{{ i }}][{{ keyForm }}] = {
{% if product.vars.value.position %}position: "{{ product.vars.value.position }}",{% endif %}
{% if product.vars.value.title %}title: "{{ product.vars.value.title }}",{% endif %}
{% if product.vars.value.quantity %}quantity: "{{ product.vars.value.quantity }}",{% endif %}
{% if product.vars.value.unit %}unit: {{ product.vars.value.unit.id }},{% endif %}
{% if product.vars.value.buyingPrice %}buyingPrice: parseFloat({{ product.vars.value.buyingPrice }}).toFixed(3),{% endif %}
{% if product.vars.value.buyingPriceByRefUnit %}buyingPriceByRefUnit: parseFloat({{ product.vars.value.buyingPriceByRefUnit }}).toFixed(3),{% endif %}
{% if product.vars.value.price %}price: parseFloat({{ product.vars.value.price }}).toFixed(3),{% endif %}
{% if product.vars.value.priceByRefUnit %}priceByRefUnit: parseFloat({{ product.vars.value.priceByRefUnit }}).toFixed(3),{% endif %}
{% if product.vars.value.availableQuantity %}availableQuantity: parseInt({{ product.vars.value.availableQuantity }}),{% endif %}
{% if product.vars.value.availableQuantityDefault %}availableQuantityDefault: parseInt({{ product.vars.value.availableQuantityDefault }}),{% endif %}
{% if product.vars.value.propertyExpirationDate %}propertyExpirationDate: "{{ product.vars.value.propertyExpirationDate }}",{% endif %}
{#{% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %}#}
};
window.formProductTemplate[{{ i }}][{{ keyForm }}] = '{{ product_family_macros.product_row(product, totalProductOrdered[i][product.vars.value.id])|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}';
{% endfor %}

</script>

{{ form_end(advancedType) }}
</div>
</li>
{% endfor %}
</ul>

{% endblock table %}


{% block head_stylesheets %}
{{ parent() }}
{% endblock %}

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

{% block script_javascript %}
{{ parent() }}
{% include '@LcShop/backend/default/block/script-vuejs.html.twig' %}
<script src="{{ asset('assets/js/backend/script/productfamily/vuejs-advanced-edition-product-family.js') }}"></script>

{% endblock %}

+ 0
- 1
ShopBundle/Resources/views/backend/productfamily/edit.html.twig Vedi File

@@ -21,5 +21,4 @@
{{ parent() }}
{% include '@LcShop/backend/default/block/script-vuejs.html.twig' %}
<script src="{{ asset('bundles/lcshop/js/backend/script/productfamily/vuejs-product-family.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/script/productfamily/init-edit.js') }}"></script>
{% endblock %}

+ 4
- 2
ShopBundle/Resources/views/backend/productfamily/form.html.twig Vedi File

@@ -9,7 +9,7 @@
<div class="lc-vue-js-container card-header p-0 border-bottom-0">
<ul class="nav nav-tabs" id="nav-params">
<li class="nav-item" v-for="section in sectionsArray">
<button type="button"
<a :href="'#'+section.name" type="button"
v-if="(section.name == 'products' && activeProducts == true) || (section.name != 'products')"
:class="'btn '+((currentSection == section.name) ? 'btn btn-primary' : 'btn ')"
@click="changeSection(section)">
@@ -17,7 +17,7 @@
<span v-if="section.name == 'products'">({{ form.products|length }})</span>
<span class="glyphicon glyphicon-triangle-bottom"></span>
<i class="fa fa-exclamation-circle invalid-form"></i>
</button>
</a>

</li>
</ul>
@@ -106,6 +106,8 @@
{% endif %}

</div>
{{ form_widget(form.stayOnPage, {"attr": {"v-model": "stayOnPage"}}) }}


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

+ 44
- 12
ShopBundle/Resources/views/backend/productfamily/macros.html.twig Vedi File

@@ -1,20 +1,39 @@
{% trans_default_domain 'lcshop' %}

{% macro total_order_product(totalProductOrdered) %}
{% macro total_order_product(totalProductOrdered, productFamily=false) %}
{% for weekNumber, weekNumberQuantity in totalProductOrdered %}
<span class="text-success"><i class="fa fa-calendar"></i> {{ weekNumber }}</span>
<span class="text-info"><i class="fa fa-shopping-basket"></i>
<strong>{{ weekNumberQuantity['quantity'] is null ? 0 : weekNumberQuantity['quantity']}}</strong></span>
<strong>
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity}}
</strong>
</span>
<br />
{% endfor %}
{% endmacro total_order_product %}


{% macro total_order_product_family(totalProductOrdered, productFamily) %}
{% for weekNumber, weekNumberQuantity in totalProductOrdered %}
<span class="text-success"><i class="fa fa-calendar"></i> {{ weekNumber }}</span>
<span class="text-info"><i class="fa fa-shopping-basket"></i>
<strong>
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity}}
{% if productFamily and productFamily.behaviorCountStock== constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') %}
{{ productFamily.unit.unitReference }}
{% endif %}
</strong>
</span>
<br />
{% endfor %}
{% endmacro total_order_product_family %}

{% macro product_field(colspan, field, field_name, field_display = false, display_suffix="",attr="") %}

{% if field_display == false %}{% set field_display = field_name %}{% endif %}

<td {{ attr|raw }} colspan="{{ colspan }}" class="{{ field_name }}">
<div class="value" v-show="{{ field_name }}Inherited == false" v-on:click="setFocusOnField('{{ field_name }}Inherited', keyForm)">
<div class="value" v-show="{{ field_name }}Inherited == false" @click="setFocusOnField('{{ field_name }}Inherited', keyForm)">
<div v-if="{{ field_name }}">
{% verbatim %}{{ {% endverbatim %}{{ field_display }} {% verbatim %}}}{% endverbatim %}{{ display_suffix }}
{% if field_name == 'priceWithTax' %}
@@ -34,7 +53,7 @@
<div v-show="{{ field_name }}Inherited == true">
{{ form_widget(field, {'attr' : {'v-model' : field_name , 'v-on:focusout': field_name~'Inherited = false', '@change' : field_name~'Updated', 'data-ref': field_name~'Inherited', ':data-y' : "keyForm" }}) }}
</div>
<button v-show="{{ field_name }}" v-on:click="{{ field_name }} = null; {{ field_name }}Inherited = false; "
<button v-show="{{ field_name }}" v-on:click="{{ field_name }} = null; {{ field_name }}Inherited = false;"
class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button>
</td>
{% endmacro %}
@@ -42,7 +61,13 @@
{% macro product_row(product, totalProductOrdered) %}

<tr class="lc-draggable">
<td><i class="fa fa-fw fa-sort"></i></td>
<td>
{% if product.vars.value is not null %}
#{{ product.vars.value.id }}
{% else %}
#new
{% endif %} <br/>
{% verbatim %}{{keyForm}}{% endverbatim %}<i class="fa fa-fw fa-sort"></i></td>
{{ _self.product_field(4, product.title, 'title') }}
{{ _self.product_field(2, product.quantity, 'quantity') }}
{{ _self.product_field(2, product.unit, 'unit', 'unitWording') }}
@@ -51,15 +76,19 @@
{{ _self.product_field(3, product.buyingPrice, 'buyingPrice',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }}
{{ _self.product_field(3, product.buyingPriceWithTax, 'buyingPriceWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }}

<td colspan="3" v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'">
{% verbatim %}{{ buyingPriceWithTax }}{% endverbatim %}€
<td class="buyingPrice" colspan="3" v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'">
{% verbatim %}{{ finalBuyingPrice }}{% endverbatim %}€
</td>

{{ _self.product_field(3, product.multiplyingFactor, 'multiplyingFactor') }}
{{ _self.product_field(3, product.priceByRefUnit, 'priceByRefUnit',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') ~ '\'"') }}
{{ _self.product_field(3, product.priceByRefUnitWithTax, 'priceByRefUnitWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') ~ '\'"') }}

<td colspan="3" v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'">

<td class="price" colspan="3" v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'">
{% verbatim %}{{ finalPrice }}{% endverbatim %}€
</td>
<td class="priceWithTax" colspan="3" v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'">
{% verbatim %}{{ finalPriceWithTax }}{% endverbatim %}€
<span class="text-danger" v-show="productFamily.reductionActive">{% verbatim %}{{ finalPriceWithTaxAndReduction }}{% endverbatim %}€</span>
</td>
@@ -89,14 +118,18 @@
{{ _self.total_order_product(totalProductOrdered) }}

</td>
<td colspan="2">
<button type="button" class="btn-remove-product btn-sm btn-info" @click="modalProductForm()">
<td colspan="3">
<button type="button" class="btn-sm btn-info" @click="modalProductForm()">
<i class="fa fa-edit"></i>
</button>
<button type="button" class="btn-sm btn-info" @click="changeStatus()">
<i class="fa fa-check-square"></i>
</button>
<button type="button" class="btn-remove-product btn-sm btn-danger" @click="deleteProductForm()">
<i class="fa fa-trash"></i>
</button>
{{ form_widget(product.position, {'attr' : {'class': "field-position"}}) }}
{{ form_widget(product.position, {'attr' : {'class': "field-position", "v-model" : 'position'}}) }}
{{ form_widget(product.status, {'attr' : {"v-model" : 'status'}}) }}


<div class="modal fade show" :id="'modal-extends-product-'+keyForm">
@@ -122,7 +155,6 @@
<button type="button" class="btn btn-info float-right" data-dismiss="modal">Ok</button>
</div>
</div>
<!-- /.modal-content -->
</div>
</div>


+ 3
- 0
ShopBundle/Resources/views/backend/productfamily/panel_general.html.twig Vedi File

@@ -4,6 +4,9 @@

<div class="row">
{{ macros.startCard(8, 'ProductFamily.main','light') }}
<div class="col-12">
{{ form_row(form.status) }}
</div>
<div class="col-12">
{{ form_row(form.supplier) }}
</div>

+ 1
- 1
ShopBundle/Resources/views/backend/productfamily/panel_price.html.twig Vedi File

@@ -73,7 +73,7 @@
<div class="col-6">
<div class="form-widget">
{{ form_label(form.multiplyingFactor) }}
<div class="input-group">
<div class="input-group multiplyingFactor">
{{ form_widget(form.multiplyingFactor, {'attr': {'v-model':'multiplyingFactor', '@change' : 'multiplyingFactorUpdated'}}) }}
<div class="input-group-append">
<span class="input-group-text">X</span>

+ 25
- 25
ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig Vedi File

@@ -7,7 +7,7 @@
{{ macros.startCard(12, 'ProductFamily.products', 'light', true) }}

<table class="table datagrid sortable lc-sortable-products products-collection-table"
:data-index="formProductArray.length"
:data-index="formProducts.length"
data-prototype="{{ product_family_macros.product_row(form.products.vars.prototype)|e('html_attr') }}">
<thead>
<tr>
@@ -23,7 +23,7 @@
Unité
</th>
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
colspan="3" class="buyingPriceByRefUnit">
colspan="3" class="buyingPriceByRefUnit ">
PA HT / ${ getUnitReference() }
</th>
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"
@@ -31,14 +31,14 @@
PA TTC / ${ getUnitReference() }
</th>

<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
<th colspan="3" class="price main-info">
PA HT
</th>
<th colspan="3" class="price">
<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
PA TTC
</th>
<th colspan="3" class="">
<th colspan="3" class="main-info">
Coef
</th>

@@ -52,11 +52,11 @@
PV TTC / ${ getUnitReference() }
</th>

<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
<th colspan="3" class="price">
{# v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">#}
PV HT
</th>
<th colspan="3" class="price">
<th colspan="3" class="price main-info">
PV TTC
</th>
<th colspan="2">
@@ -80,19 +80,18 @@
Semaine / Commandés
</th>

<th colspan="2" class="">
<th colspan="3" class="">
Action
</th>
</tr>
</thead>
<tbody class="products-collection">

<template v-for="(formProduct, key) in formProductArray">
<product-form ref="productForm" v-bind:product-family="productFamily" :template="formProduct"
:key-form="key"></product-form>
<template>
<product-form v-for="(formProduct, name, index) in formProducts" v-bind:key="name"
:key-form="name" ref="productForm" v-bind:product-family="productFamily"
:template="formProduct"></product-form>
</template>

</tbody>
<tfoot>
<th>
@@ -116,14 +115,14 @@
${productFamily.buyingPriceByRefUnitWithTax}
</th>

<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
<th colspan="3" class="price main-info">
${productFamily.buyingPrice}
</th>
<th colspan="3" class="price">
<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
${productFamily.buyingPriceWithTax}
</th>
<th colspan="3" class="">
<th colspan="3" class="main-info">
${productFamily.multiplyingFactor}
</th>

@@ -137,15 +136,15 @@
${productFamily.priceByRefUnitWithTax}
</th>

<th colspan="3" class="price"
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">
<th colspan="3" class="price">
{# v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'">#}
${productFamily.price}
</th>
<th colspan="3" class="price">
<th colspan="3" class="price main-info">
${productFamily.priceWithTax}
</th>
<th colspan="2" class="price">
${productFamily.marginProfit}€<br />
${productFamily.marginProfit}€<br/>
${productFamily.marginProfitPercent}%
</td>

@@ -164,7 +163,7 @@
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' || behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}'">
</th>

<th colspan="2" class="">
<th colspan="3" class="">

</th>
</tfoot>
@@ -189,7 +188,6 @@
{{ macros.endCard() }}
</div>
{% do form.products.setRendered %}

<script>
window.productForm = new Array();
window.formProductTemplate = new Array();
@@ -198,6 +196,8 @@
{% set product = form.products[i] %}

window.productForm[{{ keyForm }}] = {
{% if product.vars.value.status is defined %}status: parseInt({{ product.vars.value.status }}),{% endif %}
{% if product.vars.value.position %}position: "{{ product.vars.value.position }}",{% endif %}
{% if product.vars.value.title %}title: "{{ product.vars.value.title }}",{% endif %}
{% if product.vars.value.quantity %}quantity: "{{ product.vars.value.quantity }}",{% endif %}
{% if product.vars.value.unit %}unit: {{ product.vars.value.unit.id }},{% endif %}

+ 7
- 0
ShopBundle/Resources/views/backend/productfamily/panel_stock.html.twig Vedi File

@@ -24,7 +24,14 @@

{{ form_label(form.behaviorStockWeek) }}
{% for field in form.behaviorStockWeek %}
{% if field.vars.value == constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE') or field.vars.value == constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_RENEWABLE_VALIDATION') %}
<div v-if="behaviorCountStock != '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_UNLIMITED')}}'">
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorStockWeek'}}) }}
</div>
{% else %}
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorStockWeek'}}) }}
{% endif %}

{% endfor %}
</div>
<div class="col">

+ 6
- 9
ShopBundle/Services/CreditUtils.php Vedi File

@@ -44,16 +44,13 @@ class CreditUtils
public function createUserMerchant(UserInterface $user, MerchantInterface $merchant = null)
{
$merchant = $this->getMerchant($merchant) ;
$classUserMerchant = $this->em->getClassMetadata(UserMerchantInterface::class)->getName();

$userMerchant = new $classUserMerchant ;
$userMerchant->setUser($user) ;
$userMerchant->setMerchant($merchant) ;
$userMerchant->setCredit(0) ;
$userMerchant->setCreditActive(true) ;

$this->em->persist($userMerchant) ;
$this->em->flush() ;
$userMerchant = $this->merchantUtils->initUserMerchant([
'user' => $user,
'merchant' => $merchant,
'credit' => 0,
'credit_active' => true,
]) ;

return $userMerchant ;
}

+ 59
- 1
ShopBundle/Services/MerchantUtils.php Vedi File

@@ -2,7 +2,65 @@

namespace Lc\ShopBundle\Services ;

use App\Entity\UserMerchant;
use Doctrine\ORM\EntityManagerInterface;
use Lc\ShopBundle\Context\UserMerchantInterface;
use Symfony\Component\Security\Core\Security;

class MerchantUtils
{

}
protected $security ;
protected $em ;

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

public function initUserMerchant($params = [])
{
$classUserMerchant = $this->em->getClassMetadata(UserMerchantInterface::class)->getName() ;
$userMerchantRepository = $this->em->getRepository($classUserMerchant) ;

$user = isset($params['user']) ? $params['user'] : null ;
$merchant = isset($params['merchant']) ? $params['merchant'] : null ;
$active = isset($params['active']) ? $params['active'] : true ;
$flush = isset($params['flush']) ? $params['flush'] : true ;
$persist = isset($params['persist']) ? $params['persist'] : true ;

$userMerchant = $userMerchantRepository->findOneBy([
'user' => $user,
'merchant' => $merchant
]) ;

if(!$userMerchant) {
$userMerchant = new $classUserMerchant ;
$userMerchant->setUser($user) ;
$userMerchant->setMerchant($merchant) ;
$userMerchant->setCreditActive(false);
}

$userMerchant->setActive($active) ;

if(isset($params['credit_active'])) {
$userMerchant->setCreditActive($params['credit_active']) ;
}

if(isset($params['credit'])) {
$userMerchant->setCredit($params['credit']) ;
}

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

if($flush) {
$this->em->flush() ;
}

return $userMerchant ;
}

}

+ 30
- 6
ShopBundle/Services/Order/OrderUtils.php Vedi File

@@ -69,7 +69,6 @@ class OrderUtils

public function createOrderShop($params)
{

//TODO vérifier que l'utilisateur n'a pas déjà une commande en cours
$orderShop = new OrderShop();

@@ -78,7 +77,7 @@ class OrderUtils
$orderShopBelongTo = true;
$orderShop->setUser($params['user']);
}
if (isset($params['visitor']) && $params['visitor']) {
if (isset($params['visitor']) && $params['visitor'] && !$orderShop->getUser()) {
$orderShopBelongTo = true;
$orderShop->setVisitor($params['visitor']);
}
@@ -182,10 +181,14 @@ class OrderUtils
if($availableQuantity !== false && $availableQuantity > 0) {
$unit = '' ;
if($orderProductAdd->getProduct()->getProductFamily()->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
$unit = $orderProductAdd->getProduct()->getUnitInherited()->getUnit() ;
$unit = $orderProductAdd->getProduct()->getUnitInherited()->getUnitReference()->getUnit() ;
}
$textError .= ' dans cette quantité ' ;
$textError .= '<br />'.$availableQuantity.$unit.' disponible(s) dont '.$this->getQuantityOrderByProduct($orderShop, $orderProductAdd->getProduct()).$unit.' déjà dans votre panier.' ;

$user = $this->security->getUser() ;
if($user && $user->hasRole('ROLE_USER')) {
$textError .= '<br />'.$availableQuantity.$unit.' disponible(s) dont '.$this->getQuantityOrderByProduct($orderShop, $orderProductAdd->getProduct()).$unit.' déjà dans votre panier.' ;
}
}
$this->utils->addFlash('error', $textError);
}
@@ -292,7 +295,17 @@ class OrderUtils
if ($orderShop1 && $orderShop2) {

foreach ($orderShop2->getOrderProducts() as $orderProduct) {
$this->addOrderProduct($orderShop1, $orderProduct);

$orderProductAlreadyInCart = $this->hasOrderProductAlreadyInCart($orderShop1, $orderProduct) ;
if($orderProductAlreadyInCart) {
if($orderProduct->getQuantityOrder() > $orderProductAlreadyInCart->getQuantityOrder()) {
$orderShop1->removeOrderProduct($orderProductAlreadyInCart) ;
$this->addOrderProduct($orderShop1, $orderProduct);
}
}
else {
$this->addOrderProduct($orderShop1, $orderProduct);
}

if($persist) {
$this->em->remove($orderProduct);
@@ -310,6 +323,17 @@ class OrderUtils
}


public function hasOrderProductAlreadyInCart($orderShop, $orderProductTest)
{
foreach($orderShop->getOrderProducts() as $orderProduct) {
if($orderProduct->getProduct() == $orderProductTest->getProduct()) {
return $orderProduct ;
}
}

return false ;
}

public function groupOrderProductsByProductFamily($orderProducts)
{
$orderProductsByProductFamily = [];
@@ -332,7 +356,7 @@ class OrderUtils

public function isOrderShopPositiveAmount(OrderShopInterface $orderShop)
{
return $this->priceUtils->getTotalWithTax($orderShop) > 0 ;
return $this->priceUtils->getTotalWithTax($orderShop) >= 0 ;
}

public function eventOrderShopChangeQuantity(OrderShopInterface $orderShop)

+ 5
- 1
ShopBundle/Services/Order/OrderUtilsCartTrait.php Vedi File

@@ -3,6 +3,8 @@
namespace Lc\ShopBundle\Services\Order;


use Lc\ShopBundle\Model\OrderStatus;

trait OrderUtilsCartTrait
{
public function getCartCurrent()
@@ -31,7 +33,8 @@ trait OrderUtilsCartTrait
if ($orderShopUser || $orderShopVisitor) {
// merge
if ($orderShopUser && $orderShopVisitor && $orderShopUser != $orderShopVisitor
&& $orderShopVisitor->getOrderProducts() && count($orderShopVisitor->getOrderProducts())) {
&& $orderShopVisitor->getOrderProducts() && count($orderShopVisitor->getOrderProducts())
&& $orderShopUser->getOrderStatus()->getAlias() == OrderStatus::ALIAS_CART) {
$orderShop = $this->mergeOrderShops($orderShopUser, $orderShopVisitor);
$this->utils->addFlash('success', "Votre panier visiteur vient d'être fusionné avec votre panier client.");
} else {
@@ -40,6 +43,7 @@ trait OrderUtilsCartTrait
// set user
if ($orderShop && $user && !$orderShop->getUser()) {
$orderShop->setUser($user);
$orderShop->setVisitor(null) ;
$this->em->persist($orderShop);
$this->em->flush();
}

+ 15
- 1
ShopBundle/Services/Order/OrderUtilsStockTrait.php Vedi File

@@ -59,6 +59,10 @@ trait OrderUtilsStockTrait

public function isProductAvailable(Product $product, $quantityOrder = 0, $checkCart = false, $orderShop = null)
{
if($product->getStatus() != 1) {
return false ;
}

if(!$orderShop) {
$orderShop = $this->getCartCurrent() ;
}
@@ -134,7 +138,7 @@ trait OrderUtilsStockTrait
&& $orderProduct->getProduct()->getProductFamily()->getId() == $productFamily->getId())) {

if($byWeight) {
$quantity += $orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $product->getUnitInherited()->getCoefficient()) ;
$quantity += $orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $orderProduct->getProduct()->getUnitInherited()->getCoefficient()) ;
}
else {
$quantity += $orderProduct->getQuantityOrder() ;
@@ -159,5 +163,15 @@ trait OrderUtilsStockTrait
return $product->getAvailableQuantityInherited() - $this->getQuantityOrderByProduct($orderShop, $product, $byWeight) ;
}

public function getProductQuantity($product) {

$productFamily = $product->getProductFamily() ;

if($productFamily->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
return $product->getQuantityInherited() / $product->getUnitInherited()->getCoefficient() ;
}
else {
return 1 ;
}
}
}

+ 4
- 0
ShopBundle/Services/Price/ProductPriceUtils.php Vedi File

@@ -91,5 +91,9 @@ class ProductPriceUtils
}
}

public function getMultiplyingFactor(ProductPropertyInterface $product){
return $this->round($this->getPriceWithTax($product) / $this->getBuyingPrice($product));
}

}


+ 1
- 1
ShopBundle/Services/ProductFamilyUtils.php Vedi File

@@ -40,7 +40,7 @@ class ProductFamilyUtils

private function getCheapestOrMostExpensiveProduct($productFamily, $comparisonFunction, $returnSelfIfNotActiveProducts)
{
$products = $productFamily->getProducts()->getValues() ;
$products = $productFamily->getProductsOnline()->getValues() ;
if (count($products) > 0) {
usort($products, $comparisonFunction);
return $products[0];

+ 32
- 3
ShopBundle/Services/TicketUtils.php Vedi File

@@ -14,11 +14,13 @@ class TicketUtils
{
protected $em ;
protected $merchantUtils ;
protected $mailUtils ;

public function __construct(EntityManagerInterface $em, MerchantUtilsInterface $merchantUtils)
public function __construct(EntityManagerInterface $em, MerchantUtilsInterface $merchantUtils, MailUtils $mailUtils)
{
$this->em = $em ;
$this->merchantUtils = $merchantUtils ;
$this->mailUtils = $mailUtils ;
}

public function createTicket($params): TicketInterface
@@ -30,12 +32,18 @@ class TicketUtils

if(isset($params['user'])) {
$ticket->setUser($params['user']) ;

$email = $params['user']->getEmail() ;
$firstname = $params['user']->getFirstname() ;
}
else {
$ticket->setVisitorFirstname($params['visitorFirstname']) ;
$ticket->setVisitorLastname($params['visitorLastname']) ;
$ticket->setVisitorEmail($params['visitorEmail']) ;
$ticket->setVisitorToken(uniqid()) ;

$email = $params['visitorEmail'] ;
$firstname = $params['visitorFirstname'] ;
}

$ticket->setStatus(Ticket::TICKET_STATUS_OPEN) ;
@@ -55,6 +63,17 @@ class TicketUtils

$this->em->flush() ;

// envoi email au client
$this->mailUtils->send([
MailUtils::SUBJECT => 'Nouvelle demande',
MailUtils::TO_EMAIL => $email,
MailUtils::CONTENT_TEMPLATE => 'mail/ticket-new',
MailUtils::CONTENT_DATA => [
'firstname' => $firstname,
'ticket' => $ticket
],
]) ;

return $ticket ;
}

@@ -70,14 +89,24 @@ class TicketUtils
$ticketMessage->setMessage($params['message']) ;
if(isset($params['answerByAdmin']) && $params['answerByAdmin']) {
$ticketMessage->setAnswerByAdmin($params['answerByAdmin']) ;

// envoi email au client
$this->mailUtils->send([
MailUtils::SUBJECT => 'Réponse à votre demande',
MailUtils::TO_EMAIL => $ticket->getUser() ? $ticket->getUser()->getEmail() : $ticket->getVisitorEmail(),
MailUtils::CONTENT_TEMPLATE => 'mail/ticket-response',
MailUtils::CONTENT_DATA => [
'firstname' => $ticket->getUser() ? $ticket->getUser()->getFirstname() : $ticket->getVisitorFirstname(),
'ticket' => $ticket
],
]) ;
}
$this->em->persist($ticketMessage);

if(isset($params['closeTicket']) && $params['closeTicket']) {
$ticket->setTicketStatus(Ticket::TICKET_STATUS_CLOSED) ;
$ticket->setStatus(Ticket::TICKET_STATUS_CLOSED) ;
}


$ticket->setUpdatedAt(new \DateTime()) ;
$this->em->persist($ticket);


+ 4
- 2
ShopBundle/Services/Utils.php Vedi File

@@ -350,12 +350,14 @@ class Utils
if (!isset($entitiesConfig[$reminder->getEntityName()])) {
$entitiesConfig[$reminder->getEntityName()] = $this->configManager->getEntityConfig($reminder->getEntityName());
}
if ($reminder->getEntityAction() == 'edit' || $reminder->getEntityAction() == 'show') {
if($reminder->getEntityAction() == 'edit' || $reminder->getEntityAction() == 'show') {
if (!isset($entitiesRepo[$reminder->getEntityName()])) {
$entitiesRepo[$reminder->getEntityName()] = $this->em->getRepository($entitiesConfig[$reminder->getEntityName()]['class']);
}

$reminder->relatedPage = $entitiesRepo[$reminder->getEntityName()]->find($reminder->getEntityId())->__toString();
if($reminder->getEntityId()) {
$reminder->relatedPage = $entitiesRepo[$reminder->getEntityName()]->find($reminder->getEntityId())->__toString();
}
} else {
$reminder->relatedPage = 'Liste de ' . $entitiesConfig[$reminder->getEntityName()]['label'];
}

+ 17
- 5
ShopBundle/Twig/FrontendTwigExtension.php Vedi File

@@ -12,6 +12,7 @@ use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Security\Core\Security;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
@@ -29,10 +30,11 @@ class FrontendTwigExtension extends AbstractExtension
protected $productFamilyRepository;
protected $liipCacheHelper;
protected $parameterBag;
protected $kernel;

public function __construct(EntityManagerInterface $em, Security $security, MerchantUtilsInterface $merchantUtils,
FormFactoryInterface $formFactory, RequestStack $requestStack, CacheManager $liipCacheHelper,
ParameterBagInterface $parameterBag)
ParameterBagInterface $parameterBag, KernelInterface $kernel)
{
$this->em = $em;
$this->security = $security;
@@ -44,6 +46,7 @@ class FrontendTwigExtension extends AbstractExtension
$this->productFamilyRepository = $this->em->getRepository($this->em->getClassMetadata(ProductFamilyInterface::class)->getName());
$this->liipCacheHelper = $liipCacheHelper;
$this->parameterBag = $parameterBag;
$this->kernel = $kernel;
}

public function getFunctions()
@@ -62,28 +65,37 @@ class FrontendTwigExtension extends AbstractExtension
return [
new TwigFilter('format_price', [$this, 'formatPrice']),
new TwigFilter('lc_liip', [$this, 'lcLiip']),
new TwigFilter('lc_cache', [$this, 'lcCache']),
];
}

public function lcCache($file){
$cacheTime = filemtime($this->kernel->getProjectDir().'/public'.$file);
if($cacheTime){
return $file.'?c='.$cacheTime;
}else{
return $file."?c=0";
}
}


public function lcLiip($path, $thumb = 'tile', $default = 'default.jpg')
{
if (substr($path, 0, 1) === '/') $path = substr($path, 1);

if ($path) {
$fileManagerFolder = substr($this->getFileManagerFolder(), 1);
$fileManagerFolder = substr($this->getFileManagerFolder(), 1) ;

if (strpos($path, $fileManagerFolder) === false) {
$path = $fileManagerFolder . '/' . $path;
}
//dump(file_exists($path));
if (file_exists($path)) {
return $this->liipCacheHelper->getBrowserPath($path, $thumb);
}

}

return $this->liipCacheHelper->getBrowserPath($this->getFileManagerFolder() . '/' . $default, $thumb);

}

/**

Loading…
Annulla
Salva