Browse Source

Amélioration formulaire PRoductFamily & Gestion des erreurs & Intégration des caractéristqiues

reduction
Fab 4 years ago
parent
commit
fe7176303d
42 changed files with 3669 additions and 990 deletions
  1. +9
    -1
      ShopBundle/Context/GlobalParamInterface.php
  2. +55
    -119
      ShopBundle/Controller/Admin/ProductFamilyController.php
  3. +1
    -0
      ShopBundle/EventSubscriber/EditEventSubscriber.php
  4. +24
    -5
      ShopBundle/Form/ProductType.php
  5. +145
    -57
      ShopBundle/Model/ProductFamily.php
  6. +8
    -6
      ShopBundle/Model/ProductPropertyTrait.php
  7. +0
    -7
      ShopBundle/Resources/config/easy_admin/base.yaml
  8. +50
    -1
      ShopBundle/Resources/public/css/backend/custom.css
  9. +2434
    -1
      ShopBundle/Resources/public/js/backend/plugin/select2/select2.min.js
  10. +101
    -0
      ShopBundle/Resources/public/js/backend/script/default/init-common.js
  11. +53
    -2
      ShopBundle/Resources/public/js/backend/script/default/init-edit.js
  12. +10
    -120
      ShopBundle/Resources/public/js/backend/script/default/init-list.js
  13. +36
    -0
      ShopBundle/Resources/public/js/backend/script/default/init-sort.js
  14. +1
    -16
      ShopBundle/Resources/public/js/backend/script/default/utils.js
  15. +40
    -14
      ShopBundle/Resources/public/js/backend/script/default/vuejs-mixins.js
  16. +1
    -9
      ShopBundle/Resources/public/js/backend/script/order/vuejs-order.js
  17. +23
    -0
      ShopBundle/Resources/public/js/backend/script/productfamily/init-edit.js
  18. +71
    -58
      ShopBundle/Resources/public/js/backend/script/productfamily/vuejs-product-family.js
  19. +49
    -0
      ShopBundle/Resources/translations/lcshop.fr.yaml
  20. +3
    -2
      ShopBundle/Resources/views/backend/default/block/macros.html.twig
  21. +2
    -0
      ShopBundle/Resources/views/backend/default/block/script-vuejs.html.twig
  22. +9
    -2
      ShopBundle/Resources/views/backend/default/edit.html.twig
  23. +13
    -15
      ShopBundle/Resources/views/backend/default/layout.html.twig
  24. +8
    -3
      ShopBundle/Resources/views/backend/default/list.html.twig
  25. +9
    -3
      ShopBundle/Resources/views/backend/default/new.html.twig
  26. +56
    -6
      ShopBundle/Resources/views/backend/form/custom_bootstrap_4.html.twig
  27. +21
    -2
      ShopBundle/Resources/views/backend/order/edit.html.twig
  28. +16
    -8
      ShopBundle/Resources/views/backend/order/form.html.twig
  29. +0
    -10
      ShopBundle/Resources/views/backend/order/new.html.twig
  30. +88
    -76
      ShopBundle/Resources/views/backend/order/panel_orderproducts.html.twig
  31. +0
    -219
      ShopBundle/Resources/views/backend/productfamily/2panel_products.html.twig
  32. +9
    -1
      ShopBundle/Resources/views/backend/productfamily/edit.html.twig
  33. +38
    -22
      ShopBundle/Resources/views/backend/productfamily/form.html.twig
  34. +0
    -5
      ShopBundle/Resources/views/backend/productfamily/new.html.twig
  35. +8
    -0
      ShopBundle/Resources/views/backend/productfamily/panel_general.html.twig
  36. +1
    -1
      ShopBundle/Resources/views/backend/productfamily/panel_price.html.twig
  37. +82
    -81
      ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig
  38. +97
    -27
      ShopBundle/Resources/views/backend/productfamily/panel_property.html.twig
  39. +11
    -1
      ShopBundle/Resources/views/backend/productfamily/panel_stock.html.twig
  40. +4
    -0
      ShopBundle/Services/GlobalParam.php
  41. +77
    -90
      ShopBundle/Services/Utils.php
  42. +6
    -0
      ShopBundle/Twig/BridgeTwigExtension.php

+ 9
- 1
ShopBundle/Context/GlobalParamInterface.php View File

@@ -5,9 +5,17 @@ namespace Lc\ShopBundle\Context ;
interface GlobalParamInterface
{
/**
* Retourne le merchant courant en focntion du user ou du cookie du visitor
* Retourne le merchant courant en fonction du user ou du cookie du visitor
*
* @return MerchantInterface
*/
public function getCurrentMerchant();


/**
* Retourne la tva par défaut du merchant courant
*
* @return TaxRateInterface
*/
public function getCurrentMerchantTaxRate();
}

+ 55
- 119
ShopBundle/Controller/Admin/ProductFamilyController.php View File

@@ -37,142 +37,71 @@ class ProductFamilyController extends AdminController

$formBuilder->add('productCategories', ProductFamilyCategoriesType::class);

//CHOICE qui permet de sélectionner une taxe
//ça c'est du lourd fais très attention faudra refactorer
$this->getUser()->getMerchant()->getTaxRate();
$choicesTaxRate['Valeur par défaut'] = 0;
$choicesSupplierTaxRate['Hérité de la TVA du produit'] = 0;
foreach ($this->em->getRepository($this->taxRateClass->name)->findAll() as $tax) {
$choicesTaxRate[$tax->getTitle()] = $tax->getId();
$choicesSupplierTaxRate[$tax->getTitle()] = $tax->getId();
$this->choicesTaxRateParam[$tax->getId()] = $tax->getValue();
$this->choicesSupplierTaxRateParam[$tax->getId()] = $tax->getValue();
}

//là mon ami je kiffe symfo !!!!!
$this->choicesTaxRateParam[0] = $this->getUser()->getMerchant()->getTaxRate()->getValue();

// choices unit


$formBuilder->add('taxRate', ChoiceType::class, array(
'label' => 'TVA',
'choices' => $choicesTaxRate,
'mapped' => false,
'data' => 0,
'choice_attr' => function ($choice, $key, $value) {
return ['data-tax-rate-value' => $this->choicesTaxRateParam[$choice]];
},
));

$formBuilder->add('differentSupplierTaxRate', CheckboxType::class, array(
'required' => false,
'mapped' => false
));

$this->choicesSupplierTaxRateParam[0] = 'inherited';

$formBuilder->add('supplierTaxRate', ChoiceType::class, array(
'label' => 'TVA du fournisseur',
'choices' => $choicesSupplierTaxRate,
'data' => 0,
'mapped' => false,
'choice_attr' => function ($choice, $key, $value) {
return ['data-tax-rate-value' => $this->choicesSupplierTaxRateParam[$choice]];
},
));

/*$formBuilder->add('taxRate', EntityType::class, array(
'class' => $this->em->getClassMetadata(TaxRateInterface::class)->name,
'required' =>false,
'placeholder'=> 'Tva par défaut ('.$this->getUser()->getMerchant()->getTaxRate()->getValue().'%)'
));*/

$this->choicesUnitsReference = [];
$unitClass = $this->em->getClassMetadata(UnitInterface::class)->getName();
foreach ($this->em->getRepository($unitClass)->findAll() as $unit) {
$choicesUnits[$unit->getWordingUnit()] = $unit->getId();
$this->choicesUnitsReference[$unit->getId()]['unit-reference'] = $unit->getUnitReference();
$this->choicesUnitsReference[$unit->getId()]['coefficient'] = $unit->getCoefficient();
}

$formBuilder->add('unit', ChoiceType::class, array(
'label' => 'TVA du fournisseur',
'choices' => $choicesUnits,
'data' => 0,
'mapped' => false,
'choice_attr' => function ($choice, $key, $value) {
return [
'data-unit-reference' => $this->choicesUnitsReference[$choice]['unit-reference'],
'data-coefficient' => $this->choicesUnitsReference[$choice]['coefficient']
];
},
));

$formBuilder->add('quantity', NumberType::class, array(
'label' => 'Quantité',
'attr' => [
'append_html' => 'g'
]
));

$formBuilder->add('price', NumberType::class, array(
'label' => 'Prix',
));

$formBuilder->add('priceWithTax', NumberType::class, array(
'label' => 'Prix TTC',
'required' => false,
'mapped' => false
));

$formBuilder->add('buyingPrice', NumberType::class, array(
'label' => 'Prix d\'achat',
));

$formBuilder->add('priceByRefUnit', NumberType::class, array(
'label' => 'Prix de vente en fonction de l\'unité de référence',
'mapped' => false,
'required' => false
));

$formBuilder->add('priceByRefUnitWithTax', NumberType::class, array(
'label' => 'Prix',
'mapped' => false,
'required' => false
));

