Parcourir la source

Merge branch 'feature/gift_coupon' into develop

feature/module_traiteur_v1
Fab il y a 4 ans
Parent
révision
6816a642a5
29 fichiers modifiés avec 619 ajouts et 170 suppressions
  1. +39
    -0
      ShopBundle/Controller/Backend/ReductionCartController.php
  2. +1
    -1
      ShopBundle/Form/Backend/Order/AddOrderReductionCartType.php
  3. +11
    -0
      ShopBundle/Form/Backend/ProductFamily/ProductType.php
  4. +61
    -0
      ShopBundle/Form/Frontend/EditGiftVoucherType.php
  5. +21
    -1
      ShopBundle/Form/Frontend/NewsletterType.php
  6. +11
    -0
      ShopBundle/Form/Frontend/RegistrationType.php
  7. +46
    -0
      ShopBundle/Form/Frontend/SendGiftVoucherType.php
  8. +20
    -0
      ShopBundle/Model/OrderReductionCredit.php
  9. +16
    -1
      ShopBundle/Model/ReductionCart.php
  10. +57
    -0
      ShopBundle/Model/ReductionCredit.php
  11. +1
    -0
      ShopBundle/Model/ReductionTrait.php
  12. +28
    -13
      ShopBundle/Repository/OrderShopRepository.php
  13. +1
    -1
      ShopBundle/Repository/ReductionCartRepository.php
  14. +44
    -0
      ShopBundle/Repository/ReductionCreditRepository.php
  15. +134
    -124
      ShopBundle/Resources/public/css/backend/custom.css
  16. +1
    -1
      ShopBundle/Resources/public/js/backend/script/merchant/vuejs-merchant.js
  17. +6
    -5
      ShopBundle/Resources/public/js/backend/script/productfamily/vuejs-product-family.js
  18. +3
    -1
      ShopBundle/Resources/public/sass/backend/custom.scss
  19. +4
    -0
      ShopBundle/Resources/translations/lcshop.fr.yaml
  20. +2
    -0
      ShopBundle/Resources/views/backend/default/list-fields/field_product_family_total_product_ordered.html.twig
  21. +6
    -0
      ShopBundle/Resources/views/backend/merchant/panel_general.html.twig
  22. +1
    -0
      ShopBundle/Resources/views/backend/productfamily/form.html.twig
  23. +11
    -5
      ShopBundle/Resources/views/backend/productfamily/macros.html.twig
  24. +6
    -0
      ShopBundle/Resources/views/backend/productfamily/panel_price.html.twig
  25. +12
    -8
      ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig
  26. +8
    -2
      ShopBundle/Resources/views/backend/reductioncart/panel_info.html.twig
  27. +2
    -2
      ShopBundle/Services/Order/OrderUtils.php
  28. +50
    -4
      ShopBundle/Services/Order/OrderUtilsReductionTrait.php
  29. +16
    -1
      ShopBundle/Services/Utils.php

+ 39
- 0
ShopBundle/Controller/Backend/ReductionCartController.php Voir le fichier

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

namespace Lc\ShopBundle\Controller\Backend;


use Doctrine\ORM\EntityManagerInterface;

use FOS\UserBundle\Model\UserManagerInterface;
use Lc\ShopBundle\Services\UtilsManager;
use Mailjet\MailjetSwiftMailer\SwiftMailer\MailjetTransport;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class ReductionCartController extends AdminController
{


public function updateReductionCartEntity($entity, $editForm = false)
{
$displayError =false;
foreach ($entity->getCodes() as $code) {
if ($reductionCart = $this->orderUtils->getReductionCartByCode($code)) {
$this->addFlash('success', "Le code " . $code . " est déjà utilisé dans la réduction #" . $reductionCart->getId() . " " . $reductionCart->getTitle());
$displayError = true;
}
}
if ($displayError == false) parent::updateEntity($entity);
}

/* public function persistProductFamilyEntity($entity, $newForm)
{
$entity = $this->productFamilyUtils->processBeforePersistProductFamily($entity, $newForm);

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


+ 1
- 1
ShopBundle/Form/Backend/Order/AddOrderReductionCartType.php Voir le fichier

@@ -38,7 +38,7 @@ class AddOrderReductionCartType extends AbstractType
$builder
->add('reductionCart', EntityType::class, array(
'class' => $reductionCartClass->getName(),
'choices' => $reductionCartRepo->getEligibleReductionCart($entity),
'choices' => $reductionCartRepo->getOnlineReductionCart(),
'required' => true,
'mapped'=>false
));

+ 11
- 0
ShopBundle/Form/Backend/ProductFamily/ProductType.php Voir le fichier

@@ -3,8 +3,11 @@
namespace Lc\ShopBundle\Form\Backend\ProductFamily;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Lc\ShopBundle\Context\ProductInterface;
use Lc\ShopBundle\Context\ReductionCartInterface;
use Lc\ShopBundle\Context\UnitInterface;
use Lc\ShopBundle\Model\ReductionCart;
use Lc\ShopBundle\Services\Utils;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
@@ -128,6 +131,14 @@ class ProductType extends AbstractType
$builder->add('exportNote', TextType::class, array(
'required' =>false
));
$reductionCartClass = $this->em->getClassMetadata(ReductionCartInterface::class)->getName();
$reductionCartRepo = $this->em->getRepository(ReductionCartInterface::class);

/* $builder->add('giftVoucherReductionCart', EntityType::class, array(
'required' =>false,
'class'=> $reductionCartClass,
'choices' => $reductionCartRepo->getOnlineReductionCart(),
));*/

}


+ 61
- 0
ShopBundle/Form/Frontend/EditGiftVoucherType.php Voir le fichier

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

namespace Lc\ShopBundle\Form\Frontend;

use App\Entity\Address;
use App\Entity\OrderShop;
use Doctrine\ORM\EntityManagerInterface;
use Lc\ShopBundle\Model\Ticket;
use Lc\ShopBundle\Services\UtilsManager;
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\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;

class EditGiftVoucherType extends AbstractType
{
protected $orderShopRepository ;
protected $security ;
protected $em ;
protected $priceUtils ;


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

$builder->add('activationDate', DateType::class, [
'label' => 'Date d\'activation de votre bon cadeau :',
'widget'=> 'single_text',
'help'=> 'Date à partir de laquelle la personne pourra utiliser ce bon cadeau.'
//'format'=> 'dd/MM/yyyy'
])
->add('title', TextType::class, [
'label' => 'Message personnalisé affiché dans le bon cadeau :',
'help'=> 'Exemple "Joyeux Noël Tata Suzanne !"'
])
->add('email', EmailType::class, [
'label' => 'Email de la personne à qui vous souhaitez offrir ce bon cadeau :',
'help'=> 'Le bon ne sera utilisable qu\'avec cet adresse e-mail'
])
->add('ownerName', TextType::class,[
'label' => 'Offert par :',
'help'=> 'Sera affiché dans le bon cadeau'
]);


}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
// Configure your form options here
]);
}
}

+ 21
- 1
ShopBundle/Form/Frontend/NewsletterType.php Voir le fichier

@@ -2,19 +2,39 @@

namespace Lc\ShopBundle\Form\Frontend;

use Lc\ShopBundle\Services\UtilsManager;
use Lc\ShopBundle\Validator\Constraints\UniqueEmailValidator;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\EqualTo;
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
use Symfony\Component\Validator\Constraints\NotNull;

class NewsletterType extends AbstractType
{
protected $utils ;

public function __construct(UtilsManager $utilsManager)
{
$this->utils = $utilsManager->getUtils() ;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('email', EmailType::class, [
'label' => 'Renseignez votre adresse email :'
'label' => 'Renseignez votre adresse email :',
'constraints' => [
new Email(),
new NotNull()
]
]);

// captcha
$this->utils->addCaptchaType($builder);
}

public function configureOptions(OptionsResolver $resolver)

+ 11
- 0
ShopBundle/Form/Frontend/RegistrationType.php Voir le fichier

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

use FOS\UserBundle\Form\Type\RegistrationFormType as BaseRegistrationFormType;
use Lc\ShopBundle\Services\UtilsManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -11,6 +12,13 @@ use Symfony\Component\Form\FormBuilderInterface;

class RegistrationType extends AbstractType
{
protected $utils ;

public function __construct(UtilsManager $utilsManager)
{
$this->utils = $utilsManager->getUtils() ;
}

public function getParent()
{
return BaseRegistrationFormType::class;
@@ -47,6 +55,9 @@ class RegistrationType extends AbstractType
'mapped' => false,
'translation_domain' => 'lcshop',
]);

// captcha
$this->utils->addCaptchaType($builder);
}



+ 46
- 0
ShopBundle/Form/Frontend/SendGiftVoucherType.php Voir le fichier

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

namespace Lc\ShopBundle\Form\Frontend;

use App\Entity\Address;
use App\Entity\OrderShop;
use Doctrine\ORM\EntityManagerInterface;
use Lc\ShopBundle\Model\Ticket;
use Lc\ShopBundle\Services\UtilsManager;
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\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Security;

class SendGiftVoucherType extends AbstractType
{
protected $orderShopRepository ;
protected $security ;
protected $em ;
protected $priceUtils ;


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

$builder->add('message', TextareaType::class, [
'label' => 'Message personnalisé',
]);


}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
// Configure your form options here
]);
}
}

+ 20
- 0
ShopBundle/Model/OrderReductionCredit.php Voir le fichier

@@ -30,6 +30,13 @@ abstract class OrderReductionCredit implements ReductionInterface
*/
protected $reductionCredit;


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