$formBuilder->add('buyingPriceWithTax', NumberType::class, array(
'label' => 'Prix d\'achat TTC',
'required' => false,
'mapped' => false
));
$formBuilder->add('multiplyingFactor', NumberType::class, array(
'label' => 'Coefficiant de multiplication',
'mapped' => false,
$formBuilder->add('warningMessageType', ChoiceType::class, array(
'choices' => array(
'field.default.warningMessageTypeOptions.alert' => 'alert',
'field.default.warningMessageTypeOptions.info' => 'info'
),
'translation_domain' => 'lcshop',
'multiple' => false,
'expanded' => false,
'required' => false
));


$formBuilder->add('behaviorCountStock', ChoiceType::class, array(
'label' => 'Stock',
'empty_data' => 'by-product-family',
'choices' => array(
'Gèrer le stock par quantité' => 'by-quantity',
'Gèrer le stock par produit (à la pièce)' => 'by-product-family',
'Gèrer le stock par déclinaison' => 'by-product'
'field.ProductFamily.behaviorCountStockOptions.byQuantity' => 'by-quantity',
'field.ProductFamily.behaviorCountStockOptions.byProductFamily' => 'by-product-family',
'field.ProductFamily.behaviorCountStockOptions.byProduct' => 'by-product'
),
'translation_domain' => 'lcshop',
'multiple' => false,
'expanded' => true
));

$formBuilder->add('organicLabel', ChoiceType::class, array(
'label' => 'Type de labellisation',
$formBuilder->add('propertyOrganicLabel', ChoiceType::class, array(
'choices' => array(
'Agriculture biologique' => 'bio',
'Nature & progrès' => 'nature-progres',
'Haute valeur environnementale' => 'hve'
'field.ProductFamily.organicLabelOptions.bio' => 'by-quantity',
'field.ProductFamily.organicLabelOptions.natureProgres' => 'nature-progres',
'field.ProductFamily.organicLabelOptions.hVE' => 'hve'
),
'translation_domain' => 'lcshop',
'multiple' => false,
'expanded' => false,
'required' => false
));

$formBuilder->add('typeExpirationDate', ChoiceType::class, array(
'choices' => array(
'field.default.dlc' => 'dlc',
'field.default.ddm' => 'ddm',
'field.default.dluo' => 'dluo'
),
'translation_domain' => 'lcshop',
'multiple' => false,
'expanded' => true,
'required'=>false
));

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


$formBuilder->add('products', CollectionType::class, array(
'label' => 'Déclinaisons',
@@ -189,17 +118,24 @@ class ProductFamilyController extends AdminController

public function updateEntity($entity)
{
$prodductFamilyRequest = $this->request->request->get('productfamily');
$productFamilyRequest = $this->request->request->get('productfamily');

if ($taxRateId = intval($prodductFamilyRequest['taxRate']) > 0) {
$taxRateId = intval($productFamilyRequest['taxRate']);
if ($taxRateId > 0) {
$repo = $this->em->getRepository(TaxRateInterface::class);
$entity->setTaxRate($repo->find($taxRateId));
}
dump($productFamilyRequest);
$unitId = intval($productFamilyRequest['unit']);
if ($unitId > 0) {
$repo = $this->em->getRepository(UnitInterface::class);
$entity->setUnit($repo->find($unitId));
}


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

$this->setUpdated($entity);

parent::updateEntity($entity);
}

+ 1
- 0
ShopBundle/EventSubscriber/EditEventSubscriber.php View File

@@ -60,6 +60,7 @@ class EditEventSubscriber implements EventSubscriberInterface

public function updateCommonProperty(GenericEvent $event){

dump($event);
/* $this->setUpdated($entity);
$this->setAddressCreatedBy($entity) ;*/
}

+ 24
- 5
ShopBundle/Form/ProductType.php View File

@@ -8,6 +8,7 @@ use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Lc\ShopBundle\Context\ProductFamilyInterface;
use Lc\ShopBundle\Context\ProductInterface;
use Lc\ShopBundle\Context\TaxRateInterface;
use Lc\ShopBundle\Context\UnitInterface;
use Lc\ShopBundle\Services\Utils;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@@ -47,10 +48,27 @@ class ProductType extends AbstractType
]
));


$this->choicesUnitsReference = [];
$unitClass = $this->em->getClassMetadata(UnitInterface::class)->getName();
foreach ($this->em->getRepository($unitClass)->findAll() as $unit) {
$choicesUnits[$unit->getWording()] = $unit->getId();
$this->choicesUnitsReference[$unit->getId()]['unit-reference'] = $unit->getUnitReference();
$this->choicesUnitsReference[$unit->getId()]['coefficient'] = $unit->getCoefficient();
}

$builder->add('unit', ChoiceType::class, array(
'label' => 'Unité',
"required" => false,
'choices' => $this->utils->getUnitsListFormatedForType()
'label' => 'TVA du fournisseur',
'choices' => $choicesUnits,
'data' => 0,
'required'=>false,
'mapped' => false,
'choice_attr' => function ($choice, $key, $value) {
return [
'data-unit-reference' => $this->choicesUnitsReference[$choice]['unit-reference'],
'data-coefficient' => $this->choicesUnitsReference[$choice]['coefficient']
];
},
));


@@ -91,10 +109,11 @@ class ProductType extends AbstractType
'required' => false,
));

$builder->add('expirationDate', DateType::class,array(
$builder->add('propertyExpirationDate', DateType::class, array(
'required' => false,
'widget' => 'single_text'
'widget'=> 'single_text'
));

$builder->add('position', HiddenType::class);

}

+ 145
- 57
ShopBundle/Model/ProductFamily.php View File

@@ -58,6 +58,16 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
*/
protected $subtitle;

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

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $warningMessageType;

/**
* @ORM\Column(type="text", nullable=true)
*/
@@ -74,24 +84,39 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
protected $behaviorCountStock;

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

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

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $noveltyExpirationDate;
protected $propertyAllergens;

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

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

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

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


public function __construct()
@@ -233,6 +258,30 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
}


public function getWarningMessage(): ?string
{
return $this->warningMessage;
}

public function setWarningMessage(?string $warningMessage): self
{
$this->warningMessage = $warningMessage;

return $this;
}

public function getWarningMessageType(): ?string
{
return $this->warningMessageType;
}

public function setWarningMessageType(?string $warningMessageType): self
{
$this->warningMessageType = $warningMessageType;

return $this;
}

public function getNote(): ?string
{
return $this->note;
@@ -271,105 +320,144 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr
}


public function getIsNovelty(): ?bool


private function getCheapestOrMostExpensiveProduct($comparisonFunction, $returnSelfIfNotActiveProducts)
{
return $this->isNovelty;
$products = $this->getProducts()->getValues() ;
if(count($products) > 0) {
usort($products, $comparisonFunction) ;
return $products[0] ;
}
if($returnSelfIfNotActiveProducts) {
return $this ;
}
else {
return false ;
}
}

public function isNoveltyOnline(): ?bool
public function getCheapestProduct()
{
if($this->isNovelty) {
if($this->getNoveltyExpirationDate()) {
$now = new \DateTime() ;
if($now <= $this->getNoveltyExpirationDate()) {
return true ;
}
}
else {
return $this->getCheapestOrMostExpensiveProduct(function($a, $b) {
return $a->getPriceInherited() > $b->getPriceInherited() ;
},true) ;
}

public function getCheapestProductByUnitRef()
{
return $this->getCheapestOrMostExpensiveProduct(function($a, $b) {
return $a->getPriceByUnitRef() > $b->getPriceByUnitRef() ;
},false) ;
}

public function getMostExpensiveProductByUnitRef()
{
return $this->getCheapestOrMostExpensiveProduct(function($a, $b) {
return $a->getPriceByUnitRef() < $b->getPriceByUnitRef() ;
},false) ;
}



public function isPropertyNoveltyOnline(): ?bool
{

if($this->getPropertyNoveltyExpirationDate()) {
$now = new \DateTime() ;
if($now <= $this->getNoveltyExpirationDate()) {
return true ;
}
}
else {
return false ;
}

}

return false ;
public function getPropertyNoveltyExpirationDate(): ?\DateTimeInterface
{
return $this->propertyNoveltyExpirationDate;
}

public function setIsNovelty(?bool $isNovelty): self
public function setPropertyNoveltyExpirationDate(?\DateTimeInterface $propertyNoveltyExpirationDate): self
{
$this->isNovelty = $isNovelty;
$this->propertyNoveltyExpirationDate = $propertyNoveltyExpirationDate;

return $this;
}

public function getNoveltyExpirationDate(): ?\DateTimeInterface
public function getPropertyOrganicLabel(): ?string
{
return $this->noveltyExpirationDate;
return $this->propertyOrganicLabel;
}

public function setNoveltyExpirationDate(?\DateTimeInterface $noveltyExpirationDate): self
public function setPropertyOrganicLabel(?string $propertyOrganicLabel): self
{
$this->noveltyExpirationDate = $noveltyExpirationDate;
$this->propertyOrganicLabel = $propertyOrganicLabel;

return $this;
}

public function getIsOrganic(): ?bool
public function getPropertyAllergens(): ?string
{
return $this->isOrganic;
return $this->propertyAllergens;
}

public function setIsOrganic(?bool $isOrganic): self
public function setPropertyAllergens(?string $propertyAllergens): self
{
$this->isOrganic = $isOrganic;
$this->propertyAllergens = $propertyAllergens;

return $this;
}

public function getOrganicLabel(): ?string
public function getPropertyComposition(): ?string
{
return $this->organicLabel;
return $this->propertyComposition;
}

public function setOrganicLabel(?string $organicLabel): self
public function setPropertyComposition(?string $propertyComposition): self
{
$this->organicLabel = $organicLabel;
$this->propertyComposition = $propertyComposition;

return $this;
}

private function getCheapestOrMostExpensiveProduct($comparisonFunction, $returnSelfIfNotActiveProducts)
public function getPropertyFragrances(): ?string
{
$products = $this->getProducts()->getValues() ;
if(count($products) > 0) {
usort($products, $comparisonFunction) ;
return $products[0] ;
}
if($returnSelfIfNotActiveProducts) {
return $this ;
}
else {
return false ;
}
return $this->propertyFragrances;
}

public function getCheapestProduct()
public function setPropertyFragrances(?string $propertyFragrances): self
{
return $this->getCheapestOrMostExpensiveProduct(function($a, $b) {
return $a->getPriceInherited() > $b->getPriceInherited() ;
},true) ;
$this->propertyFragrances = $propertyFragrances;

return $this;
}

public function getCheapestProductByUnitRef()

public function getBehaviorExpirationDate(): ?string
{
return $this->getCheapestOrMostExpensiveProduct(function($a, $b) {
return $a->getPriceByUnitRef() > $b->getPriceByUnitRef() ;
},false) ;
return $this->behaviorExpirationDate;
}

public function getMostExpensiveProductByUnitRef()
public function setBehaviorExpirationDate(?string $behaviorExpirationDate): self
{
return $this->getCheapestOrMostExpensiveProduct(function($a, $b) {
return $a->getPriceByUnitRef() < $b->getPriceByUnitRef() ;
},false) ;
$this->behaviorExpirationDate = $behaviorExpirationDate;

return $this;
}

public function getTypeExpirationDate(): ?string
{
return $this->typeExpirationDate;
}

public function setTypeExpirationDate(?string $typeExpirationDate): self
{
$this->typeExpirationDate = $typeExpirationDate;

return $this;
}

}

+ 8
- 6
ShopBundle/Model/ProductPropertyTrait.php View File

@@ -33,7 +33,8 @@ trait ProductPropertyTrait
/**
* @ORM\Column(type="date", nullable=true)
*/
protected $expirationDate;
protected $propertyExpirationDate;


public function getBuyingPrice(): ?float
{
@@ -83,15 +84,16 @@ trait ProductPropertyTrait
return $this;
}

public function getExpirationDate(): ?\DateTimeInterface
public function getPropertyExpirationDate(): ?\DateTimeInterface
{
return $this->expirationDate;
return $this->propertyExpirationDate;
}

public function setExpirationDate(?\DateTimeInterface $expirationDate): self
public function setPropertyExpirationDate(?\DateTimeInterface $propertyExpirationDate): self
{
$this->expirationDate = $expirationDate;
$this->propertyExpirationDate = $propertyExpirationDate;

return $this;
}
}

}

+ 0
- 7
ShopBundle/Resources/config/easy_admin/base.yaml View File

@@ -12,18 +12,11 @@ easy_admin:
favicon: '/assets/img/backend/favicon-pdl.png'
js:
- '/bundles/cksourceckfinder/ckfinder/ckfinder.js'
- '/bundles/lcshop/js/backend/plugin/vue.min.js'
#- '/bundles/lcshop/js/backend/plugin/jquery-ui.min.js'
- '/bundles/lcshop/js/backend/script/setup-ckfinder.js'
- '/bundles/lcshop/js/backend/script/utils.js'
- '/bundles/lcshop/js/backend/script/custom.js'
- '/bundles/lcshop/js/backend/script/productfamily/vuejs-mixins.js'
- '/bundles/lcshop/js/backend/script/productfamily/vuejs-product-family.js'
- '/bundles/lcshop/js/backend/script/order/vuejs-order.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'

+ 50
- 1
ShopBundle/Resources/public/css/backend/custom.css View File

@@ -16,12 +16,52 @@ table th.filtered{border-top:3px solid var(--primary);}
td.actions{white-space: nowrap;}


/************************ form error *********************/

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


/*CUSTOM Checkbox
/* Customize the label (the container) */
.form-check-label {display: block; position: relative; padding-left: 26px; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;}
/* Hide the browser's default checkbox */
.form-check-label input { position: absolute; opacity: 0; cursor: pointer; height: 0; width: 0;}
/* Create a custom checkbox */

.form-check{padding-left: 0px;}

.form-sent .form-check-label input:invalid ~ .checkmark { border-color: #dc3545;}
.form-check-label input ~ .checkmark { position: absolute; top: 0; left: 0; height: 18px; width: 18px; background-color: #eee;border: 1px solid var(--primary);}
.form-check-label.big input ~ .checkmark { height: 21px; width: 21px; }
.form-check-label input[type="checkbox"] ~ .checkmark {top: 2px;}
.form-check-label input[type="radio"] ~ .checkmark { top:3px; border-radius: 50%;}
.form-check-label:hover input ~ .checkmark { background-color: #ccc;}
/* When the checkbox is checked, add a blue background */
.form-check-label input:checked ~ .checkmark {background-color: var(--primary);}
/* Create the checkmark/indicator (hidden when not checked) */
.form-check-label .checkmark:after { content: ""; position: absolute; display: none;}
/* Show the checkmark when checked */
.form-check-label input:checked ~ .checkmark:after {display: block;}
/* Style the checkmark/indicator */
.form-check-label .checkmark:after {left: 7px; top: 3px; width: 6px; height: 11px; border: solid white; border-width: 0 3px 3px 0; -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg);}
.form-check-label input[type="checkbox"] ~ .checkmark:after {left: 6px; top: 2px; width: 6px; height: 10px; border: solid white; border-width: 0 3px 3px 0; -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg);}
.form-check-label input[type="radio"] ~ .checkmark:after {top: 4px; left: 4px; width: 8px; height: 8px; border-radius: 50%; background: white;}

.form-check-label.big input[type="checkbox"] ~ .checkmark:after {left: 7px; top: 3px; width: 6px; height: 11px;}
/* Create a custom radio button */



/* Général */
.btn.btn-primary.action-save{float: right;}

.input-group-text {
padding: 0.250rem .75rem ;
}


#toast-container.toast-top-right{top:60px}

/* SIDEBAR */
@@ -49,6 +89,12 @@ td.actions{white-space: nowrap;}

.lc-ckfinder-wrap .lc-ckfinder-button{width: 100%; bottom: 0px; left: 0; position: absolute;}

/* VUES JS */
.nav-item .btn {padding-right: 15px; position: relative;}
.nav-item .btn .invalid-form{display: none; position: absolute; top: -7px;right: -6px; color: #dc3545; background: #fff; border-radius: 10px;font-size: 1.2rem;}
.nav-item.has-invalid .btn .invalid-form{display: inline-block; z-index: 2;}


/* ProductFamily */

.new-productfamily #nav-params,
@@ -96,7 +142,10 @@ td.actions{white-space: nowrap;}
text-align: right ;
}

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


/* ORDER */

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


+ 2434
- 1
ShopBundle/Resources/public/js/backend/plugin/select2/select2.min.js
File diff suppressed because it is too large
View File


+ 101
- 0
ShopBundle/Resources/public/js/backend/script/default/init-common.js View File

@@ -0,0 +1,101 @@
jQuery(document).ready(function () {
custom_switch_merchants();
initAdminLtePlugin();
});

function initLcNoty() {
$('.lc-noty').each(function () {
generateNotice($(this).data('type'), $(this).html());
});
}


function custom_switch_merchants() {
$('#switch-merchant select').change(function () {
$('#switch-merchant form').submit();
});
}

function setBootstrapSwitch($checkbox) {

$checkbox.bootstrapSwitch();
$checkbox.bootstrapSwitch('state', true);
$checkbox.on('switchChange.bootstrapSwitch', function (e, state) {
var event = new Event('change');
e.target.dispatchEvent(event);
});
}

function initAdminLtePlugin() {

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

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

$(document).on('keypress', function (event) {

/*if(event.keyCode == '13') {
checkForm();
}*/
});
$('form button[type="submit"]').on('click', function (e) {
log('EVENT CLICK:');
checkForm()
})


if ($('.select2, select.form-control').length) {
$('form .form-widget>select.form-control, .select2').each(function (i, elm) {
setSelect2($(elm))
});

$('form .form-inline>select.form-control').each(function (i, elm) {
setSelect2($(elm))
});
}

$('.autoresize textarea').each(function () {
this.setAttribute('style', 'height:' + (this.scrollHeight) + 'px;overflow-y:hidden;');
}).on('input', function () {
log(this.scrollHeight);
$(this).height('auto');
log('BLOP' + this.scrollHeight);
if (this.scrollHeight < 50) {
$(this).outerHeight(this.scrollHeight - 12);
} else {
$(this).outerHeight(this.scrollHeight);
}
});

}


function setSelect2($select) {
if (typeof $select.data('select2-id') === 'undefined') {

$select.data('init', 'set')
var options = {
width: "100%",
dropdownAutoWidth: false,
allowClear: false,
minimumResultsForSearch: 8
};

if ($select.find('option[value=""]')) {
options.placeholder = $select.find('option[value=""]').html()
}
/*if($select.is(':required') == false) {
options.allowclear = true
}*/
myselect = $select.select2(options);

myselect.on('select2:select', function (e) {
var event = new Event('change');
e.target.dispatchEvent(event);
});

return myselect;
}
}

ShopBundle/Resources/public/js/backend/script/setup-ckfinder.js → ShopBundle/Resources/public/js/backend/script/default/init-edit.js View File

@@ -1,4 +1,30 @@
$(window).on('load', function () {
jQuery(document).ready(function () {

initLcCkEditor();
initCkFinder();
//generateNotice('error', 'Ceci est une notice');

});

function checkForm(){
$('form').addClass('form-sent');
//Panel vues js
if($('form').find('.panel').length){
log('here');

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

function initCkFinder(){

$('.lc-ckfinder-wrap').each(function(){
$widget = $(this);
@@ -36,4 +62,29 @@ $(window).on('load', function () {
if ($('.field-ckfinder_file_chooser').length > 0) {
CKFinder.config({connectorPath: '/ckfinder/connector'});
}
});
}


/* CKEditor */

function initLcCkEditor(){
var elements = $( '.lc-ckeditor' );

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"
});
CKFinder.setupCKEditor(editor);
}
}
}

ShopBundle/Resources/public/js/backend/script/custom.js → ShopBundle/Resources/public/js/backend/script/default/init-list.js View File

@@ -1,115 +1,11 @@
jQuery(document).ready(function () {
custom_switch_merchants();
initLcSortableList();
initLcCkEditor();
initLcSortableProductsList();
initLcSortableList();
initDataTable();

initAdminLtePlugin();

initDataTable();
//generateNotice('error', 'Ceci est une notice');

});

function initLcNoty() {
$('.lc-noty').each(function () {
generateNotice($(this).data('type'), $(this).html());
});
}

function initAdminLtePlugin(){
$('[data-toggle="tooltip"]').tooltip()

if($('.select2, select.form-control').length) {
$('form select.form-control').each(function (i, elm) {

myselect = $(elm).select2({
//theme: 'bootstrap',
//width: "100%",
dropdownAutoWidth: false,
placeholder: "Select an option"
});
myselect.on('select2:select', function (e) {
var event = new Event('change');
e.target.dispatchEvent(event);
});
});
}
if($('.select2-no-search').length) {
$('.select2-no-search').select2({
minimumResultsForSearch: Infinity
});
}



}


function custom_switch_merchants() {
$('#switch-merchant select').change(function () {
$('#switch-merchant form').submit();
});
}

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

function initLcSortableList() {

if ($('.lc-sortable').length > 0) {
$('.lc-sortable tbody').sortable({
placeholder: "ui-state-highlight"
});

$('.lc-sortable tbody').on("sortupdate", function (event, ui) {

prototype = $('#form_entities').data('prototype');

$('.lc-sortable tr.lc-draggable').each(function (index, li) {
// instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);

// Replace '__name__' in the prototype's HTML to
$(li).find('div:last-child').remove();

$(li).append(newForm);
$(li).find('#form_entities_' + index + '_id').val($(li).data('id'));
if ($('.lc-sortable').data('parent-position') !== '') val = $('.lc-sortable').data('parent-position') + '_' + index
else val = index;

log($(li).find('#form_entities_' + index + '_position'));

$(li).find('#form_entities_' + index + '_position').val(val);
});

});
}
}


function initDataTable() {
$(".checkbox-switch input").each(function(){
$(this).bootstrapSwitch('state', $(this).prop('checked'));
});

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

@@ -169,25 +65,21 @@ function initDataTable() {
var select = false;
toggle = $('.table.datatable-simple thead tr:eq(1) th:eq('+i+') select.toggle')
if(toggle.length) {
toggle.select2({
'placeholder': 'Filtrer'//LC_TRAD['search']
});
setSelect2(toggle);
toggle.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex($(this).val());


if(val=="all"){
column.search('').draw();
}else {
var niche = table.column('2');
log(column.cell('4').data());
/*
val = "bootstrap-switch-on";
column.data().each(function(d){
log(d)
});
//filter in column 5, with an regex, no smart filtering, not case sensitive
column.search( val ? '^'+val+'$' : '', true, false ).draw();*/
/*
val = "bootstrap-switch-on";
column.data().each(function(d){
log(d)
});
//filter in column 5, with an regex, no smart filtering, not case sensitive
column.search( val ? '^'+val+'$' : '', true, false ).draw();*/
}
} );

@@ -212,9 +104,7 @@ val = "bootstrap-switch-on";
select.append('<option value="' + $(val).text().trim() + '">' + $(val).text().trim() + '</option>')
});
});
select.select2({
'placeholder': 'Filtrer'//LC_TRAD['search']
});
setSelect2(select);
select.on( 'change', function () {
var val = $(this).val();
if(val=="all"){

+ 36
- 0
ShopBundle/Resources/public/js/backend/script/default/init-sort.js View File

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

function initLcSortableList() {

if ($('.lc-sortable').length > 0) {
$('.lc-sortable tbody').sortable({
placeholder: "ui-state-highlight"
});

$('.lc-sortable tbody').on("sortupdate", function (event, ui) {

prototype = $('#form_entities').data('prototype');

$('.lc-sortable tr.lc-draggable').each(function (index, li) {
// instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);

// Replace '__name__' in the prototype's HTML to
$(li).find('div:last-child').remove();

$(li).append(newForm);
$(li).find('#form_entities_' + index + '_id').val($(li).data('id'));
if ($('.lc-sortable').data('parent-position') !== '') val = $('.lc-sortable').data('parent-position') + '_' + index
else val = index;

log($(li).find('#form_entities_' + index + '_position'));

$(li).find('#form_entities_' + index + '_position').val(val);
});

});
}
}


ShopBundle/Resources/public/js/backend/script/utils.js → ShopBundle/Resources/public/js/backend/script/default/utils.js View File

@@ -39,22 +39,7 @@ function lcTaxPriceUpdate(priceType) {
}
}*/

/* CKEditor */

function initLcCkEditor(){
var elements = $( '.lc-ckeditor' );

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"} );
CKFinder.setupCKEditor(editor);
}
}


/**
* Retourne un prix sans taxe sur base du prix avec tax

ShopBundle/Resources/public/js/backend/script/vuejs-mixins.js → ShopBundle/Resources/public/js/backend/script/default/vuejs-mixins.js View File

@@ -1,6 +1,6 @@
let mixinPriceWithTaxField = {
let mixinPrice = {
data() {
return {
return Object.assign({
price: null,
priceWithTax: null,
buyingPrice: null,
@@ -8,18 +8,29 @@ let mixinPriceWithTaxField = {
differentSupplierTaxRate: null,
multiplyingFactor: null,
priceByRefUnit: null,
taxRate: null,
supplierTaxRate: null,
priceByRefUnitWithTax: null
};
}, window.mixinPriceValues);

},
computed: {
taxRateValue: function () {
return $('#productfamily_taxRate').find('option[value="' + this.taxRate + '"]').data('tax-rate-value');
if(this.taxRate) {
return this.taxRatesList[this.taxRate]['value'];
}else if (this.taxRate == null || this.taxRate == "undefined"){
return this.taxRatesList['default']['value'];
}else{
log('ERREUR : pas de taxRate')
}
},
supplierTaxRateValue: function () {
if ($('#productfamily_supplierTaxRate').find('option[value="' + this.supplierTaxRate + '"]').data('tax-rate-value') == 'inherited') {
if(this.supplierTaxRate) {
return this.taxRatesList[this.supplierTaxRate]['value'];
}else if (this.supplierTaxRate == null || this.supplierTaxRate == "undefined"){
return this.taxRateValue;
} else {
return $('#productfamily_supplierTaxRate').find('option[value="' + this.supplierTaxRate + '"]').data('tax-rate-value');
}else{
log('ERREUR : pas de supplier taxRate')
}
},

@@ -39,14 +50,17 @@ let mixinPriceWithTaxField = {
this.buyingPriceUpdate('buyingPriceWithTax');
},
changePrice: function () {

this.priceUpdate('price');
this.setMultiplyingFactor();
},
changePriceWithTax: function () {

this.priceUpdate('priceWithTax');
this.setMultiplyingFactor();
},
priceUpdate: function (priceType) {

if (priceType == 'priceWithTax' && this.price) {
this.price = parseFloat(this.price.replace(',', '.')).toFixed(3);
this.priceWithTax = getPriceWithTax(this.price, this.taxRateValue);
@@ -60,7 +74,9 @@ let mixinPriceWithTaxField = {
this.priceByRefUnitUpdate();
},
buyingPriceUpdate: function (priceType) {

if (priceType == 'buyingPriceWithTax' && this.buyingPrice) {

this.buyingPrice = parseFloat(this.buyingPrice.replace(',', '.')).toFixed(3);
this.buyingPriceWithTax = getPriceWithTax(this.buyingPrice, this.supplierTaxRateValue);
} else if (this.buyingPriceWithTax) {
@@ -76,7 +92,8 @@ let mixinPriceWithTaxField = {
this.priceUpdate('price');
},
setMultiplyingFactor: function () {
if (this.priceWithTax || this.buyingPrice) {
log('SETFACTOR')
if (this.priceWithTax && this.buyingPrice) {
this.multiplyingFactor = parseFloat(this.priceWithTaxValue / this.buyingPriceValue).toFixed(3);
}
},
@@ -101,19 +118,29 @@ let mixinUnit = {
}, window.mixinUnitValues);
},
computed: {
unitWording: function () {
if (this.unit) {
return this.unitsList[this.unit]['wording'];
} else if (this.unitValue) {
return this.unitsList[this.unitValue]['wording'];
} else {
return '';
}
},
unitCoefficient: function () {
if (this.unit) {
unitCoefficient = $('#productfamily_unit').find('option[value="' + this.unit + '"]').data('coefficient');

return unitCoefficient;
return this.unitsList[this.unit]['coefficient'];
} else if (this.unitValue) {
return this.unitsList[this.unitValue]['coefficient'];
} else {
return 0;
}
},
unitReference: function () {
if (this.unit) {
unitRef = $('#productfamily_unit').find('option[value="' + this.unit + '"]').data('unit-reference');
return unitRef;
return this.unitsList[this.unitsList[this.unit]['unitReference']]['wording'];
} else if (this.unitValue) {
return this.unitsList[this.unitsList[this.unitValue]['unitReference']]['wording'];
} else {
return '';
}
@@ -139,7 +166,6 @@ let mixinTemplate = {
template: {
immediate: true, // makes the watcher fire on first render, too.
handler() {
log(this.template);
if (this.template) {
var res = Vue.compile(this.template);


+ 1
- 9
ShopBundle/Resources/public/js/backend/script/order/vuejs-order.js View File

@@ -40,7 +40,7 @@ Vue.component('order-product-form', {
var select = $(this.$el).find('select.form-control');

var monSelect = $(this.$el).find('select.form-control').select2({
theme: 'bootstrap',
//theme: 'bootstrap',
debug: true,
placeholder: "Select an option"
});
@@ -225,12 +225,4 @@ appOrder = new Vue({
}
});

$(window).on('load',function(){

for(i=0; i<window.formProductTemplate.length; i++) {
appProductFamily.formProductArray.push(formProductTemplate[i]);
appProductFamily.indexFormProduct++;
}


});

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

@@ -0,0 +1,23 @@
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);
});
}
}

+ 71
- 58
ShopBundle/Resources/public/js/backend/script/productfamily/vuejs-product-family.js View File

@@ -3,32 +3,29 @@ var staticRenderFns = [];


Vue.component('product-unit-price', {
mixins: [mixinUnit, mixinPriceWithTaxField, mixinTemplate],
mixins: [mixinUnit, mixinPrice, mixinTemplate],
props: ['template', 'keyForm'],
data() {
return Object.assign({
taxRate: null,
supplierTaxRate: null,
}, window.productUnitPriceValues);
return Object.assign({}, window.productUnitPriceValues);

},
computed:{
buyingPriceValue:function() {
computed: {
buyingPriceValue: function () {
return this.buyingPrice;
},
buyingPriceWithTaxValue:function() {
buyingPriceWithTaxValue: function () {
return this.buyingPriceWithTax;
},
priceWithTaxValue:function(){
priceWithTaxValue: function () {
return this.priceWithTax;
},
priceValue:function(){
priceValue: function () {
return this.price;
},
quantityValue:function(){
quantityValue: function () {
return this.quantity;
},
unitValue:function(){
unitValue: function () {
return this.unit;
}
},
@@ -40,6 +37,7 @@ Vue.component('product-unit-price', {
watch: {
taxRate: function () {
this.changePriceWithTax();
this.changeBuyingPriceWithTax();
},
supplierTaxRate: function () {
this.changeBuyingPriceWithTax();
@@ -54,42 +52,44 @@ Vue.component('product-unit-price', {
});

Vue.component('product-form', {
mixins: [mixinUnit, mixinPriceWithTaxField, mixinTemplate],
mixins: [mixinUnit, mixinPrice, mixinTemplate],
props: ['template', 'keyForm', 'productFamily'],
computed:{
taxRate:function () {
computed: {
taxRate: function () {
return this.productFamily.taxRate;
},
supplierTaxRate:function () {
supplierTaxRate: function () {
return this.productFamily.supplierTaxRate;
},
buyingPriceValue:function() {
buyingPriceValue: function () {
if (this.buyingPrice) return this.buyingPrice;
else return this.productFamily.buyingPrice;
},
buyingPriceWithTaxValue:function() {
buyingPriceWithTaxValue: function () {
if (this.buyingPriceWithTax) return this.buyingPriceWithTax;
else return this.productFamily.buyingPriceWithTax;
},
priceWithTaxValue:function(){
if(this.priceWithTax) return this.priceWithTax;
priceWithTaxValue: function () {
if (this.priceWithTax) return this.priceWithTax;
else return this.productFamily.priceWithTax;
},
priceValue:function(){
if(this.price) return this.price;
priceValue: function () {
if (this.price) return this.price;
else return this.productFamily.price;
},
quantityValue:function(){
if(this.quantity) return this.quantity;
quantityValue: function () {
if (this.quantity) return this.quantity;
else return this.productFamily.quantity;
},
unitValue:function(){
if(this.unit) return this.unit;
unitValue: function () {
if (this.unit) return this.unit;
else return this.productFamily.unit;
},
expirationDateFormated:function () {
if(this.expirationDate) return getDateFormatted(this.expirationDate, '-')
else return getDateFormatted(this.productFamily.expirationDate, '-')
propertyExpirationDateFormated: function () {
log(this.propertyExpirationDate)
log(this.productFamily.propertyExpirationDate)
if (this.propertyExpirationDate) return getDateFormatted(this.propertyExpirationDate, '-')
else return getDateFormatted(this.productFamily.propertyExpirationDate, '-')
}
},
data() {
@@ -103,7 +103,7 @@ Vue.component('product-form', {
multiplyingFactor: null,
availableQuantityDefault: null,
availableQuantity: null,
expirationDate: null,
propertyExpirationDate: null,

titleInherited: false,
priceInherited: false,
@@ -115,12 +115,22 @@ Vue.component('product-form', {
buyingPriceWithTaxInherited: false,
expirationDateInherited: false,
availableQuantityInherited: false,
availableQuantityDefaultInherited: false
availableQuantityDefaultInherited: false,
propertyExpirationDateInherited: false

}, window.productForm[this.keyForm])
},
mounted: function () {
//INIT VAR
updateSortableProducts();


$(this.$el).find('select').each(function (i, select) {
log($(select).parents('td'));
setSelect2($(select));
});


//METHOD
this.updateProductForm();
this.updateProductView();
@@ -130,30 +140,13 @@ Vue.component('product-form', {
this.changePriceWithTax();
this.changeBuyingPriceWithTax();
//EDIT UNIT
/* $('#productfamily_products_' + this.keyForm + '_unit').find('option').hide();

switch (this.productFamily.unit) {
case 'kg' :
case 'g' :
$('#productfamily_products_' + this.keyForm + '_unit').find('option[value="g"]').show();
$('#productfamily_products_' + this.keyForm + '_unit').find('option[value="kg"]').show();
break;
case 'ml':
case 'L' :
$('#productfamily_products_' + this.keyForm + '_unit').find('option[value="ml"]').show();
$('#productfamily_products_' + this.keyForm + '_unit').find('option[value="L"]').show();
break;
case 'piece':
$('#productfamily_products_' + this.keyForm + '_unit').find('option[value="piece"]').show();
break;
}*/
},

updateProductView: function () {
log(this.unitValue);
if(this.unitValue == 'piece'){

if (this.unitValue == 'piece') {
$('.priceByRefUnit').hide();
}else{
} else {
$('.priceByRefUnit').show();
}
if (this.productFamily.behaviorCountStock == 'by-product-family' || this.productFamily.behaviorCountStock == 'by-quantity') {
@@ -165,12 +158,10 @@ Vue.component('product-form', {
},
saveProductForm: function () {
this.updateProductView();

$('#form-product-modal-' + this.keyForm).modal('hide');

},
deleteProductForm: function () {
if(confirm('Êtes-vous sur de cette action ?')) {
if (confirm('Êtes-vous sur de cette action ?')) {
this.$parent.formProductArray.splice(this.keyForm, 1);
}
},
@@ -212,7 +203,8 @@ appProductFamily = new Vue({
'supplierTaxRate': this.$refs.productUnitPrice.supplierTaxRate,
'multiplyingFactor': this.$refs.productUnitPrice.multiplyingFactor,
'taxRateValue': this.$refs.productUnitPrice.taxRateValue,
'expirationDate': this.expirationDate
'propertyExpirationDate': this.propertyExpirationDate,
'behaviorExpirationDate': this.behaviorExpirationDate
};
},
unitReference: function () {
@@ -229,8 +221,15 @@ appProductFamily = new Vue({
activeProducts: false,
isNovelty: null,
isOrganic: null,
expirationDate:null,
propertyExpirationDate: null,
behaviorCountStock: null,

typeExpirationDate: null,
behaviorExpirationDate: null,
propertyAllergens: null,
propertyOrganicLabelActive: false,
propertyNoveltyExpirationDateActive: false,

formProductArray: [],
currentSection: 'general',
sectionsArray: [
@@ -240,7 +239,7 @@ appProductFamily = new Vue({
},
{
name: 'price',
nameDisplay: 'Prix / stock'
nameDisplay: 'Prix '
},
{
name: 'products',
@@ -263,13 +262,18 @@ appProductFamily = new Vue({
}, window.appProductFamilyValues);
},
mounted: function () {

$(".vuejs-checkbox-switch input").each(function () {
setBootstrapSwitch($(this));
});
},
methods: {

changeSection: function (section) {
this.updateChild();
this.currentSection = section.name;
$(".vuejs-checkbox-switch input").each(function () {
setBootstrapSwitch($(this));
});
},
addProductForm: function () {
var $collectionHolder = $('table.products-collection-table');
@@ -278,6 +282,7 @@ appProductFamily = new Vue({
newForm = newForm.replace(/__name__/g, this.indexFormProduct);
this.formProductArray.push(newForm);
this.indexFormProduct++;

//updateSortableProducts();
},

@@ -301,3 +306,11 @@ appProductFamily = new Vue({
},
}
});


$(window).on('load', function () {
for (i = 0; i < window.formProductTemplate.length; i++) {
appProductFamily.formProductArray.push(formProductTemplate[i]);
appProductFamily.indexFormProduct++;
}
});

+ 49
- 0
ShopBundle/Resources/translations/lcshop.fr.yaml View File

@@ -21,10 +21,17 @@ group:
categories: Catégories
unit: Unité & quantité
tax: TVA
storage: Ordganisation dépot
stock: Stock
property: Caractéristiques
propertyMain: Caractéristiques principales
propertySecondary: Caractéristiques secondaires
note: Note interne
None: Aucune valeur
label.form.empty_value: Choisissez une option
field:
default:
placeholder: Choisissez une option
id: Id
status: En ligne
supplier: Producteur
@@ -57,7 +64,32 @@ field:
cities: Villes
orderPriceMin: Montant minimum de commande
deliveryPrice: Montant de la livraison
typeExpirationDate: Type de date d'expiration
dlc: DLC
ddm: DDM
dluo: DLUO
propertyDLC: DLC
propertyDDM: DDM
propertyDLUO: DLUO
propertyAllergens: Allergènes
propertyComposition: Compositon (ingrédients)
propertyFragrances: Parfums
propertyActive: Active
property: Caractéristiques
propertyValue: Valeurs
propertyNoveltyExpirationDate: Nouveauté
propertyOrganicLabel: Label
depositoryZone: Zone du dépot
storageOrder: Ordre de rangement
note: Note interne
warningMessageType: Type de message d'avertissement
warningMessageTypeOptions:
alert: Alerte
info: Information
warningMessage: Contenu du message d'avertissement

ProductFamily:
activeProducts: Activer les déclinaisons
productsType: Type de déclinaisons
productsTypeHelp: 'Volume / Pods / Varieté / Parfum ...'
buyingPrice: Prix d'achat
@@ -67,6 +99,23 @@ field:
availableQuantityDefault: Quantité disponible par défaut
quantity: Quantité
behaviorCountStock: Gestion du stock
differentSupplierTaxRate: TVA différente pour le producteur
supplierTaxRate: TVA du producteur
propertyNoveltyExpirationDateActive: Marquer le produit comme "nouveauté" jusqu'au
propertyOrganicLabelActive: Marquer le produit comme "labellisé"
propertyLargeVolume: Marquer le produit comme "gros volume"
behaviorCountStockOptions:
byQuantity: Gérer le stock par quantité
byProductFamily: Gérer le stock par produit (à l'unité)
byProduct: Gérer le stock par déclainaison
organicLabelOptions:
bio: Agriculture biologique
hVE: Haute valeur environnementale
natureProgres: Nature & progrès
behaviorExpirationDate: Gèrer
behaviorExpirationDateOptions:
productFamily: Par produit
product: Par déclinaisons
taxRate: TVA
unit: Unité
action:

+ 3
- 2
ShopBundle/Resources/views/backend/default/block/macros.html.twig View File

@@ -1,4 +1,4 @@
{% macro startCard(col, zone = "default", card ='primary' ) %}
{% macro startCard(col, zone = "default", card ='primary', fullWidth = false ) %}
{% if col > 0 %}<div class="col-{{ col }}">{% endif %}
<div class="card card-{{ card }}">
<div class="card-header">
@@ -7,7 +7,8 @@
{{ label|trans({}, 'lcshop')|raw }}
</h3>
</div>
<div class="card-body row">
<div class="card-body {{ fullWidth == true ? 'p-0' : 'row' }}">

{% endmacro %}
v
{% macro endCard(noCol = false) %}

+ 2
- 0
ShopBundle/Resources/views/backend/default/block/script-vuejs.html.twig View File

@@ -0,0 +1,2 @@
<script src="{{ asset('bundles/lcshop/js/backend/plugin/vue.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/script/default/vuejs-mixins.js') }}"></script>

+ 9
- 2
ShopBundle/Resources/views/backend/default/edit.html.twig View File

@@ -42,10 +42,17 @@
<link rel="stylesheet" href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/jquery-ui/jquery-ui.min.css') }}">
{% endblock %}

{% block body_javascript %}
{{ parent() }}

{% block plugin_javascript %}
{{ parent() }}
<script src="{{ asset('bundles/lcshop/js/backend/plugin/jquery-ui/jquery-ui.min.js') }}"></script>
<script src="{{ asset('bundles/cksourceckfinder/ckfinder/ckfinder.js') }}"></script>
{% endblock %}

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



{#<script type="text/javascript">

+ 13
- 15
ShopBundle/Resources/views/backend/default/layout.html.twig View File

@@ -15,12 +15,12 @@
<link rel="stylesheet"
href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/fontawesome-free/css/all.min.css') }}">
<!-- Theme style -->
<link rel="stylesheet"
href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/datatables/dataTables.bootstrap4.min.css') }}">
<link rel="stylesheet"
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/bootstrap/bootstrap-switch.min.css') }}">

<!-- Theme style -->
<link rel="stylesheet" href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/toastr/toastr.min.css') }}">
<link rel="stylesheet" href="{{ asset('bundles/lcshop/css/backend/adminlte/adminlte.min.css') }}">
@@ -31,9 +31,9 @@
{% endblock %}

{% block head_custom_stylesheets %}
{% for css_asset in easyadmin_config('design.assets.css') %}
<link rel="stylesheet" href="{{ asset(css_asset) }}">
{% endfor %}
<link rel="stylesheet" href="{{ asset('bundles/lcshop/css/backend/custom.css') }}">
{% endblock head_custom_stylesheets %}

{#
@@ -105,7 +105,7 @@
<label for="switch-merchant"><i
class="fa fa-store"></i> {{ 'action.switchMerchant'|trans() }} :
</label>
<select id="switch-merchant" class="select2-no-search" name="id_merchant">
<select id="switch-merchant" class="select2" name="id_merchant">
{% for merchant in merchants %}
<option value="{{ merchant.id }}"
{% if current_merchant and current_merchant.id == merchant.id %}selected="selected"{% endif %}>
@@ -210,24 +210,22 @@
const DOMAIN = "{{ app.request.getSchemeAndHttpHost() }}";
</script>

{% block body_javascript %}
{% block plugin_javascript %}
<!-- jQuery -->
<script src="{{ asset('bundles/lcshop/js/backend/plugin/jquery/jquery.min.js') }}"></script>
<!-- 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/bootstrap/bootstrap-switch.min.js') }}"></script>
<!-- AdminLTE App -->
<script src="{{ asset('bundles/lcshop/js/backend/plugin/adminlte.min.js') }}"></script>
<script src="{{ asset('bundles/lcshop/js/backend/script/vuejs-mixins.js') }}"></script>

{% endblock body_javascript %}
<script src="{{ asset('bundles/lcshop/js/backend/script/default/utils.js') }}"></script>
{% endblock plugin_javascript %}

{% block body_custom_javascript %}
{% for js_asset in easyadmin_config('design.assets.js') %}
<script src="{{ asset(js_asset) }}"></script>
{% endfor %}
{% endblock body_custom_javascript %}
{% block script_javascript %}
<script src="{{ asset('bundles/lcshop/js/backend/script/default/init-common.js') }}"></script>
{% endblock script_javascript %}


</body>

+ 8
- 3
ShopBundle/Resources/views/backend/default/list.html.twig View File

@@ -239,17 +239,22 @@
{% endblock %}#}
{% block head_stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/bootstrap/bootstrap-switch.min.css') }}">
<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 body_javascript %}
{% 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>
<script src="{{ asset('bundles/lcshop/js/backend/plugin/bootstrap/bootstrap-switch.min.js') }}"></script>
{% endblock %}

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

+ 9
- 3
ShopBundle/Resources/views/backend/default/new.html.twig View File

@@ -29,12 +29,18 @@
<link rel="stylesheet" href="{{ asset('bundles/lcshop/css/backend/adminlte/plugins/jquery-ui/jquery-ui.min.css') }}">
{% endblock %}

{% block body_javascript %}
{{ parent() }}

{% block plugin_javascript %}
{{ parent() }}
<script src="{{ asset('bundles/lcshop/js/backend/plugin/jquery-ui/jquery-ui.min.js') }}"></script>
<script src="{{ asset('bundles/cksourceckfinder/ckfinder/ckfinder.js') }}"></script>
{% endblock %}

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

{#
{#
<script type="text/javascript">
$(function() {
$('.new-form').areYouSure({ 'message': '{{ 'form.are_you_sure'|trans({}, 'EasyAdminBundle')|e('js') }}' });

+ 56
- 6
ShopBundle/Resources/views/backend/form/custom_bootstrap_4.html.twig View File

@@ -13,7 +13,13 @@

{% endblock form_widget %}

{%- block choice_widget_collapsed -%}
{% if placeholder is empty %}{% set placeholder = 'field.default.placeholder' %}{% endif %}
{{ parent() }}
{% endblock %}

{% block form_row -%}

{% set _field_type = easyadmin.field.fieldType|default('default') %}
<div class="form-group {% if (not compound or force_error|default(false)) and not valid %}has-error{% endif %} field-{{ block_prefixes|slice(-2)|first }}">
{{- form_label(form) -}}
@@ -48,9 +54,8 @@
</div>
{% endif %}#}

{% set labelHelp = 'form.field.'~easyadmin['entity']['name']~'.'~name~'Help' %}
{% set labelHelp = 'field.'~easyadmin['entity']['name']~'.'~name~'Help' %}
{% if labelHelp|trans({}, 'lcshop') == labelHelp %}{% set labelHelp = 'form.field.default.'~name~'Help' %}{% endif %}

{% if labelHelp|trans({}, 'lcshop') != labelHelp %}
<small class="form-text text-muted">{{ labelHelp|trans({}, 'lcshop')|raw }}</small>
{% endif %}
@@ -63,6 +68,7 @@


{% block easyadmin_widget_groups %}

{% import '@LcShop/backend/default/block/macros.html.twig' as macros %}
{% for group_name, group_config in easyadmin_form_groups|filter(group_config => not group_config.form_tab or group_config.form_tab == tab_name) %}
{{ macros.startCard(group_config.columns|default('12'), group_config.label, 'primary') }}
@@ -98,17 +104,15 @@
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif -%}

{# {%- if label_format is not empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{{ name|lc_trad(easyadmin['entity']['name'], 'form') }}
{% set label = 'form.field.'~easyadmin['entity']['name']~'.'~name %}
{% if label|trans({}, 'lcshop') == label %}{% set label = 'form.field.default.'~name %}{% endif %}
{%- endif -%}#}

{%- endif -%}
<{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ name|lc_trad(easyadmin['entity']['name'], 'field') }}</{{ element|default('label') }}>

{%- endif -%}
@@ -124,3 +128,49 @@
</div>
</div>
{% endblock easyadmin_rest %}


{% block checkbox_radio_label -%}
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#}
{%- if widget is defined -%}
{% set is_parent_custom = parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class or 'switch-custom' in parent_label_class) %}
{% set is_custom = label_attr.class is defined and ('checkbox-custom' in label_attr.class or 'radio-custom' in label_attr.class or 'switch-custom' in label_attr.class) %}
{%- if is_parent_custom or is_custom -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-control-label')|trim}) -%}
{%- else %}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-check-label')|trim}) -%}
{%- endif %}
{%- if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif -%}
{%- if required -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) -%}
{%- endif -%}
{%- if parent_label_class is defined -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%}
{%- endif -%}
{%- if label is not same as(false) and label is empty -%}
{%- if label_format is not empty -%}
{%- set label = label_format|replace({
'%name%': name,
'%id%': id,
}) -%}
{%- else -%}

{%- set label = name|humanize -%}
{%- endif -%}
{%- endif -%}

<label{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}>
{{ widget|raw }}
<span class="checkmark"></span>

{# {% if translation_domain == 'lcshop' %}
{{ name|lc_trad(easyadmin['entity']['name'], 'field') }}
{% else %}#}
{{- label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans(label_translation_parameters, translation_domain)) -}}
{#{% endif %}#}
{{- form_errors(form) -}}
</label>
{%- endif -%}
{%- endblock checkbox_radio_label %}

+ 21
- 2
ShopBundle/Resources/views/backend/order/edit.html.twig View File

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

{% block entity_form %}
{% include '@LcShop/backend/order/form.html.twig' %}


{% if formView is defined and formView == 'default'%}
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %}
{{ macros.startCard(8, 'OrderShop.selectUser') }}
<div class="col-12">
{{ form(form) }}
</div>
{{ macros.endCard() }}
{% else %}
{% include '@LcShop/backend/order/form.html.twig' %}
{% endif %}


{% endblock entity_form %}

{% block body_javascript %}
{{ parent() }}
{% include '@LcShop/backend/default/block/script-vuejs.html.twig' %}
<script src="{{ asset('bundles/lcshop/js/backend/script/order/vuejs-order.js') }}"></script>
{% endblock %}

+ 16
- 8
ShopBundle/Resources/views/backend/order/form.html.twig View File

@@ -2,14 +2,22 @@

<div class="lc-vue-js-container" id="lc-order-edit">

<div id="nav-params">
<button type="button" v-for="section in sectionsArray"
v-if="(section.name == 'delivery' && deliveryType == 'at-home' && deliveryAddress>0) || (section.name != 'delivery')"
:class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')"
@click="changeSection(section)">
${ section.nameDisplay }
<span class="glyphicon glyphicon-triangle-bottom"></span>
</button>
<div id="lc-product-family-edit">
<div class="card card-light">
<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"
v-if="(section.name == 'delivery' && deliveryType == 'at-home' && deliveryAddress>0) || (section.name != 'delivery')"
:class="'btn '+((currentSection == section.name) ? 'btn btn-primary' : 'btn')"
@click="changeSection(section)">
${ section.nameDisplay }
<span class="glyphicon glyphicon-triangle-bottom"></span>
</button>
</li>
</ul>
</div>
</div>
</div>
<div class="form">


+ 0
- 10
ShopBundle/Resources/views/backend/order/new.html.twig View File

@@ -1,10 +0,0 @@
{% extends '@LcShop/backend/default/new.html.twig' %}

{% block entity_form %}

{% if formView is defined and formView == 'default'%}
{{ form(form) }}
{% else %}
{% include '@LcShop/backend/order/form.html.twig' %}
{% endif %}
{% endblock entity_form %}

+ 88
- 76
ShopBundle/Resources/views/backend/order/panel_orderproducts.html.twig View File

@@ -34,90 +34,102 @@


{% import _self as formMacros %}
<table id="order-products-list" class="table datagrid"
data-prototype="{{ formMacros.printOrderProductRow(form.orderProducts.vars.prototype)|e('html_attr') }}">
<thead>
<tr>
<th colspan="2">
<span>Produit</span>
</th>
<th>
<span>Prix HT à l'unité</span>
</th>
<th>
<span>Prix TTC à l'unité</span>
</th>
<th>
<span>Quantité</span>
</th>
<th>
<span>Total</span>
</th>
<th>
<span>Action</span>
</th>
</tr>
</thead>
<tbody>
<template v-for="(formProduct, key) in formOrderProductArray">

<order-product-form ref="orderProductForm" :template="formProduct" :key-form="key"></order-product-form>
</template>
<tr>
<td colspan="7">
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %}

<button type="button" class="add_tag_link btn-add-product btn btn-default" @click="addOrderProductForm"><span
class="fa fa-plus"></span> Ajouter un produit
</button>
</td>
</tr>
<tr>
<td colspan="4"></td>
<td colspan="3">
<table class="sub-table table-order-summary">
<tr>
<th>Total without Tax</th>
<td>${totalWithoutTax}€</td>
<td ></td>
</tr>
<tr>
<th>Total</th>
<td>${totalWithTax}€</td>
<td ></td>
</tr>
</table>
</td>
<div class="row">
{{ macros.startCard(12, 'OrderShop.cart') }}
<div class="col-12">
<table id="order-products-list" class="table table-striped"
data-prototype="{{ formMacros.printOrderProductRow(form.orderProducts.vars.prototype)|e('html_attr') }}">
<thead>
<tr>
<th colspan="2">
<span>Produit</span>
</th>
<th>
<span>Prix HT à l'unité</span>
</th>
<th>
<span>Prix TTC à l'unité</span>
</th>
<th>
<span>Quantité</span>
</th>
<th>
<span>Total</span>
</th>
<th>
<span>Action</span>
</th>
</tr>
</thead>
<tbody>
<template v-for="(formProduct, key) in formOrderProductArray">

</tr>
</tbody>
</table>
<order-product-form ref="orderProductForm" :template="formProduct" :key-form="key"></order-product-form>
</template>
</tbody>
</table>

<button type="button" class="add_tag_link btn-add-product btn btn-default float-right" @click="addOrderProductForm">
<span class="fa fa-plus"></span> Ajouter un produit
</button>

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

<div class="row">
<div class="col-6"></div>
<div class="col-6">
<div class="table-responsive">
<table class="table">
<tbody>
<tr>
<td>Total without Tax</td>
<td>${totalWithoutTax}€</td>
</tr>
<tr>
<td>Total Tax</td>
<td>${totalWithTax- totalWithoutTax}€</td>
</tr>
<tr>
<td>Total</td>
<td>${totalWithTax}€</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

<div class="clearfix"></div>
<script>
window.orderProductForm = new Array();
</script>
<div class="clearfix"></div>
<script>
window.orderProductForm = new Array();
</script>

{% for keyForm, orderProduct in form.orderProducts %}
{% for keyForm, orderProduct in form.orderProducts %}

<script>
window.orderProductForm[{{ keyForm }}] = {
{% if orderProduct.vars.value.title %}title: "{{ orderProduct.vars.value.title }}",{% endif %}
{% if orderProduct.vars.value.quantity %}quantity: "{{ orderProduct.vars.value.quantity }}",{% endif %}
{% if orderProduct.vars.value.unit %}unit: "{{ orderProduct.vars.value.unit }}",{% endif %}
{#{% if orderProduct.vars.value.buyingPrice %}buyingPrice: "{{ orderProduct.vars.value.buyingPrice }}",{% endif %}#}
{% if orderProduct.vars.value.price %}price: parseFloat({{ orderProduct.vars.value.price }}).toFixed(3),{% endif %}
{% if orderProduct.vars.value.product %}product: {{ orderProduct.vars.value.product.id }}{% endif %}
};
jQuery(window).on('load', function () {
var orderProductForm = '{{ formMacros.printOrderProductRow(orderProduct)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}';
<script>
window.orderProductForm[{{ keyForm }}] = {
{% if orderProduct.vars.value.title %}title: "{{ orderProduct.vars.value.title }}",{% endif %}
{% if orderProduct.vars.value.quantity %}quantity: "{{ orderProduct.vars.value.quantity }}",{% endif %}
{% if orderProduct.vars.value.unit %}unit: "{{ orderProduct.vars.value.unit }}",{% endif %}
{#{% if orderProduct.vars.value.buyingPrice %}buyingPrice: "{{ orderProduct.vars.value.buyingPrice }}",{% endif %}#}
{% if orderProduct.vars.value.price %}price: parseFloat({{ orderProduct.vars.value.price }}).toFixed(3),{% endif %}
{% if orderProduct.vars.value.product %}product: {{ orderProduct.vars.value.product.id }}{% endif %}
};
jQuery(window).on('load', function () {
var orderProductForm = '{{ formMacros.printOrderProductRow(orderProduct)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}';

appOrder.formOrderProductArray.push(orderProductForm);
appOrder.indexOrderProductForm++;
});
</script>
appOrder.formOrderProductArray.push(orderProductForm);
appOrder.indexOrderProductForm++;
});
</script>

{% endfor %}
{% endfor %}

{% do form.orderProducts.setRendered %}
{% do form.orderProducts.setRendered %}

</div>
{{ macros.endCard() }}
</div>

+ 0
- 219
ShopBundle/Resources/views/backend/productfamily/2panel_products.html.twig View File

@@ -1,219 +0,0 @@
{% macro printProductRow(product) %}

<td><i class="fa fa-fw fa-sort"></i></td>
<td class="title"></td>
<td class="quantity"></td>
<td class="unit"></td>
<td class="buyingPrice"></td>
<td class="price"></td>
<td class="coefficiant"></td>
<td class="stock"></td>
<td class="stock"></td>
<td>

<td class="TOBEREPLACE">
<div v-on:click="TOBEREPLACEInherited = true" v-show="TOBEREPLACEInherited == false">
{% verbatim %}{{ TOBEREPLACE ? TOBEREPLACE : productFamily.TOBEREPLACE }}{% endverbatim %}
</div>
<div v-show="TOBEREPLACEInherited == true">
{{ form_widget(product.TOBEREPLACE, {'attr' : {'v-model' : 'TOBEREPLACE', 'v-on:focusout': 'TOBEREPLACEInherited = false'}}) }}
</div>
</td>

{# <button type="button" class="btn-edit-product btn btn-default"
@click="editProductForm(key)"><i class="fa fa-pen"></i> Éditer cette déclinaison
</button>
<button type="button" class="btn-remove-product btn btn-default"
@click="deleteProductForm(key)"><i class="fa fa-trash"></i> Supprimer cette
déclinaison
</button>#}
<div :id="'form-product-modal-'+ keyForm" class="product-form modal" tabindex="-1" role="dialog"
data-backdrop="static">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Déclinaison</h5>
</div>
<div class="modal-body">
<div class="form-group row">
{{ form_label(product.title, null, {'label_attr': {'class': 'col-2 col-form-label text-right'}}) }}

<div class="form-widget col-10">
{{ form_widget(product.titleInherited, {'label': 'Utiliser la valeur par défaut : {{ productFamily.title }}','attr' : {'v-model' : 'titleInherited'}}) }}

<div v-show="titleInherited == false">
{{ form_widget(product.title, {'attr' : {'v-model' : 'title'}}) }}
{{ form_help(product.title) }}
</div>

</div>
</div>
<div class="form-group row">
{{ form_label(product.unit, null, {'label_attr': {'class': 'col-2 col-form-label text-right'}}) }}
<div class="form-widget col-10">
{{ form_widget(product.unitInherited, {'label': 'Utiliser la valeur par défaut : {{ productFamily.unit }}','attr' : {'v-model' : 'unitInherited'}}) }}

<div v-show="unitInherited == false">
{{ form_widget(product.unit, {"attr":{'v-model': 'unit', 'class' : 'select-unit'}}) }}
{{ form_help(product.unit) }}
</div>
</div>
</div>
<div class="form-group row field-weight">
{{ form_label(product.quantity, null, {'label_attr': {'class': 'col-2 col-form-label text-right'}}) }}
<div class="form-widget col-10">
{{ form_widget(product.quantityInherited, {'label': 'Utiliser la valeur par défaut : {{ productFamily.quantity }}','attr' : {'v-model' : 'quantityInherited'}}) }}

<div v-show="quantityInherited == false" class="input-group">
{{ form_widget(product.quantity, {'attr' : {'v-model' : 'quantity'}}) }}
<div class="input-group-append">
<span class="input-group-text">g</span>
</div>
</div>
{{ form_help(product.quantity) }}
</div>
</div>
{# <div v-else class="form-group row field-step">
{{ form_label(product.step, null, {'label_attr': {'class': 'col-2 col-form-label text-right'}}) }}
<div class="form-widget col-8">
{{ form_widget(product.stepInherited, {'label': 'Utiliser la valeur par défaut : {{ productFamily.step }}','attr' : {'v-model' : 'stepInherited'}}) }}

<div v-show="stepInherited == false" class="input-group">
{{ form_widget(product.step, {'attr' : {'v-model' : 'step'}}) }}
<div class="input-group-append">
<span class="input-group-text">{% verbatim %}{{ unit ? unit : productFamily.unit }}{% endverbatim %}</span>
</div>
</div>
{{ form_help(product.step) }}
</div>
</div>
#}
<div class="form-group row field-price">
{{ form_label(product.price, null, {'label_attr': {'class': 'col-2 col-form-label text-right'}}) }}
<div class="form-widget col-10">

{{ form_widget(product.priceInherited, {'label': 'Utiliser la valeur par défaut : {{ productFamily.price }}','attr' : {'v-model' : 'priceInherited'}}) }}

<div v-show="priceInherited == false" class="input-group">
{{ form_widget(product.price, {'attr' : {'v-model': 'price', '@change' : 'changePriceWithTax'}}) }}
<div class="input-group-append">
<span class="input-group-text">€ HT / {% verbatim %}{{ unitReference }}{% endverbatim %}</span>
</div>
</div>
</div>
</div>

<div class="form-group row field-price">
<div class="col-2">&nbsp;</div>
<div class="form-widget col-10">
<div v-show="priceInherited == false" class="input-group">
{{ form_widget(product.priceWithTax, {'attr' : {'v-model': 'priceWithTax', '@change' : 'changePrice'}}) }}
<div class="input-group-append">
<span class="input-group-text">€ TTC / {% verbatim %}{{ unitReference }}{% endverbatim %}</span>
</div>
</div>
</div>
</div>

<div v-show="productFamily.behaviorCountStock == 'by-product'"
class="form-group row field-available-quantity">
{{ form_label(product.availableQuantity, null, {'label_attr': {'class': 'col-2 col-form-label text-right'}}) }}
<div class="form-widget">
<div class="input-group">
{{ form_widget(product.availableQuantity, {'attr' : {'v-model': 'availableQuantity'}}) }}
<div class="input-group-append">
<span class="input-group-text">{% verbatim %}{{ unitReference }}{% endverbatim %}</span>
</div>
</div>
{{ form_help(product.availableQuantity) }}
</div>
</div>
</div>
{{ form_widget(product.position, {'attr' : {'class' : 'field-position'}}) }}
<div class="modal-footer">
<button @click="saveProductForm()" type="button" class="btn btn-primary">Fermer
</button>
</div>
</div>
</div>
</div>
</td>
{% endmacro %}
{% import _self as formMacros %}
<table class="table datagrid sortable lc-sortable-products products-collection-table">
<thead>
<tr>
<th>
<span></span>
</th>
<th class="string">
<span>Titre</span>
</th>
<th class="string ">
<span>Quantité</span>
</th>
<th class="quantity">
<span>Unité</span>
</th>
<th class="price">
<span>Prix achat</span>
</th>
<th class="price">
<span>Prix Vente</span>
</th>
<th class="stock">
<span>Coef</span>
</th>
<th class="stock">
<span>Stock</span>
</th>
<th class="stock">
<span>Stock par défaut</span>
</th>
<th class="">
<span>Action</span>
</th>
</tr>
</thead>
<tbody class="products-collection" :data-index="formProductArray.length"
data-prototype="{{ formMacros.printProductRow(form.products.vars.prototype)|e('html_attr') }}">
<tr class="product-item lc-draggable" :id="'product-item-'+key"
v-for="(formProduct, key) in formProductArray">

<product-form ref="productForm" v-bind:product-family="productFamily" :template="formProduct"
:key-form="key"></product-form>

</tr>
</tbody>
</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>
<script>
window.productForm = new Array();
</script>

{% for keyForm,i in sortableProductsField %}
{% set product = form.products[i] %}
<script>
window.productForm[{{ keyForm }}] = {
{% if product.vars.value.title %}title: "{{ product.vars.value.title }}",{% endif %}
{% if product.vars.value.unit %}unit: "{{ product.vars.value.unit }}",{% endif %}

{#{% if product.vars.value.quantity %}step: parseInt({{ product.vars.value.quantity }}),{% endif %}#}

{% if product.vars.value.price %}price: parseFloat({{ product.vars.value.price }}).toFixed(3),{% endif %}
{% if product.vars.value.availableQuantity %}availableQuantity: parseInt({{ product.vars.value.availableQuantity }}){% endif %}
};
jQuery(document).ready(function () {
var formProduct = '{{ formMacros.printProductRow(product)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}';

appProductFamily.formProductArray.push(formProduct);
appProductFamily.indexFormProduct++;
});
</script>

{% endfor %}

{% do form.products.setRendered %}


+ 9
- 1
ShopBundle/Resources/views/backend/productfamily/edit.html.twig View File

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

{% block entity_form %}
{% include '@LcShop/backend/productfamily/form.html.twig' %}
{% endblock entity_form %}

{% block script_javascript %}
{{ 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 %}

+ 38
- 22
ShopBundle/Resources/views/backend/productfamily/form.html.twig View File

@@ -1,5 +1,6 @@
{{ form_start(form, {"attr": {'@change' : 'formUpdated'}}) }}
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %}
{% set formValues = form.vars.value %}

<div id="lc-product-family-edit">
<div class="card card-light">
@@ -13,31 +14,43 @@
${ section.nameDisplay }
<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>

</li>
</ul>
</div>
</div>
<div class="form ">

<script>// rendered by server
<script>


window.mixinUnitValues = {
unitsList: {{ getUnitsList()|json_encode|raw }}
};
window.mixinPriceValues = {
taxRatesList: {{ getTaxRatesList()|json_encode|raw }}
};
window.appProductFamilyValues = {
{% if form.vars.value.title %}title: "{{ form.vars.value.title }}",{% endif %}
{% if formValues.title %}title: "{{ formValues.title }}",{% endif %}
{% if form.behaviorCountStock.vars.value %}behaviorCountStock: "{{ form.behaviorCountStock.vars.value }}",{% endif %}
{% if form.vars.value.availableQuantity %}availableQuantity: "{{ form.vars.value.availableQuantity }}",{% endif %}
{% if form.vars.value.availableQuantityDefault %}availableQuantityDefault: "{{ form.vars.value.availableQuantityDefault }}",{% endif %}
{% if form.vars.value.activeProducts %}activeProducts: "{{ form.vars.value.activeProducts }}"{% endif %}
{% if form.vars.value.isNovelty %}isNovelty: "{{ form.vars.value.isNovelty }}"{% endif %}
{% if form.vars.value.expirationDate %}expirationDate: "{{ form.vars.value.expirationDate }}"{% endif %}
{% if formValues.availableQuantity %}availableQuantity: "{{ formValues.availableQuantity }}",{% endif %}
{% if formValues.availableQuantityDefault %}availableQuantityDefault: "{{ formValues.availableQuantityDefault }}",{% endif %}
{% if formValues.activeProducts %}activeProducts: "{{ formValues.activeProducts }}",{% endif %}
{% if formValues.propertyOrganicLabel %}propertyOrganicLabelActive: true,{% endif %}
{% if formValues.propertyNoveltyExpirationDate %}propertyNoveltyExpirationDateActive: true,{% endif %}
{% if formValues.typeExpirationDate %}typeExpirationDate: "{{ formValues.typeExpirationDate }}",{% endif %}
{% if formValues.behaviorExpirationDate %}behaviorExpirationDate: "{{ formValues.behaviorExpirationDate }}",{% endif %}
{% if formValues.propertyExpirationDate %}propertyExpirationDate: "{{ formValues.propertyExpirationDate }}",{% endif %}
};
window.productUnitPriceValues = {
{% if form.vars.value.unit %}unit: "{{ form.vars.value.unit }}",{% endif %}
{% if form.vars.value.quantity %}quantity: parseFloat({{ form.vars.value.quantity }}),{% endif %}
{% if form.taxRate.vars.value != "" %}taxRate: "{{ form.taxRate.vars.value }}",{% endif %}
{% if form.vars.value.price %}price: parseFloat({{ form.vars.value.price }}).toFixed(3),{% endif %}
{% if form.vars.value.buyingPrice %}buyingPrice: parseFloat({{ form.vars.value.buyingPrice }}).toFixed(3),{% endif %}
{% if form.supplierTaxRate.vars.value != "" %}supplierTaxRate: "{{ form.supplierTaxRate.vars.value }}",{% endif %}
{% if formValues.unit %}unit: parseInt({{ formValues.unit.id }}),{% endif %}
{% if formValues.quantity %}quantity: parseFloat({{ formValues.quantity }}),{% endif %}
{% if formValues.taxRate %}taxRate: parseInt({{ formValues.taxRate.id }}),{% endif %}
{% if formValues.price %}price: parseFloat({{ formValues.price }}).toFixed(3),{% endif %}
{% if formValues.buyingPrice %}buyingPrice: parseFloat({{ formValues.buyingPrice }}).toFixed(3),{% endif %}
{% if formValues.supplierTaxRate %}supplierTaxRate: parseInt({{ formValues.supplierTaxRate.id }}),{% endif %}
{% if form.supplierTaxRate.vars.value != 0 %}differentSupplierTaxRate: true{% endif %}
}
</script>
@@ -51,29 +64,32 @@
{% include '@LcShop/backend/productfamily/panel_price.html.twig' %}

</div>
<div v-show="currentSection == 'property'" class="panel panel-default">
{% include '@LcShop/backend/productfamily/panel_property.html.twig' %}
</div>
<div v-show="currentSection == 'products'" class="panel panel-default">
{% include '@LcShop/backend/productfamily/panel_products.html.twig' %}
</div>

<div v-show="currentSection == 'stock'" class="panel panel-default">
{% include '@LcShop/backend/productfamily/panel_stock.html.twig' %}
</div>

<div v-show="currentSection == 'property'" class="panel panel-default">
{% include '@LcShop/backend/productfamily/panel_property.html.twig' %}
</div>


<div v-show="currentSection == 'note'" class="panel panel-default">
<div class="row">
{{ macros.startCard(12, 'ProductFamily.note', 'light') }}
{{ form_row(form.note) }}
{{ form_row(form.note) }}
{{ macros.endCard() }}
</div>
</div>
<div class="row">
{{ macros.startCard(12, 'ProductFamily.note', 'light') }}
{% if entity.note|striptags !="" %}
<div class="row">
{{ macros.startCard(12, 'ProductFamily.note', 'light') }}
{{ entity.note|raw }}
{{ macros.endCard() }}
</div>
{{ macros.endCard() }}
</div>
{% endif %}

</div>


+ 0
- 5
ShopBundle/Resources/views/backend/productfamily/new.html.twig View File

@@ -1,5 +0,0 @@
{% extends '@LcShop/backend/default/new.html.twig' %}

{% block entity_form %}
{% include '@LcShop/backend/productfamily/form.html.twig' %}
{% endblock entity_form %}

+ 8
- 0
ShopBundle/Resources/views/backend/productfamily/panel_general.html.twig View File

@@ -20,6 +20,14 @@
{{ form_row(form.description) }}
</div>

<div class="col-12">
{{ form_row(form.warningMessageType) }}
</div>

<div class="col-12">
{{ form_row(form.warningMessage) }}
</div>

{{ macros.endCard() }}
{{ macros.startCard(4, 'ProductFamily.products','light') }}
<div class="col-12">

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

@@ -15,7 +15,7 @@
<div class="input-group">
{{ form_widget(form.quantity, {'attr' : {'v-model': 'quantity', '@change': "priceByRefUnitUpdate"}}) }}
<div class="input-group-append">
<span class="input-group-text">${ unit }</span>
<span class="input-group-text">${ unitWording }</span>
</div>
</div>
{{ form_help(form.quantity) }}

+ 82
- 81
ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig View File

@@ -4,7 +4,7 @@

<tr class="lc-draggable">
<td><i class="fa fa-fw fa-sort"></i></td>
<td colspan="3" class="title" v-on:click="titleInherited = true">
<td colspan="2" class="title" v-on:click="titleInherited = true">
<div v-show="titleInherited == false">
<div v-if="title" class="blop">
{% verbatim %}{{ title }}{% endverbatim %}
@@ -35,10 +35,10 @@
<td colspan="2" class="unit" v-on:click="unitInherited = true">
<div v-show="unitInherited == false">
<div v-if="unit" class="blop">
{% verbatim %}{{ unit }}{% endverbatim %}
{% verbatim %}{{ unitWording }}{% endverbatim %}
</div>
<div v-else class="inherited">
{% verbatim %}{{ productFamily.unit }}{% endverbatim %}
{% verbatim %}{{ unitWording }}{% endverbatim %}
</div>
</div>
<div v-show="unitInherited == true">
@@ -133,13 +133,13 @@
</td>


<td class="stock availableQuantity " v-on:click="availableQuantityInherited = true">
<td v-show="productFamily.behaviorCountStock== 'by-product'" class="stock availableQuantity " v-on:click="availableQuantityInherited = true">
<div v-show="availableQuantityInherited == false">
<div v-if="availableQuantity">
{% verbatim %}{{ availableQuantity }} {{ unitReference }}{% endverbatim %}
{% verbatim %}{{ availableQuantity }}{% endverbatim %}
</div>
<div v-else class="inherited">
{% verbatim %}{{ productFamily.availableQuantity }} {{ unitReference }}{% endverbatim %}
{% verbatim %}{{ productFamily.availableQuantity }}{% endverbatim %}
</div>

</div>
@@ -148,7 +148,7 @@
</div>
</td>

<td class="stock availableQuantityDefault" v-on:click="availableQuantityDefaultInherited = true">
<td v-show="productFamily.behaviorCountStock== 'by-product'" class="stock availableQuantityDefault" v-on:click="availableQuantityDefaultInherited = true">
<div v-show="availableQuantityDefaultInherited == false">
<div v-if="availableQuantityDefault">
{% verbatim %}{{ availableQuantityDefault }}{% endverbatim %}
@@ -162,17 +162,17 @@
</div>
</td>

<td colspan="2" class="expirationDate" v-on:click="expirationDateInherited = true">
<div v-show="expirationDateInherited == false">
<div v-if="expirationDate">
{% verbatim %}{{ expirationDateFormated }}{% endverbatim %}
<td v-show="productFamily.behaviorExpirationDate== 'by-product'" colspan="2" v-on:click="propertyExpirationDateInherited = true">
<div v-show="propertyExpirationDateInherited == false">
<div v-if="propertyExpirationDate">
{% verbatim %}{{ propertyExpirationDateFormated }}{% endverbatim %}
</div>
<div v-else class="inherited">
{% verbatim %}{{ expirationDateFormated }}{% endverbatim %}
{% verbatim %}{{ propertyExpirationDateFormated }}{% endverbatim %}
</div>
</div>
<div v-show="expirationDateInherited == true">
{{ form_widget(product.expirationDate, {'attr' : {'v-model' : 'expirationDate', 'v-on:focusout': 'expirationDateInherited = false'}}) }}
<div v-show="propertyExpirationDateInherited == true">
{{ form_widget(product.propertyExpirationDate, {'attr' : {'v-model' : 'propertyExpirationDate', 'v-on:focusout': 'propertyExpirationDateInherited = false'}}) }}
</div>
</td>

@@ -186,77 +186,78 @@
{% endmacro %}

{% import _self as formMacros %}
<div class="row">
{{ macros.startCard(12, 'ProductFamily.products', 'light', true) }}

{{ macros.startCard(12, 'ProductFamily.products', 'light') }}
<div class="col-12">
<table class="table datagrid sortable lc-sortable-products products-collection-table"
:data-index="formProductArray.length"
data-prototype="{{ formMacros.printProductRow(form.products.vars.prototype)|e('html_attr') }}">
<thead>
<tr>
<th>
</th>
<th colspan="3" class="string">
Titre
</th>
<th colspan="1" class="string ">
Quantité
</th>
<th colspan="2" class="quantity">
Unité
</th>
<th colspan="2" class="price">
PA HT
</th>
<th colspan="2" class="price">
PA TTC
</th>
<th colspan="2" class="">
Coef
</th>
<th colspan="2" class="price">
PV HT
</th>
<th colspan="2" class="price">
PV TTC
</th>
<th colspan="2" class="priceByRefUnit">
PV HT / ${ getUnitReference() }
</th>
<th colspan="2" class="priceByRefUnit">
PV TTC / ${ getUnitReference() }
</th>
<table class="table datagrid sortable lc-sortable-products products-collection-table"
:data-index="formProductArray.length"
data-prototype="{{ formMacros.printProductRow(form.products.vars.prototype)|e('html_attr') }}">
<thead>
<tr>
<th>
</th>
<th colspan="2" class="string">
Titre
</th>
<th colspan="1" class="string ">
Quantité
</th>
<th colspan="2" class="quantity">
Unité
</th>
<th colspan="2" class="price">
PA HT
</th>
<th colspan="2" class="price">
PA TTC
</th>
<th colspan="2" class="">
Coef
</th>
<th colspan="2" class="price">
PV HT
</th>
<th colspan="2" class="price">
PV TTC
</th>
<th colspan="2" class="priceByRefUnit">
PV HT / ${ getUnitReference() }
</th>
<th colspan="2" class="priceByRefUnit">
PV TTC / ${ getUnitReference() }
</th>

<th class="stock">
Stock
</th>
<th class="stock">
Stock par défaut
</th>
<th colspan="2" class="">
DLC
</th>
<th class="">
Action
</th>
</tr>
</thead>
<tbody class="products-collection">
<th v-show="behaviorCountStock== 'by-product'">
Stock
</th>
<th v-show="behaviorCountStock== 'by-product'">
Stock par défaut
</th>
<th colspan="2" class="" v-show="behaviorExpirationDate== 'by-product'">
<span style="text-transform: uppercase"> ${typeExpirationDate}</span>
</th>
<th class="">
Action
</th>
</tr>
</thead>
<tbody class="products-collection">

<template v-for="(formProduct, key) in formProductArray">
<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 ref="productForm" v-bind:product-family="productFamily" :template="formProduct"
:key-form="key"></product-form>
</template>

</tbody>
</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>
<div class="clearfix"></div>
</tbody>
</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>
<div class="clearfix"></div>

{{ macros.endCard() }}
{{ macros.endCard() }}
</div>
{% do form.products.setRendered %}

<script>
@@ -274,9 +275,9 @@
{% if product.vars.value.price %}price: parseFloat({{ product.vars.value.price }}).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.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %}
{#{% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %}#}
};
window.formProductTemplate[{{ keyForm }}] = '{{ formMacros.printProductRow(product)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}';
{% endfor %}
</script>
</div>

+ 97
- 27
ShopBundle/Resources/views/backend/productfamily/panel_property.html.twig View File

@@ -2,39 +2,109 @@
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %}

<div class="row">
{{ macros.startCard(7, 'ProductFamily.property', 'light') }}

<div class="col-12">
<div class="row">
<div class="col-5">
{{ form_row(form.isNovelty, {'attr': {'v-model':'isNovelty'}}) }}
</div>
<div class="col-7" v-show="isNovelty==true">
{{ form_row(form.noveltyExpirationDate) }}
</div>
</div>
</div>
{{ macros.startCard(8, 'ProductFamily.propertyMain', 'light', true) }}
<table class="table table-bordered">
<thead>
<tr>
{#<th style="width: 10px">#</th>#}
<th style="width: 40%">{{ 'field.default.property'|trans({}, 'lcshop') }}</th>
<th style="width: 60%">{{ 'field.default.propertyValue'|trans({}, 'lcshop') }}</th>
</tr>
</thead>
<tbody>
<tr>

<td>{{ form_widget(form.propertyNoveltyExpirationDateActive, {"attr" : {'v-model' : 'propertyNoveltyExpirationDateActive'}}) }}</td>
<td>
<div v-show="propertyNoveltyExpirationDateActive == true">
{{ form_widget(form.propertyNoveltyExpirationDate) }}
</div>
</td>
</tr>
<tr>
<td>{{ form_widget(form.propertyOrganicLabelActive, {"attr" : {'v-model' : 'propertyOrganicLabelActive' } }) }}</td>
<td>
<div class="form-widget" v-show="propertyOrganicLabelActive == true">
{{ form_widget(form.propertyOrganicLabel) }}
</div>
</td>
</tr>
<tr>
<td>{{ form_widget(form.propertyLargeVolume) }}</td>
<td></td>
</tr>
</tbody>
</table>
{{ macros.endCard(true) }}

<div class="col-12">
<div class="row">
<div class="col-5">
{{ form_row(form.isOrganic, {'attr': {'v-model':'isOrganic'}}) }}
</div>
<div class="col-7" v-show="isOrganic==true">
{{ form_row(form.organicLabel) }}
</div>
</div>
</div>
<div class="col-12">
{{ macros.startCard(0, 'ProductFamily.propertySecondary', 'light', true) }}

{{ form_row(form.largeVolume) }}
<table class="table table-bordered">
<thead>
<tr>
{#<th style="width: 10px">#</th>#}
<th style="width: 40%">{{ 'field.default.property'|trans({}, 'lcshop') }}</th>
<th style="width: 60%">{{ 'field.default.propertyValue'|trans({}, 'lcshop') }}</th>
</tr>
</thead>
<tbody>
<tr v-show="typeExpirationDate != ''">
<td><label style="text-transform: uppercase">${typeExpirationDate}</label></td>
<td>{{ form_widget(form.propertyExpirationDate, {'attr' : {'v-model' : 'propertyExpirationDate'}}) }}</td>
</tr>

<tr>
{#<td>
{{ form_widget(form.propertyAllergensActive, {"label" : false , "attr" : {'v-model' : 'propertyAllergensActive'}}) }}
</td>#}
<td>{{ form_label(form.propertyAllergens) }}</td>
<td>
<div class="autoresize">
{{ form_widget(form.propertyAllergens, {'attr' : {rows : '1'}}) }}
</div>
</td>
</tr>

<tr>
<td>{{ form_label(form.propertyComposition) }}</td>
<td>
<div class="autoresize">
{{ form_widget(form.propertyComposition, {'attr' : {rows : '1'}}) }}
</div>
</td>
</tr>

<tr>
<td>{{ form_label(form.propertyFragrances) }}</td>
<td>
<div class="autoresize">
{{ form_widget(form.propertyFragrances, {'attr' : {rows : '1'}}) }}
</div>
</td>
</tr>

</tbody>
</table>

</div>
{{ macros.endCard() }}
{{ macros.startCard(5, 'ProductFamily.property', 'light') }}

{{ macros.startCard(4, 'ProductFamily.property', 'light') }}

<div class="col">
{{ form_row(form.expirationDate, {'attr': {'v-model':'expirationDate'}}) }}

{{ form_label(form.typeExpirationDate) }}
{% for field in form.typeExpirationDate %}
{{ form_widget(field, {"attr" : {"v-model" : 'typeExpirationDate'}}) }}
{% endfor %}

{{ form_label(form.behaviorExpirationDate) }}
{% for field in form.behaviorExpirationDate %}
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorExpirationDate'}}) }}
{% endfor %}

</div>

{{ macros.endCard() }}


</div>

+ 11
- 1
ShopBundle/Resources/views/backend/productfamily/panel_stock.html.twig View File

@@ -3,7 +3,7 @@

{% import '@LcShop/backend/default/block/macros.html.twig' as macros %}
<div class="row">
{{ macros.startCard(12, 'ProductFamily.stock', 'light') }}
{{ macros.startCard(8, 'ProductFamily.stock', 'light') }}

<div class="col">
{{ form_label(form.behaviorCountStock) }}
@@ -47,4 +47,14 @@

{{ macros.endCard() }}

{{ macros.startCard(4, 'ProductFamily.storage', 'light') }}
<div class="col">
{{ form_row(form.depositoryZone) }}
{{ form_row(form.storageOrder) }}
</div>


{{ macros.endCard() }}


</div>

+ 4
- 0
ShopBundle/Services/GlobalParam.php View File

@@ -27,4 +27,8 @@ class GlobalParam
return false ;
}
}
public function getCurrentMerchantTaxRate()
{
return $this->getCurrentMerchant()->getTaxRate();
}
}

+ 77
- 90
ShopBundle/Services/Utils.php View File

@@ -4,100 +4,15 @@ namespace Lc\ShopBundle\Services;

use Doctrine\ORM\EntityManagerInterface;
use Lc\ShopBundle\Context\PageInterface;
use Lc\ShopBundle\Context\TaxRateInterface;
use Lc\ShopBundle\Context\UnitInterface;

class Utils
{
protected $em ;
protected $globalParam ;

protected $unitsArray = [
'piece' => [
'unit' => 'piece',
'wording_unit' => 'la pièce',
'wording' => 'pièce(s)',
'wording_short' => 'p.',
'coefficient' => 1,
'ref' => 'piece'
],
'g' => [
'unit' => 'g',
'wording_unit' => 'le g',
'wording' => 'g',
'wording_short' => 'g',
'coefficient' => 1000,
'ref' => 'kg'
],
'kg' => [
'unit' => 'kg',
'wording_unit' => 'le kg',
'wording' => 'kg',
'wording_short' => 'kg',
'coefficient' => 1,
'ref' => 'kg'
],
'mL' => [
'unit' => 'mL',
'wording_unit' => 'le mL',
'wording' => 'mL',
'wording_short' => 'mL',
'coefficient' => 1000,
'ref' => 'L'
],
'cL' => [
'unit' => 'cL',
'wording_unit' => 'le cL',
'wording' => 'cL',
'wording_short' => 'cL',
'coefficient' => 100,
'ref' => 'L'
],
'L' => [
'unit' => 'L',
'wording_unit' => 'le litre',
'wording' => 'L',
'wording_short' => 'L',
'coefficient' => 1,
'ref' => 'L'
],
];

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

public static function getDayByNumber($number, $lang = 'fr')
{
if($lang == 'fr') {
$daysArray = [
1 => 'Lundi',
2 => 'Mardi',
3 => 'Mercredi',
4 => 'Jeudi',
5 => 'Vendredi',
6 => 'Samedi',
7 => 'Dimanche'
] ;
}
else {
$daysArray = [
1 => 'Monday',
2 => 'Tuesday',
3 => 'Wednesday',
4 => 'Thursday',
5 => 'Friday',
6 => 'Saturday',
7 => 'Sunday',
] ;
}

if(isset($daysArray[$number])) {
return $daysArray[$number] ;
}

return '' ;
}

public function getUnitsListFormatedForType()
/*public function getUnitsListFormatedForType()
{
$choices = [] ;
foreach ($this->unitsArray as $unit=>$unitInfo){
@@ -122,6 +37,8 @@ class Utils
return false ;
}



public function getUnitWording($unit, $type = 'wording_short')
{
return $this->getUnitProperty($unit, $type) ;
@@ -135,12 +52,82 @@ class Utils
public function getUnitCoefficient($unit)
{
return $this->getUnitProperty($unit, 'coefficient') ;
}*/


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

public function getUnitsList()
{
$unitsList =array();
$units = $this->em->getRepository(UnitInterface::class)->findAll();
foreach ($units as $unit){
$unitsList[$unit->getId()]['unit'] = $unit->getUnit();
$unitsList[$unit->getId()]['wordingUnit'] = $unit->getWordingUnit();
$unitsList[$unit->getId()]['wording'] = $unit->getWording();
$unitsList[$unit->getId()]['wordingShort'] = $unit->getWordingShort();
$unitsList[$unit->getId()]['coefficient'] = $unit->getCoefficient();
$unitsList[$unit->getId()]['unitReference'] = $unit->getUnitReference()->getId();
}

return $unitsList;
}

public function getTaxRatesList()
{
$taxRatesList =array();
$taxRates = $this->em->getRepository(TaxRateInterface::class)->findAll();
foreach ($taxRates as $taxRate){
$taxRatesList[$taxRate->getId()]['title'] = $taxRate->getTitle();
$taxRatesList[$taxRate->getId()]['value'] = $taxRate->getValue();
}

$taxRatesList['default']['title'] = $this->globalParam->getCurrentMerchantTaxRate()->getTitle();
$taxRatesList['default']['value'] = $this->globalParam->getCurrentMerchantTaxRate()->getValue();
return $taxRatesList;
}

public static function getDayByNumber($number, $lang = 'fr')
{
if($lang == 'fr') {
$daysArray = [
1 => 'Lundi',
2 => 'Mardi',
3 => 'Mercredi',
4 => 'Jeudi',
5 => 'Vendredi',
6 => 'Samedi',
7 => 'Dimanche'
] ;
}
else {
$daysArray = [
1 => 'Monday',
2 => 'Tuesday',
3 => 'Wednesday',
4 => 'Thursday',
5 => 'Friday',
6 => 'Saturday',
7 => 'Sunday',
] ;
}

if(isset($daysArray[$number])) {
return $daysArray[$number] ;
}

return '' ;
}


public function getElementByDevAlias($devAlias, $class = PageInterface::class)
{
$class = $this->em->getClassMetadata($class)->getName();
return $this->em->getRepository($class)->findOneByDevAlias($devAlias) ;
}

}
}

+ 6
- 0
ShopBundle/Twig/BridgeTwigExtension.php View File

@@ -22,6 +22,7 @@ class BridgeTwigExtension extends AbstractExtension
return array(
new TwigFunction('getDayByNumber', [$this, 'getDayByNumber']),
new TwigFunction('getUnitsList', [$this, 'getUnitsList']),
new TwigFunction('getTaxRatesList', [$this, 'getTaxRatesList']),
new TwigFunction('getElementByDevAlias', [$this, 'getElementByDevAlias']),
new TwigFunction('get_form_newsletter', [$this, 'getFormNewsletter']),
);
@@ -43,6 +44,11 @@ class BridgeTwigExtension extends AbstractExtension
return $this->utils->getUnitsList() ;
}

public function getTaxRatesList()
{
return $this->utils->getTaxRatesList() ;
}

public function getElementByDevAlias($devAlias, $class = PageInterface::class)
{
return $this->utils->getElementByDevAlias($devAlias, $class) ;

Loading…
Cancel
Save