public function __toString()
{
return $this->title;
@@ -70,4 +77,17 @@ abstract class OrderReductionCredit implements ReductionInterface

return $this;
}

public function getType(): ?string
{
return $this->type;
}

public function setType(string $type): self
{
$this->type = $type;

return $this;
}

}

+ 16
- 1
ShopBundle/Model/ReductionCart.php Voir le fichier

@@ -70,7 +70,10 @@ abstract class ReductionCart extends AbstractEntity implements ReductionProperty
*/
protected $uncombinableTypes = [];


/**
* @ORM\Column(type="integer")
*/
protected $availableQuantityPerCode;
public function __toString()
{
return $this->title;
@@ -210,4 +213,16 @@ abstract class ReductionCart extends AbstractEntity implements ReductionProperty
return $this;
}

public function getAvailableQuantityPerCode(): ?int
{
return $this->availableQuantityPerCode;
}

public function setAvailableQuantityPerCode(int $availableQuantityPerCode): self
{
$this->availableQuantityPerCode = $availableQuantityPerCode;

return $this;
}

}

+ 57
- 0
ShopBundle/Model/ReductionCredit.php Voir le fichier

@@ -15,6 +15,10 @@ use Lc\ShopBundle\Context\StatusInterface;
*/
abstract class ReductionCredit extends AbstractEntity implements ReductionInterface, FilterMerchantInterface, StatusInterface
{
const TYPE_CREDIT = 'credit' ;
const TYPE_GIFT = 'gift' ;


use ReductionTrait;
use StatusTrait;

@@ -35,7 +39,20 @@ abstract class ReductionCredit extends AbstractEntity implements ReductionInterf
*/
protected $merchant;

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

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

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

public function __construct()
{
@@ -98,4 +115,44 @@ abstract class ReductionCredit extends AbstractEntity implements ReductionInterf

return $this;
}

public function getType(): ?string
{
return $this->type;
}

public function setType(string $type): self
{
$this->type = $type;

return $this;
}




public function getSended(): ?bool
{
return $this->sended;
}

public function setSended(?bool $sended): self
{
$this->sended = $sended;

return $this;
}


public function getOwner(): ?User
{
return $this->owner;
}

public function setOwner(?User $owner): self
{
$this->owner = $owner;

return $this;
}
}

+ 1
- 0
ShopBundle/Model/ReductionTrait.php Voir le fichier

@@ -6,6 +6,7 @@ use Doctrine\ORM\Mapping as ORM;

trait ReductionTrait
{

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

+ 28
- 13
ShopBundle/Repository/OrderShopRepository.php Voir le fichier

@@ -24,16 +24,19 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
return OrderShopInterface::class;
}

public function countValidOrderWithReductionCredit($reductionCredit, $user)
public function countValidOrderWithReductionCredit($reductionCredit, $user=null)
{
$query = $this->findByMerchantQuery();
$query = $this->filterOrderValid($query);
$query->select('count(e.id)');
$query->andWhere('e.user = :user');
if($user) {
$query->andWhere('e.user = :user');
$query->setParameter('user', $user);
}
$query->innerJoin('e.orderReductionCredits', 'orc');
$query->andWhere('orc.reductionCredit = :reductionCredit');
$query->setParameter('reductionCredit', $reductionCredit);
$query->setParameter('user', $user);
return $query->getQuery()->getSingleScalarResult();
}

@@ -64,10 +67,6 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
}


public function filterOrderValid(?QueryBuilder $query): QueryBuilder
{
return $this->_filterOrderStatus($query, OrderStatus::$statusAliasAsValid) ;
}

public function filterOrderWaitingDelivery($query)
{
@@ -78,6 +77,10 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
{
return $this->_filterOrderStatus($query, OrderStatus::$statusAliasAsCart) ;
}
public function filterOrderValid(?QueryBuilder $query): QueryBuilder
{
return $this->_filterOrderStatus($query, OrderStatus::$statusAliasAsValid) ;
}

private function _filterOrderStatus($query, $statusArray) {
$query->leftJoin('e.orderStatus', 'os');
@@ -196,29 +199,42 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
}

$setParameterHorsTournee = false ;
$setParameterGiftVoucher = false ;

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

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

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

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

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

if($setParameterGiftVoucher) {
$query->setParameter('devAliasGiftVoucher', 'giftvoucher') ;
}

if (isset($params['deliveryAvailability'])) {
$deliveryAvailability = $params['deliveryAvailability'] ;

@@ -249,7 +265,6 @@ class OrderShopRepository extends BaseRepository implements DefaultRepositoryInt
$query->orderBy('e.id', 'DESC');
}


if (isset($params['groupBy'])) {
$query->groupBy( $params['groupBy']);
}

+ 1
- 1
ShopBundle/Repository/ReductionCartRepository.php Voir le fichier

@@ -54,7 +54,7 @@ class ReductionCartRepository extends BaseRepository implements DefaultRepositor

}

public function getEligibleReductionCart($order)
public function getOnlineReductionCart()
{
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.status = 1');

+ 44
- 0
ShopBundle/Repository/ReductionCreditRepository.php Voir le fichier

@@ -6,6 +6,7 @@ use Doctrine\ORM\EntityManager;
use Lc\ShopBundle\Context\DefaultRepositoryInterface;
use Lc\ShopBundle\Context\MerchantUtilsInterface;
use Lc\ShopBundle\Context\ReductionCreditInterface;
use Lc\ShopBundle\Model\ReductionCredit;

/**
* @method ReductionCreditInterface|null find($id, $lockMode = null, $lockVersion = null)
@@ -26,8 +27,51 @@ class ReductionCreditRepository extends BaseRepository implements DefaultReposit
{
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.status = 1');
$query->andWhere('e.type = :type');
$query->andWhere(':user MEMBER OF e.users');
$query->setParameter('user', $user);
$query->setParameter('type', ReductionCredit::TYPE_CREDIT);
return $query->getQuery()->getResult() ;
}

public function findReductionGiftToUseByUser($user){
$query = $this->findByMerchantQuery() ;
$query->andWhere('e.status = 1');
$query->andWhere('e.type = :type');
$query->andWhere(':user MEMBER OF e.users');
$query->andWhere(':now > e.activationDate');
$query->setParameter('now', new \DateTime()) ;

$query->setParameter('user', $user);
$query->setParameter('type', ReductionCredit::TYPE_GIFT);
return $query->getQuery()->getResult() ;
}


public function findReductionGiftOwnedByUser($user){
$query = $this->findByMerchantQuery() ;
$query->leftJoin('e.users', 'u');
$query->having('COUNT(u.id) =0');
$query->andWhere('e.status = 1');
$query->andWhere('e.type = :type');
$query->andWhere('e.owner = :user');
$query->setParameter('user', $user);
$query->setParameter('type', ReductionCredit::TYPE_GIFT);
$query->groupBy('e.id');
return $query->getQuery()->getResult() ;
}

public function findReductionGiftOwnedActiveByUser($user){
$query = $this->findByMerchantQuery() ;
$query->leftJoin('e.users', 'u');
$query->having('COUNT(u.id) >0');
$query->andWhere('e.status = 1');
$query->andWhere('e.type = :type');
$query->andWhere('e.owner = :user');
$query->setParameter('user', $user);
$query->setParameter('type', ReductionCredit::TYPE_GIFT);
$query->groupBy('e.id');

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

+ 134
- 124
ShopBundle/Resources/public/css/backend/custom.css Voir le fichier

@@ -84,149 +84,159 @@ a.link-as-text {
body#pdl-body .wrapper .main-sidebar {
bottom: 0;
float: none;
height: 100vh;
height: 110vh;
left: 0;
position: fixed;
top: 0;
}

/* line 41, ../../sass/backend/custom.scss */
body#pdl-body .wrapper .sidebar {
height: 100%;
}

/* line 42, ../../sass/backend/custom.scss */
body#pdl-body .wrapper .sidebar nav {
padding-bottom: 40px;
}

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

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

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

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

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

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

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

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

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

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

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

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

/* line 59, ../../sass/backend/custom.scss */
/* line 61, ../../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 */
/* line 63, ../../sass/backend/custom.scss */
table th.filtered {
border-top: 3px solid var(--primary);
}

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

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

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

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

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

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

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

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

/* line 76, ../../sass/backend/custom.scss */
/* line 78, ../../sass/backend/custom.scss */
table th input {
width: 100%;
}

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

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

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

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

/* line 85, ../../sass/backend/custom.scss */
/* line 87, ../../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 90, ../../sass/backend/custom.scss */
/* line 92, ../../sass/backend/custom.scss */
.form-check-label {
display: block;
position: relative;
@@ -261,7 +271,7 @@ table th .select2-container--default .select2-selection--single {
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* line 154, ../../sass/backend/custom.scss */
/* line 156, ../../sass/backend/custom.scss */
.lc-sortable div:last-child {
display: none;
}
@@ -496,13 +506,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 169, ../../sass/backend/custom.scss */
/* line 171, ../../sass/backend/custom.scss */
.nav-item .btn {
padding-right: 15px;
position: relative;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

/* line 226, ../../sass/backend/custom.scss */
/* line 228, ../../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 */
/* line 229, ../../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 */
/* line 230, ../../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 */
/* line 231, ../../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 */
/* line 232, ../../sass/backend/custom.scss */
.input-group.multiplyingFactor input, .input-group.multiplyingFactor .input-group-text {
font-weight: bold;
border-color: #222;
}

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

/* line 239, ../../sass/backend/custom.scss */
/* line 241, ../../sass/backend/custom.scss */
.order-product-item.redelivery {
background: rgba(18, 104, 253, 0.38) !important;
}
@@ -638,36 +648,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 244, ../../sass/backend/custom.scss */
/* line 246, ../../sass/backend/custom.scss */
.product-form-modal {
display: none;
}

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

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

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

/* line 248, ../../sass/backend/custom.scss */
/* line 250, ../../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 249, ../../sass/backend/custom.scss */
/* line 251, ../../sass/backend/custom.scss */
.products-collection-table .btn-empty-field {
position: absolute;
right: 3px;
@@ -676,14 +686,14 @@ table th .select2-container--default .select2-selection--single {
padding: 0px;
}

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

/* line 251, ../../sass/backend/custom.scss */
/* line 253, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table th {
font-size: 13px;
border-left: 1px solid #dee2e6;
@@ -693,22 +703,22 @@ table th .select2-container--default .select2-selection--single {
position: relative;
}

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

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

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

/* line 255, ../../sass/backend/custom.scss */
/* line 257, ../../sass/backend/custom.scss */
#lc-product-family-edit .products-collection-table td {
border-left: 1px solid #dee2e6;
text-align: center;
@@ -716,26 +726,26 @@ table th .select2-container--default .select2-selection--single {
border-bottom: 1px solid #dee2e6;
}

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

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

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

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

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

/* line 261, ../../sass/backend/custom.scss */
/* line 263, ../../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 */
/* line 265, ../../sass/backend/custom.scss */
table.products-collection-table tr.disabled {
opacity: 0.5;
}

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

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

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

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

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

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

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

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

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

/* line 288, ../../sass/backend/custom.scss */
/* line 290, ../../sass/backend/custom.scss */
#dashboard .btn-statistic {
width: 120px;
height: 70px;
@@ -824,62 +834,62 @@ table.products-collection-table tr.disabled {
line-height: 1rem;
}

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

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

/* line 292, ../../sass/backend/custom.scss */
/* line 294, ../../sass/backend/custom.scss */
#dashboard #range_date_interval {
margin-bottom: 20px;
}

/* line 293, ../../sass/backend/custom.scss */
/* line 295, ../../sass/backend/custom.scss */
#dashboard #range_date_interval label {
float: left;
margin-right: 20px;
}

/* line 294, ../../sass/backend/custom.scss */
/* line 296, ../../sass/backend/custom.scss */
#dashboard #range_date_interval .form-check {
float: left;
margin-right: 10px;
}

/* line 295, ../../sass/backend/custom.scss */
/* line 297, ../../sass/backend/custom.scss */
#dashboard .table-condensed .btn, #dashboard .table-condensed .btn-sm {
white-space: nowrap;
}

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

/* line 307, ../../sass/backend/custom.scss */
/* line 309, ../../sass/backend/custom.scss */
#toast-container {
width: 350px;
}

/* line 308, ../../sass/backend/custom.scss */
/* line 310, ../../sass/backend/custom.scss */
.toast {
float: right;
}

/* line 310, ../../sass/backend/custom.scss */
/* line 312, ../../sass/backend/custom.scss */
#toast-container:before:hover {
opacity: 1;
cursor: pointer;
}

/* line 314, ../../sass/backend/custom.scss */
/* line 316, ../../sass/backend/custom.scss */
#toast-close-all {
border: 0;
position: absolute;

+ 1
- 1
ShopBundle/Resources/public/js/backend/script/merchant/vuejs-merchant.js Voir le fichier

@@ -12,7 +12,7 @@ appOrder = new Vue({
sectionsArray: [
{
name: 'general',
nameDisplay: 'Catalogue'
nameDisplay: 'Général'
},
{
name: 'product',

+ 6
- 5
ShopBundle/Resources/public/js/backend/script/productfamily/vuejs-product-family.js Voir le fichier

@@ -192,7 +192,6 @@ $(window).on('load', function () {
availableQuantityInherited: false,
availableQuantityDefaultInherited: false,
propertyExpirationDateInherited: false

}, window.productForm[this.keyForm])
},
mounted: function () {
@@ -239,8 +238,7 @@ $(window).on('load', function () {
},
availableQuantityDefaultUpdated: function () {
},
propertyExpirationDateUpdated: function () {
},
propertyExpirationDateUpdated: function () {},
setFocusOnField: function (field, y) {
this[field] = true;
this.$nextTick(function () {
@@ -371,7 +369,8 @@ $(window).on('load', function () {
'reductionActive': this.reductionActive,
'reductionUnit': this.reductionUnit,
'reductionValue': this.reductionValue,
'reductionBehaviorTaxRate': this.reductionBehaviorTaxRate
'reductionBehaviorTaxRate': this.reductionBehaviorTaxRate,
'giftVoucherActive': this.giftVoucherActive
};
} else {
return {
@@ -396,7 +395,8 @@ $(window).on('load', function () {
'taxRateValue': null,
'productsQuantityAsTitle': null,
'propertyExpirationDate': this.propertyExpirationDate,
'behaviorExpirationDate': this.behaviorExpirationDate
'behaviorExpirationDate': this.behaviorExpirationDate,
'giftVoucherActive': this.giftVoucherActive
};
}
},
@@ -424,6 +424,7 @@ $(window).on('load', function () {
propertyNoveltyExpirationDateActive: false,
propertyNoveltyExpirationDate:null,
activeProducts: false,
giftVoucherActive: false,
productsQuantityAsTitle: false,
formProducts: {},
currentSection: 'general',

+ 3
- 1
ShopBundle/Resources/public/sass/backend/custom.scss Voir le fichier

@@ -37,7 +37,9 @@ a.link-as-text{color:#333;}
.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 .main-sidebar{bottom: 0; float: none; height: 110vh; left: 0; position: fixed; top: 0;}
body#pdl-body .wrapper .sidebar{height: 100%;}
body#pdl-body .wrapper .sidebar nav{padding-bottom: 40px;}
body#pdl-body .wrapper .content-wrapper{margin-top: 0; padding-top: 57px;}
.sidebar{overflow-y: auto;}


+ 4
- 0
ShopBundle/Resources/translations/lcshop.fr.yaml Voir le fichier

@@ -374,6 +374,10 @@ field:
value: Montant ou valeur
permanent: Réduction permanante
dateRange: Date de but et date de fin
ReductionCredit:
type:
gift: Bon cadeau
credit: Avoir
ReductionCart:
type: Type de réduction
typeOptions:

+ 2
- 0
ShopBundle/Resources/views/backend/default/list-fields/field_product_family_total_product_ordered.html.twig Voir le fichier

@@ -0,0 +1,2 @@
{% import '@LcShop/backend/productfamily/macros.html.twig' as macros %}
{{ macros.total_order_product_family(orderUtils.getTotalProductOrderedLastWeeks(item, 2, true)['total'], item, true) }}

+ 6
- 0
ShopBundle/Resources/views/backend/merchant/panel_general.html.twig Voir le fichier

@@ -12,6 +12,12 @@
<div class="col-12">
{{ form_row(form.merchantConfigs['second-line-element-menu']) }}
</div>
<div class="col-12">
{{ form_row(form.merchantConfigs['message-global-alert-type']) }}
</div>
<div class="col-12">
{{ form_row(form.merchantConfigs['message-global-alert']) }}
</div>
{{ macros.card_end() }}
</div>
</div>

+ 1
- 0
ShopBundle/Resources/views/backend/productfamily/form.html.twig Voir le fichier

@@ -48,6 +48,7 @@
{% if formValues.behaviorExpirationDate %}behaviorExpirationDate: "{{ formValues.behaviorExpirationDate }}",{% endif %}
{% if formValues.propertyExpirationDate %}propertyExpirationDate: "{{ formValues.propertyExpirationDate }}",{% endif %}
{% if formValues.activeProducts %}activeProducts: "{{ formValues.activeProducts }}",{% endif %}
{% if formValues.giftVoucherActive %}giftVoucherActive: "{{ formValues.giftVoucherActive }}",{% endif %}
{% if formValues.productsQuantityAsTitle %}productsQuantityAsTitle: {{ formValues.productsQuantityAsTitle }},{% endif %}

};

+ 11
- 5
ShopBundle/Resources/views/backend/productfamily/macros.html.twig Voir le fichier

@@ -13,13 +13,13 @@
{% endmacro total_order_product %}


{% macro total_order_product_family(totalProductOrdered, productFamily) %}
{% macro total_order_product_family(totalProductOrdered, productFamily,forceByMeasure = 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 is null ? 0 : weekNumberQuantity}}
{% if productFamily and productFamily.behaviorCountStock== constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') %}
{% if productFamily and (productFamily.behaviorCountStock== constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') or forceByMeasure)%}
{{ productFamily.unit.unitReference }}
{% endif %}
</strong>
@@ -96,7 +96,7 @@
{{ _self.product_field(3, product.price, 'price', false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }}
{{ _self.product_field(3, product.priceWithTax, 'priceWithTax', false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }}

<td colspan="2">
<td colspan="2" v-show="productFamily.giftVoucherActive!= true">
<span v-if="productFamily.reductionActive" class="text-danger">
{% verbatim %}{{ marginProfitWithReduction }}{% endverbatim %}€<br />
{% verbatim %}{{ marginProfitPercentWithReduction }}{% endverbatim %}%
@@ -113,11 +113,17 @@
{{ _self.product_field(2, product.availableQuantityDefault, 'availableQuantityDefault',false, '', 'v-show="productFamily.behaviorCountStock== \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') ~ '\' && productFamily.behaviorStockWeek!= \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE') ~ '\'"') }}


<td colspan="2" v-show="productFamily.behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' || productFamily.behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}'">
<td colspan="2">

{{ _self.total_order_product(totalProductOrdered) }}

</td>

{# <td colspan="4" v-show="productFamily.giftVoucherActive== true">

{{ form_row(product.giftVoucherReductionCart, {"label": false, "attr" : {'v-model' : 'giftVoucherReductionCart', ':required': 'status ==1 && productFamily.giftVoucherActive'}}) }}

</td>#}
<td colspan="3">
<button type="button" class="btn-sm btn-info" @click="modalProductForm()">
<i class="fa fa-edit"></i>
@@ -147,9 +153,9 @@
</div>
<div class="col">
{{ form_row(product.exportNote) }}

</div>


</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-info float-right" data-dismiss="modal">Ok</button>

+ 6
- 0
ShopBundle/Resources/views/backend/productfamily/panel_price.html.twig Voir le fichier

@@ -21,9 +21,15 @@
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorPrice'}}) }}
{% endfor %}
</div>
<div class="col-12" v-show="activeProducts == true">
<label>Bon cadeau</label>
{{ form_row(form.giftVoucherActive, {"attr": {"v-model": 'giftVoucherActive'}}) }}
</div>

{{ macros.endCard(true) }}



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

+ 12
- 8
ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig Voir le fichier

@@ -83,7 +83,7 @@
<button v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'" v-on:click="emptyProductsField('priceWithTax');"
class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button>
</th>
<th colspan="2">
<th colspan="2" v-show="giftVoucherActive!= true">
Marge HT
</th>

@@ -105,11 +105,13 @@
<button v-on:click="emptyProductsField('availableQuantityDefault');"
class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button>
</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 colspan="2">
Semaine / Commandés
</th>

{#<th colspan="4"
v-show="giftVoucherActive== true">
Réduction "Bon cadeaux"
</th>#}
<th colspan="3" class="">
Action
</th>
@@ -174,7 +176,7 @@
<th colspan="3" class="price main-info">
${productFamily.priceWithTax}
</th>
<th colspan="2" class="price">
<th colspan="2" class="price" v-show="giftVoucherActive!= true">
${productFamily.marginProfit}€<br/>
${productFamily.marginProfitPercent}%
</td>
@@ -190,10 +192,11 @@
<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 colspan="2">
</th>

{#<th colspan="4"
v-show="giftVoucherActive== true">
</th>#}
<th colspan="3" class="">

</th>
@@ -246,6 +249,7 @@
{% 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.giftVoucherReductionCart %}giftVoucherReductionCart: {{ product.vars.value.giftVoucherReductionCart.id }},{% endif %}#}
{# {% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %} #}
};
window.formProductTemplate[{{ keyForm }}] = '{{ product_family_macros.product_row(product, totalProductOrdered[product.vars.value.id])|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}';

+ 8
- 2
ShopBundle/Resources/views/backend/reductioncart/panel_info.html.twig Voir le fichier

@@ -9,17 +9,23 @@
<div class="col-12">
{{ form_row(form.type) }}
</div>
<div class="col-6">
<div class="col-4">
{{ form_row(form.availableQuantity) }}
</div>
<div class="col-6">
<div class="col-4">
{{ form_row(form.availableQuantityPerUser) }}
</div>

<div class="col-4">
{{ form_row(form.availableQuantityPerCode) }}
</div>
<div class="col-12">
{{ form_row(form.codes, {"attr":{'v-on:keyup' : 'updateCodes'}}) }}
</div>




{{ macros.endCard() }}

</div>

+ 2
- 2
ShopBundle/Services/Order/OrderUtils.php Voir le fichier

@@ -177,7 +177,7 @@ class OrderUtils
$this->em->flush();
}

$this->eventOrderShopChangeQuantity($orderShop) ;
$this->eventCartChange($orderShop) ;
}
}
else {
@@ -380,7 +380,7 @@ class OrderUtils
return $this->priceUtils->getTotalWithTax($orderShop) >= 0 ;
}

public function eventOrderShopChangeQuantity(OrderShopInterface $orderShop)
public function eventCartChange(OrderShopInterface $orderShop)
{

}

+ 50
- 4
ShopBundle/Services/Order/OrderUtilsReductionTrait.php Voir le fichier

@@ -7,9 +7,24 @@ use Lc\ShopBundle\Context\OrderReductionCreditInterface;
use Lc\ShopBundle\Context\OrderShopInterface;
use Lc\ShopBundle\Context\ReductionCartInterface;
use Lc\ShopBundle\Context\ReductionCreditInterface;
use Lc\ShopBundle\Model\ReductionCredit;
use function Matrix\trace;

trait OrderUtilsReductionTrait
{
public function getReductionCartByCode($code){
$reductionCartRepository = $this->em->getRepository(ReductionCartInterface::class);

$reductionCarts = $reductionCartRepository->findByCode($code);
$findReductionCart = null;
foreach ($reductionCarts as $reductionCart) {
if ($reductionCart && in_array($code, $reductionCart->getCodes())) {
$findReductionCart = $reductionCart;
}
}
return $findReductionCart;
}

public function compareOrderProductReductionCatalog($orderProductReductionCatalog1, $orderProductReductionCatalog2)
{
return (!$orderProductReductionCatalog1 && !$orderProductReductionCatalog2)
@@ -39,7 +54,7 @@ trait OrderUtilsReductionTrait
}


public function createOrderReductionCart(OrderShopInterface $orderShop, ReductionCartInterface $reductionCart)
public function createOrderReductionCart(OrderShopInterface $orderShop, ReductionCartInterface $reductionCart, $code = null)
{
$orderReductionCartClass = $this->em->getClassMetadata(OrderReductionCartInterface::class);
$orderReductionCart = new $orderReductionCartClass->name;
@@ -50,6 +65,7 @@ trait OrderUtilsReductionTrait
$orderReductionCart->setTitle($reductionCart->getTitle());
$orderReductionCart->setValue($reductionCart->getValue());
$orderReductionCart->setUnit($reductionCart->getUnit());
$orderReductionCart->setCodeUsed($code);
$orderReductionCart->setBehaviorTaxRate($reductionCart->getBehaviorTaxRate());
$orderReductionCart->setFreeShipping($reductionCart->getFreeShipping());
$orderReductionCart->setAppliedTo($reductionCart->getAppliedTo());
@@ -77,9 +93,17 @@ trait OrderUtilsReductionTrait
}

// n'a pas été utilisé
if ($this->orderShopRepo->countValidOrderWithReductionCredit($reductionCredit, $user) > 0) {
$this->utils->addFlash('error', 'error.reductionCredit.alreadyUse');
return false;
if($reductionCredit->getType()== ReductionCredit::TYPE_CREDIT){
if ($this->orderShopRepo->countValidOrderWithReductionCredit($reductionCredit, $user) > 0) {
$this->utils->addFlash('error', 'error.reductionCredit.alreadyUse');
return false;
}
}else{
if ($this->orderShopRepo->countValidOrderWithReductionCredit($reductionCredit) > 0) {
$this->utils->addFlash('error', 'error.reductionCredit.alreadyUse');
return false;
}

}

return true;
@@ -108,6 +132,7 @@ trait OrderUtilsReductionTrait
$orderReductionCredit->setValue($reductionCredit->getValue());
$orderReductionCredit->setUnit($reductionCredit->getUnit());
$orderReductionCredit->setBehaviorTaxRate($reductionCredit->getBehaviorTaxRate());
$orderReductionCredit->setType($reductionCredit->getType());

$orderShop->addOrderReductionCredit($orderReductionCredit) ;

@@ -143,6 +168,27 @@ trait OrderUtilsReductionTrait
return $reductionCreditsArray ;
}

public function getReductionGiftsAvailableByUser($user)
{
$reductionGifts = $this->reductionCreditRepo->findReductionGiftToUseByUser($user) ;

$reductionGiftsArray = [] ;
foreach($reductionGifts as $reductionGift) {
if(!$this->orderShopRepo->countValidOrderWithReductionCredit($reductionGift)) {
$reductionGiftsArray[] = $reductionGift ;
}
}

return $reductionGiftsArray ;
}

public function isReductionGiftUsed($reductionGift){
if($this->orderShopRepo->countValidOrderWithReductionCredit($reductionGift)) {
return true;
}else{
return false;
}
}
public function isReductionCreditAddedToOrder($orderShop, $reductionCredit)
{
foreach($orderShop->getOrderReductionCredits() as $orderReductionCredit) {

+ 16
- 1
ShopBundle/Services/Utils.php Voir le fichier

@@ -24,9 +24,12 @@ use Lc\ShopBundle\Context\UserInterface;
use Lc\ShopBundle\Context\UserPointSaleInterface;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\HttpClient\HttplugClient;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Validator\Constraints\EqualTo;
use Symfony\Contracts\Translation\TranslatorInterface;

class Utils
@@ -542,6 +545,18 @@ class Utils
}



public function addCaptchaType(FormBuilderInterface $builder)
{
$builder->add('specialField', HiddenType::class, [
'data' => 0,
'mapped' => false,
'attr' => [
'class' => 'special-field'
],
'constraints' => [
new EqualTo(['value' => $this->parameterBag->get('app.captcha_value'), 'message' => 'Valeur incorrecte'])
],
]);
}

}

Chargement…
Annuler
Enregistrer