@@ -0,0 +1,8 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Context; | |||
interface ProductPropertyInterface | |||
{ | |||
} |
@@ -25,6 +25,7 @@ use Lc\ShopBundle\Form\ProductType; | |||
use Lc\ShopBundle\Form\Widget\PriceWidgetType; | |||
use Lc\ShopBundle\Repository\BaseRepository; | |||
use Lc\ShopBundle\Repository\ProductCategoryRepository; | |||
use Lc\ShopBundle\Services\Utils; | |||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\Extension\Core\Type\CollectionType; | |||
@@ -40,12 +41,14 @@ class AdminController extends EasyAdminController | |||
protected $security; | |||
protected $userManager; | |||
protected $em ; | |||
protected $utils ; | |||
public function __construct(Security $security, UserManagerInterface $userManager, EntityManagerInterface $em) | |||
public function __construct(Security $security, UserManagerInterface $userManager, EntityManagerInterface $em, Utils $utils) | |||
{ | |||
$this->security = $security; | |||
$this->userManager = $userManager; | |||
$this->em = $em ; | |||
$this->utils = $utils ; | |||
} | |||
public function showAction() |
@@ -16,6 +16,7 @@ use Symfony\Bridge\Doctrine\Form\Type\EntityType; | |||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\Extension\Core\Type\CollectionType; | |||
use Symfony\Component\Form\Extension\Core\Type\DateType; | |||
use Symfony\Component\Form\Extension\Core\Type\MoneyType; | |||
use Symfony\Component\Form\Extension\Core\Type\NumberType; | |||
use Symfony\Component\HttpFoundation\Response; | |||
@@ -24,6 +25,7 @@ class ProductFamilyController extends AdminController | |||
{ | |||
private $taxRateClass; | |||
private $choicesTaxRateParam; | |||
private $choicesSupplierTaxRateParam; | |||
public function createEntityFormBuilder($entity, $view) | |||
{ | |||
@@ -38,10 +40,16 @@ class ProductFamilyController extends AdminController | |||
//ç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(); | |||
@@ -55,30 +63,36 @@ class ProductFamilyController extends AdminController | |||
}, | |||
)); | |||
$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('unit', ChoiceType::class, array( | |||
'label' => 'Unité', | |||
//'' | |||
'choices' => array( | |||
'pièce' => 'piece', | |||
'g' => 'g', | |||
'kg' => 'kg', | |||
'ml' => 'ml', | |||
'L' => 'L' | |||
), | |||
'choices' => $this->utils->getUnitsListFormatedForType() | |||
)); | |||
$formBuilder->add('weight', NumberType::class, array( | |||
'label' => 'Poids', | |||
$formBuilder->add('quantity', NumberType::class, array( | |||
'label' => 'Quantité', | |||
'attr' => [ | |||
'append_html' => 'g' | |||
] | |||
)); | |||
$formBuilder->add('step', NumberType::class, array( | |||
'label' => 'Pas', | |||
'help' => 'Quantité à incrémenter / décrémenter lors des mouvements de quantité', | |||
)); | |||
$formBuilder->add('price', NumberType::class, array( | |||
'label' => 'Prix', | |||
)); | |||
@@ -89,22 +103,59 @@ class ProductFamilyController extends AdminController | |||
'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, | |||
'required'=>false | |||
)); | |||
$formBuilder->add('behaviorCountStock', ChoiceType::class, array( | |||
'label' => 'Stock', | |||
'empty_data' => 'by-product-family', | |||
'choices' => array( | |||
'Gèrer le stock par produit' => 'by-product-family', | |||
'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' | |||
), | |||
'multiple' => false, | |||
'expanded' => true | |||
)); | |||
$formBuilder->add('availableQuantity', NumberType::class, array( | |||
'label' => 'Quantité disponible', | |||
'required' => false, | |||
$formBuilder->add('organicLabel', ChoiceType::class, array( | |||
'label' => 'Type de labellisation', | |||
'choices' => array( | |||
'Agriculture biologique' => 'bio', | |||
'Nature & progrès' => 'nature-progres', | |||
'Haute valeur environnementale' => 'hve' | |||
), | |||
'multiple' => false, | |||
'expanded' => false, | |||
'required' => false | |||
)); | |||
$formBuilder->add('products', CollectionType::class, array( | |||
'label' => 'Déclinaisons', | |||
'entry_type' => ProductType::class, | |||
@@ -224,8 +275,11 @@ class ProductFamilyController extends AdminController | |||
} | |||
ksort($sortableProductsField); | |||
dump($this->request->request); | |||
$editForm->handleRequest($this->request); | |||
if ($editForm->isSubmitted() && $editForm->isValid()) { | |||
$this->processUploadedFiles($editForm); | |||
$this->dispatch(EasyAdminEvents::PRE_UPDATE, ['entity' => $entity]); |
@@ -8,8 +8,10 @@ use FOS\CKEditorBundle\Form\Type\CKEditorType; | |||
use Lc\ShopBundle\Context\ProductFamilyInterface; | |||
use Lc\ShopBundle\Context\ProductInterface; | |||
use Lc\ShopBundle\Context\TaxRateInterface; | |||
use Lc\ShopBundle\Services\Utils; | |||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | |||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
use Symfony\Component\Form\Extension\Core\Type\DateType; | |||
use Symfony\Component\Form\Extension\Core\Type\HiddenType; | |||
use Symfony\Component\Form\Extension\Core\Type\NumberType; | |||
use function PHPSTORM_META\type; | |||
@@ -21,65 +23,53 @@ use Symfony\Component\OptionsResolver\OptionsResolver; | |||
class ProductType extends AbstractType | |||
{ | |||
protected $em; | |||
protected $utils; | |||
public function __construct(EntityManagerInterface $entityManager) | |||
public function __construct(EntityManagerInterface $entityManager, Utils $utils) | |||
{ | |||
$this->em = $entityManager; | |||
$this->utils = $utils; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
$builder->add('titleInherited', CheckboxType::class, array( | |||
/* $builder->add('titleInherited', CheckboxType::class, array( | |||
'mapped'=>false, | |||
'required'=>false | |||
)); | |||
));*/ | |||
$builder->add('title', TextType::class, array( | |||
"required" => false | |||
)) ; | |||
$builder->add('unitInherited', CheckboxType::class, array( | |||
/*$builder->add('unitInherited', CheckboxType::class, array( | |||
'mapped'=>false, | |||
'required'=>false | |||
)); | |||
$builder->add('unit', ChoiceType::class, array( | |||
'label' => 'Unité', | |||
"required" => false, | |||
'choices' => array( | |||
'pièce' => 'piece', | |||
'g' => 'g', | |||
'kg' => 'kg', | |||
'ml' => 'ml', | |||
'L' => 'L' | |||
), | |||
)); | |||
));*/ | |||
$builder->add('weightInherited', CheckboxType::class, array( | |||
/* $builder->add('quantityInherited', CheckboxType::class, array( | |||
'mapped'=>false, | |||
'required'=>false | |||
)); | |||
$builder->add('weight', NumberType::class, array( | |||
'label' => 'Poids', | |||
"required" => false, | |||
));*/ | |||
$builder->add('quantity', NumberType::class, array( | |||
'label' => 'Quantité', | |||
'required'=>false, | |||
'attr' => [ | |||
'append_html' => 'g' | |||
] | |||
)); | |||
$builder->add('stepInherited', CheckboxType::class, array( | |||
'mapped'=>false, | |||
'required'=>false | |||
)); | |||
$builder->add('step', NumberType::class, array( | |||
'label' => 'Pas', | |||
$builder->add('unit', ChoiceType::class, array( | |||
'label' => 'Unité', | |||
"required" => false, | |||
'help' => 'Quantité à incrémenter / décrémenter lors des mouvements de quantité', | |||
'choices' => $this->utils->getUnitsListFormatedForType() | |||
)); | |||
$builder->add('priceInherited', CheckboxType::class, array( | |||
/* $builder->add('priceInherited', CheckboxType::class, array( | |||
'mapped'=>false, | |||
'required'=>false | |||
)); | |||
));*/ | |||
$builder->add('price', NumberType::class, array( | |||
'label' => 'Prix', | |||
"required" => false | |||
@@ -91,11 +81,36 @@ class ProductType extends AbstractType | |||
'mapped' => false | |||
)); | |||
$builder->add('buyingPrice', NumberType::class, array( | |||
'label' => 'Prix d\'achat', | |||
'required'=>false | |||
)); | |||
$builder->add('buyingPriceWithTax', NumberType::class, array( | |||
'label' => 'Prix d\'achat TTC', | |||
'required' => false, | |||
'mapped' => false | |||
)); | |||
$builder->add('multiplyingFactor', NumberType::class, array( | |||
'label' => 'Coefficiant de multiplication', | |||
'mapped'=>false, | |||
'required'=>false | |||
)); | |||
$builder->add('availableQuantity', NumberType::class, array( | |||
'label' => 'Quantité disponible', | |||
'required' => false, | |||
)); | |||
$builder->add('availableQuantityDefault', NumberType::class, array( | |||
'label' => 'Quantité disponible', | |||
'required' => false, | |||
)); | |||
$builder->add('expirationDate', DateType::class,array( | |||
'required' => false, | |||
'widget' => 'single_text' | |||
)); | |||
$builder->add('position', HiddenType::class); | |||
} |
@@ -3,14 +3,18 @@ | |||
namespace Lc\ShopBundle\Model; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\ShopBundle\Context\ProductPropertyInterface; | |||
use Lc\ShopBundle\Context\SortableInterface; | |||
/** | |||
* @ORM\MappedSuperclass() | |||
*/ | |||
abstract class Product extends AbstractEntity implements SortableInterface | |||
abstract class Product extends AbstractEntity implements SortableInterface, ProductPropertyInterface | |||
{ | |||
use SortableTrait; | |||
use ProductPropertyTrait; | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface", inversedBy="products") | |||
* @ORM\JoinColumn(nullable=false) | |||
@@ -22,35 +26,6 @@ abstract class Product extends AbstractEntity implements SortableInterface | |||
*/ | |||
protected $title; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $price; | |||
/** | |||
* @ORM\Column(type="string", length=31, nullable=true) | |||
*/ | |||
protected $unit; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $step; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $weight; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $availableQuantity; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $stock; | |||
public function getProductFamily(): ?ProductFamily | |||
@@ -65,78 +40,6 @@ abstract class Product extends AbstractEntity implements SortableInterface | |||
return $this; | |||
} | |||
public function getPrice(): ?float | |||
{ | |||
return $this->price; | |||
} | |||
public function setPrice(?float $price): self | |||
{ | |||
$this->price = $price; | |||
return $this; | |||
} | |||
public function getUnit(): ?string | |||
{ | |||
return $this->unit; | |||
} | |||
public function setUnit(?string $unit): self | |||
{ | |||
$this->unit = $unit; | |||
return $this; | |||
} | |||
public function getStep(): ?float | |||
{ | |||
return $this->step; | |||
} | |||
public function setStep(?float $step): self | |||
{ | |||
$this->step = $step; | |||
return $this; | |||
} | |||
public function getWeight(): ?float | |||
{ | |||
return $this->weight; | |||
} | |||
public function setWeight(?float $weight): self | |||
{ | |||
$this->weight = $weight; | |||
return $this; | |||
} | |||
public function getAvailableQuantity(): ?float | |||
{ | |||
return $this->availableQuantity; | |||
} | |||
public function setAvailableQuantity(?float $availableQuantity): self | |||
{ | |||
$this->availableQuantity = $availableQuantity; | |||
return $this; | |||
} | |||
public function getStock(): ?float | |||
{ | |||
return $this->stock; | |||
} | |||
public function setStock(?float $stock): self | |||
{ | |||
$this->stock = $stock; | |||
return $this; | |||
} | |||
public function getTitle(): ?string | |||
{ | |||
return $this->title; |
@@ -6,12 +6,15 @@ use Doctrine\Common\Collections\ArrayCollection; | |||
use Doctrine\Common\Collections\Collection; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Lc\ShopBundle\Context\ProductInterface; | |||
use Lc\ShopBundle\Context\ProductPropertyInterface; | |||
/** | |||
* @ORM\MappedSuperclass() | |||
*/ | |||
abstract class ProductFamily extends AbstractDocumentEntity | |||
abstract class ProductFamily extends AbstractDocumentEntity implements ProductPropertyInterface | |||
{ | |||
use ProductPropertyTrait; | |||
/** | |||
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\MerchantInterface", inversedBy="productFamilies") | |||
* @ORM\JoinColumn(nullable=false) | |||
@@ -23,6 +26,16 @@ abstract class ProductFamily extends AbstractDocumentEntity | |||
*/ | |||
protected $productCategories; | |||
/** | |||
* @ORM\Column(type="boolean") | |||
*/ | |||
protected $activeProducts; | |||
/** | |||
* @ORM\Column(type="string", length=255, nullable=true) | |||
*/ | |||
protected $productsType; | |||
/** | |||
* @ORM\OneToMany(targetEntity="Lc\ShopBundle\Context\ProductInterface", mappedBy="productFamily", orphanRemoval=true, cascade={"persist"}) | |||
*/ | |||
@@ -35,50 +48,53 @@ abstract class ProductFamily extends AbstractDocumentEntity | |||
protected $taxRate; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\TaxRateInterface") | |||
*/ | |||
protected $price; | |||
protected $supplierTaxRate; | |||
/** | |||
* @ORM\Column(type="string", length=31, nullable=true) | |||
* @ORM\Column(type="string", length=255, nullable=true) | |||
*/ | |||
protected $unit; | |||
protected $subTitle; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
* @ORM\Column(type="text", nullable=true) | |||
*/ | |||
protected $step; | |||
protected $note; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
* @ORM\Column(type="string", length=31, nullable=true) | |||
*/ | |||
protected $weight; | |||
protected $behaviorOutOfStock; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
* @ORM\Column(type="string", length=31) | |||
*/ | |||
protected $stock; | |||
protected $behaviorCountStock; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
* @ORM\Column(type="boolean", nullable=true) | |||
*/ | |||
protected $availableQuantity; | |||
protected $isNovelty; | |||
/** | |||
* @ORM\Column(type="string", length=31, nullable=true) | |||
* @ORM\Column(type="date", nullable=true) | |||
*/ | |||
protected $behaviorOutOfStock; | |||
protected $noveltyExpirationDate; | |||
/** | |||
* @ORM\Column(type="string", length=31) | |||
* @ORM\Column(type="boolean", nullable=true) | |||
*/ | |||
protected $behaviorCountStock; | |||
protected $isOrganic; | |||
/** | |||
* @ORM\Column(type="boolean") | |||
* @ORM\Column(type="string", length=255, nullable=true) | |||
*/ | |||
protected $activeProducts; | |||
protected $organicLabel; | |||
public function __construct() | |||
{ | |||
@@ -98,6 +114,30 @@ abstract class ProductFamily extends AbstractDocumentEntity | |||
return $this; | |||
} | |||
public function getActiveProducts(): ?bool | |||
{ | |||
return $this->activeProducts; | |||
} | |||
public function setActiveProducts(bool $activeProducts): self | |||
{ | |||
$this->activeProducts = $activeProducts; | |||
return $this; | |||
} | |||
public function getProductsType(): ?string | |||
{ | |||
return $this->productsType; | |||
} | |||
public function setProductsType(?string $productsType): self | |||
{ | |||
$this->productsType = $productsType; | |||
return $this; | |||
} | |||
/** | |||
* @return Collection|ProductInterface[] | |||
*/ | |||
@@ -139,7 +179,7 @@ abstract class ProductFamily extends AbstractDocumentEntity | |||
public function initProductCategories() | |||
{ | |||
$this->productCategories = new ArrayCollection() ; | |||
$this->productCategories = new ArrayCollection(); | |||
} | |||
public function addProductCategory(ProductCategory $productCategory): self | |||
@@ -172,111 +212,119 @@ abstract class ProductFamily extends AbstractDocumentEntity | |||
return $this; | |||
} | |||
public function getUnit(): ?string | |||
public function getSupplierTaxRate(): ?TaxRate | |||
{ | |||
return $this->unit; | |||
return $this->supplierTaxRate; | |||
} | |||
public function setUnit(?string $unit): self | |||
public function setSupplierTaxRate(?TaxRate $supplierTaxRate): self | |||
{ | |||
$this->unit = $unit; | |||
$this->supplierTaxRate = $supplierTaxRate; | |||
return $this; | |||
} | |||
public function getPrice(): ?float | |||
public function getSubTitle(): ?string | |||
{ | |||
return $this->price; | |||
return $this->subTitle; | |||
} | |||
public function setPrice(?float $price): self | |||
public function setSubTitle(?string $subTitle): self | |||
{ | |||
$this->price = $price; | |||
$this->subTitle = $subTitle; | |||
return $this; | |||
} | |||
public function getStep(): ?float | |||
public function getNote(): ?string | |||
{ | |||
return $this->step; | |||
return $this->note; | |||
} | |||
public function setStep(?float $step): self | |||
public function setNote(?string $note): self | |||
{ | |||
$this->step = $step; | |||
$this->note = $note; | |||
return $this; | |||
} | |||
public function getWeight(): ?float | |||
public function getBehaviorOutOfStock(): ?string | |||
{ | |||
return $this->weight; | |||
return $this->behaviorOutOfStock; | |||
} | |||
public function setWeight(?float $weight): self | |||
public function setBehaviorOutOfStock(?string $behaviorOutOfStock): self | |||
{ | |||
$this->weight = $weight; | |||
$this->behaviorOutOfStock = $behaviorOutOfStock; | |||
return $this; | |||
} | |||
public function getStock(): ?float | |||
public function getBehaviorCountStock(): ?string | |||
{ | |||
return $this->stock; | |||
return $this->behaviorCountStock; | |||
} | |||
public function setStock(?float $stock): self | |||
public function setBehaviorCountStock(string $behaviorCountStock): self | |||
{ | |||
$this->stock = $stock; | |||
$this->behaviorCountStock = $behaviorCountStock; | |||
return $this; | |||
} | |||
public function getAvailableQuantity(): ?float | |||
public function getIsNovelty(): ?bool | |||
{ | |||
return $this->availableQuantity; | |||
return $this->isNovelty; | |||
} | |||
public function setAvailableQuantity(?float $availableQuantity): self | |||
public function setIsNovelty(?bool $isNovelty): self | |||
{ | |||
$this->availableQuantity = $availableQuantity; | |||
$this->isNovelty = $isNovelty; | |||
return $this; | |||
} | |||
public function getBehaviorOutOfStock(): ?string | |||
public function getNoveltyExpirationDate(): ?\DateTimeInterface | |||
{ | |||
return $this->behaviorOutOfStock; | |||
return $this->noveltyExpirationDate; | |||
} | |||
public function setBehaviorOutOfStock(?string $behaviorOutOfStock): self | |||
public function setNoveltyExpirationDate(?\DateTimeInterface $noveltyExpirationDate): self | |||
{ | |||
$this->behaviorOutOfStock = $behaviorOutOfStock; | |||
$this->noveltyExpirationDate = $noveltyExpirationDate; | |||
return $this; | |||
} | |||
public function getBehaviorCountStock(): ?string | |||
public function getIsOrganic(): ?bool | |||
{ | |||
return $this->behaviorCountStock; | |||
return $this->isOrganic; | |||
} | |||
public function setBehaviorCountStock(string $behaviorCountStock): self | |||
public function setIsOrganic(?bool $isOrganic): self | |||
{ | |||
$this->behaviorCountStock = $behaviorCountStock; | |||
$this->isOrganic = $isOrganic; | |||
return $this; | |||
} | |||
public function getActiveProducts(): ?bool | |||
public function getOrganicLabel(): ?string | |||
{ | |||
return $this->activeProducts; | |||
return $this->organicLabel; | |||
} | |||
public function setActiveProducts(bool $activeProducts): self | |||
public function setOrganicLabel(?string $organicLabel): self | |||
{ | |||
$this->activeProducts = $activeProducts; | |||
$this->organicLabel = $organicLabel; | |||
return $this; | |||
} | |||
} |
@@ -0,0 +1,137 @@ | |||
<?php | |||
namespace Lc\ShopBundle\Model; | |||
use Doctrine\ORM\Mapping as ORM; | |||
use Gedmo\Mapping\Annotation as Gedmo; | |||
trait ProductPropertyTrait | |||
{ | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $price; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $buyingPrice; | |||
/** | |||
* @ORM\Column(type="string", length=31, nullable=true) | |||
*/ | |||
protected $unit; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $quantity; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $availableQuantity; | |||
/** | |||
* @ORM\Column(type="float", nullable=true) | |||
*/ | |||
protected $availableQuantityDefault; | |||
/** | |||
* @ORM\Column(type="date", nullable=true) | |||
*/ | |||
protected $expirationDate; | |||
public function getUnit(): ?string | |||
{ | |||
return $this->unit; | |||
} | |||
public function setUnit(?string $unit): self | |||
{ | |||
$this->unit = $unit; | |||
return $this; | |||
} | |||
public function getPrice(): ?float | |||
{ | |||
return $this->price; | |||
} | |||
public function setPrice(?float $price): self | |||
{ | |||
$this->price = $price; | |||
return $this; | |||
} | |||
public function getBuyingPrice(): ?float | |||
{ | |||
return $this->buyingPrice; | |||
} | |||
public function setBuyingPrice(?float $buyingPrice): self | |||
{ | |||
$this->buyingPrice = $buyingPrice; | |||
return $this; | |||
} | |||
public function getQuantity(): ?float | |||
{ | |||
return $this->quantity; | |||
} | |||
public function setQuantity(?float $quantity): self | |||
{ | |||
$this->quantity = $quantity; | |||
return $this; | |||
} | |||
public function getAvailableQuantity(): ?float | |||
{ | |||
return $this->availableQuantity; | |||
} | |||
public function setAvailableQuantity(?float $availableQuantity): self | |||
{ | |||
$this->availableQuantity = $availableQuantity; | |||
return $this; | |||
} | |||
public function getAvailableQuantityDefault(): ?float | |||
{ | |||
return $this->availableQuantityDefault; | |||
} | |||
public function setAvailableQuantityDefault(?float $availableQuantityDefault): self | |||
{ | |||
$this->availableQuantityDefault = $availableQuantityDefault; | |||
return $this; | |||
} | |||
public function getExpirationDate(): ?\DateTimeInterface | |||
{ | |||
return $this->expirationDate; | |||
} | |||
public function setExpirationDate(?\DateTimeInterface $expirationDate): self | |||
{ | |||
$this->expirationDate = $expirationDate; | |||
return $this; | |||
} | |||
} |
@@ -82,3 +82,12 @@ | |||
.product-form.modal .form-check-label{font-style: italic; color: #666; text-align: left;} | |||
.products-collection-table .inherited{color: #888; font-style: italic; font-weight: initial;} | |||
.products-collection-table td{} | |||
#lc-product-family-edit .products-collection-table {table-layout:fixed;} | |||
#lc-product-family-edit .products-collection-table tr{border-bottom: 1px solid #dee2e6;} | |||
#lc-product-family-edit .products-collection-table th{font-size:13px; border-left: 1px solid #dee2e6; border-top: 1px solid #dee2e6; text-align: center;} | |||
#lc-product-family-edit .products-collection-table th span {white-space: initial;} | |||
#lc-product-family-edit .products-collection-table th:last-child{border-right: 1px solid #dee2e6;} | |||
#lc-product-family-edit .products-collection-table td{border-left: 1px solid #dee2e6; text-align: center; font-size: 13px;} | |||
#lc-product-family-edit .products-collection-table td:last-child{border-right: 1px solid #dee2e6;} | |||
#lc-product-family-edit .btn-add-product {margin: 20px 0; float: right;} | |||
#lc-product-family-edit .inherited {color: #888; font-style: italic; font-weight: initial;} |
@@ -21,6 +21,7 @@ function initLcSortableProductsList(){ | |||
}); | |||
} | |||
function updateSortableProducts(){ | |||
log('update'); | |||
$('.lc-sortable-products tr.lc-draggable').each(function (index, li) { | |||
$(li).find('.field-position').val(index); | |||
}); |
@@ -127,13 +127,18 @@ $.fn.serializeObject = function () { | |||
}; | |||
function getDateFormatted(date) { | |||
var _d = date.getDate(), | |||
d = _d > 9 ? _d : '0' + _d, | |||
_m = date.getMonth() + 1, | |||
m = _m > 9 ? _m : '0' + _m, | |||
formatted = date.getFullYear() + '-' + m + '-' + d; | |||
return formatted; | |||
function getDateFormatted(date, separator) { | |||
if(date) { | |||
var date = new Date(date); | |||
var _d = date.getDate(), | |||
d = _d > 9 ? _d : '0' + _d, | |||
_m = date.getMonth() + 1, | |||
m = _m > 9 ? _m : '0' + _m, | |||
formatted = d + separator + m + separator + date.getFullYear(); | |||
return formatted; | |||
}else{ | |||
return ''; | |||
} | |||
} | |||
//Affiche une alert au click sur un bouton submit lorsqu'un utilisateur admin tente de modifer un établissement |
@@ -1,78 +1,121 @@ | |||
let mixinPriceProduct = { | |||
let mixinPriceWithTaxField = { | |||
data() { | |||
return { | |||
price: null, | |||
priceWithTax: null | |||
priceWithTax: null, | |||
buyingPrice: null, | |||
buyingPriceWithTax: null, | |||
differentSupplierTaxRate: null, | |||
multiplyingFactor: null, | |||
priceByRefUnit:null, | |||
priceByRefUnitWithTax:null | |||
}; | |||
}, | |||
methods: { | |||
changePrice: function () { | |||
this.priceUpdate('price'); | |||
computed:{ | |||
taxRateValue: function () { | |||
return $('#productfamily_taxRate').find('option[value="'+this.taxRate+'"]').data('tax-rate-value'); | |||
}, | |||
changePriceWithTax: function () { | |||
this.priceUpdate('priceWithTax'); | |||
}, | |||
priceUpdate: function (priceType) { | |||
if (priceType == 'priceWithTax' && this.price) { | |||
this.price = parseFloat(this.price.replace(',', '.')).toFixed(3); | |||
this.priceWithTax = getPriceWithTax(this.price, this.productFamily.taxRateValue ); | |||
} else if (this.priceWithTax){ | |||
this.priceWithTax = parseFloat(this.priceWithTax.replace(',', '.')).toFixed(2); | |||
this.price = getPrice(this.priceWithTax, this.productFamily.taxRateValue ); | |||
supplierTaxRateValue: function () { | |||
if($('#productfamily_supplierTaxRate').find('option[value="'+this.supplierTaxRate+'"]').data('tax-rate-value') == 'inherited') { | |||
return this.taxRateValue; | |||
}else{ | |||
return $('#productfamily_supplierTaxRate').find('option[value="'+this.supplierTaxRate+'"]').data('tax-rate-value'); | |||
} | |||
} | |||
} | |||
}; | |||
}, | |||
let mixinPriceWithTaxField = { | |||
data() { | |||
return { | |||
price: null, | |||
priceWithTax: null, | |||
taxRate:null, | |||
taxRateValue:null | |||
}; | |||
}, | |||
mounted: function () { | |||
this.setTaxRateValue(); | |||
}, | |||
methods: { | |||
/*changeTaxRate: function () { | |||
this.$emit('tax-rate-change'); | |||
this.changePriceWithTax(); | |||
},*/ | |||
changeBuyingPrice: function () { | |||
this.buyingPriceUpdate('buyingPrice'); | |||
}, | |||
changeBuyingPriceWithTax: function () { | |||
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 ); | |||
} else if (this.priceWithTax){ | |||
this.priceWithTax = parseFloat(this.priceWithTax.replace(',', '.')).toFixed(2); | |||
this.price = getPrice(this.priceWithTax, this.taxRateValue ); | |||
this.priceWithTax = getPriceWithTax(this.price, this.taxRateValue); | |||
} else if (this.priceWithTax) { | |||
if(typeof this.priceWithTax !="number"){ | |||
this.priceWithTax = parseFloat(this.priceWithTax.replace(',', '.')); | |||
} | |||
this.priceWithTax = this.priceWithTax.toFixed(2); | |||
this.price = getPrice(this.priceWithTax, this.taxRateValue); | |||
} | |||
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) { | |||
this.buyingPriceWithTax = parseFloat(this.buyingPriceWithTax.replace(',', '.')).toFixed(2); | |||
this.buyingPrice = getPrice(this.buyingPriceWithTax, this.supplierTaxRateValue); | |||
} | |||
this.setMultiplyingFactor(); | |||
this.priceByRefUnitUpdate(); | |||
}, | |||
updateMultiplyingFactor: function () { | |||
this.priceWithTax = this.buyingPriceValue * this.multiplyingFactor; | |||
this.priceUpdate('price'); | |||
}, | |||
setMultiplyingFactor:function () { | |||
if(this.priceWithTax || this.buyingPrice) { | |||
this.multiplyingFactor = parseFloat(this.priceWithTaxValue / this.buyingPriceValue).toFixed(3); | |||
} | |||
}, | |||
setTaxRateValue: function () { | |||
this.taxRateValue = $('#productfamily_taxRate').find('option:selected').data('tax-rate-value'); | |||
priceByRefUnitUpdate:function () { | |||
if(this.unitArray[this.unitValue]){ | |||
this.priceByRefUnit = parseFloat((this.priceValue / this.quantityValue) *this.unitArray[this.unitValue].coefficient).toFixed(2); | |||
this.priceByRefUnitWithTax = parseFloat((this.priceWithTaxValue / this.quantityValue )*this.unitArray[this.unitValue].coefficient).toFixed(2); | |||
} | |||
} | |||
}, | |||
watch:{ | |||
taxRate: function (){ | |||
this.setTaxRateValue(); | |||
this.changePriceWithTax(); | |||
} | |||
watch: { | |||
} | |||
}; | |||
let mixinUnit = { | |||
data() { | |||
return Object.assign( | |||
{ | |||
quantity:null, | |||
unit: null, | |||
unitArray: null | |||
}, window.mixinUnitValues); | |||
}, | |||
computed: { | |||
unitReference: function () { | |||
if (this.unit) { | |||
return this.unitArray[this.unit].ref | |||
} else { | |||
return ''; | |||
} | |||
} | |||
} | |||
}; | |||
let mixinTemplate = { | |||
data() { | |||
return { |
@@ -3,63 +3,119 @@ var staticRenderFns = []; | |||
Vue.component('product-unit-price', { | |||
mixins: [mixinPriceWithTaxField, mixinTemplate], | |||
mixins: [mixinUnit, mixinPriceWithTaxField, mixinTemplate], | |||
props: ['template', 'keyForm'], | |||
data() { | |||
return Object.assign( | |||
{ | |||
step: null, | |||
unit: null, | |||
weight: null | |||
return Object.assign({ | |||
taxRate: null, | |||
supplierTaxRate: null, | |||
}, window.productUnitPriceValues); | |||
}, | |||
methods: { | |||
getUnitReference: function () { | |||
if (this.unit == 'g') { | |||
return 'kg'; | |||
} else if (this.unit == 'ml') { | |||
return 'L'; | |||
} else { | |||
return this.unit; | |||
} | |||
computed:{ | |||
buyingPriceValue:function() { | |||
return this.buyingPrice; | |||
}, | |||
buyingPriceWithTaxValue:function() { | |||
return this.buyingPriceWithTax; | |||
}, | |||
priceWithTaxValue:function(){ | |||
return this.priceWithTax; | |||
}, | |||
priceValue:function(){ | |||
return this.price; | |||
}, | |||
quantityValue:function(){ | |||
return this.quantity; | |||
}, | |||
unitValue:function(){ | |||
return this.unit; | |||
} | |||
}, | |||
mounted: function () { | |||
this.priceUpdate('priceWithTax'); | |||
this.buyingPriceUpdate('buyingPriceWithTax'); | |||
}, | |||
watch: { | |||
/*log($('.product-form.modal .select-unit')); | |||
$('.product-form.modal .select-unit').find('option:selected').each(function(i,elm){ | |||
$(this).prop("selected", false); | |||
}); | |||
log($('.product-form.modal .select-unit'));*/ | |||
taxRate: function () { | |||
this.changePriceWithTax(); | |||
}, | |||
supplierTaxRate: function () { | |||
this.changeBuyingPriceWithTax(); | |||
} | |||
/*log($('.product-form.modal .select-unit')); | |||
$('.product-form.modal .select-unit').find('option:selected').each(function(i,elm){ | |||
$(this).prop("selected", false); | |||
}); | |||
log($('.product-form.modal .select-unit'));*/ | |||
} | |||
}); | |||
Vue.component('product-form', { | |||
mixins: [mixinPriceProduct, mixinTemplate], | |||
mixins: [mixinUnit, mixinPriceWithTaxField, mixinTemplate], | |||
props: ['template', 'keyForm', 'productFamily'], | |||
computed:{ | |||
taxRate:function () { | |||
return this.productFamily.taxRate; | |||
}, | |||
supplierTaxRate:function () { | |||
return this.productFamily.supplierTaxRate; | |||
}, | |||
buyingPriceValue:function() { | |||
if (this.buyingPrice) return this.buyingPrice; | |||
else return this.productFamily.buyingPrice; | |||
}, | |||
buyingPriceWithTaxValue:function() { | |||
if (this.buyingPriceWithTax) return this.buyingPriceWithTax; | |||
else return this.productFamily.buyingPriceWithTax; | |||
}, | |||
priceWithTaxValue:function(){ | |||
if(this.priceWithTax) return this.priceWithTax; | |||
else return this.productFamily.priceWithTax; | |||
}, | |||
priceValue:function(){ | |||
if(this.price) return this.price; | |||
else return this.productFamily.price; | |||
}, | |||
quantityValue:function(){ | |||
if(this.quantity) return this.quantity; | |||
else return this.productFamily.quantity; | |||
}, | |||
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, '-') | |||
} | |||
}, | |||
data() { | |||
return Object.assign( | |||
{ | |||
title: null, | |||
titleInherited: null, | |||
fieldToUpdate: ['title', 'unit', 'weight', 'step', 'price'], | |||
unit: null, | |||
unitInherited: null, | |||
step: null, | |||
stepInherited: null, | |||
weight: null, | |||
weightInherited: null, | |||
fieldToUpdate: ['title', 'unit', 'quantity', 'price'], | |||
price: null, | |||
priceInherited: null, | |||
priceWithTax: null, | |||
stock: null, | |||
availableQuantity: null | |||
buyingPrice: null, | |||
multiplyingFactor: null, | |||
availableQuantityDefault: null, | |||
availableQuantity: null, | |||
expirationDate: null, | |||
titleInherited: false, | |||
priceInherited: false, | |||
priceWithTaxInherited: false, | |||
unitInherited: false, | |||
quantityInherited: false, | |||
multiplyingFactorInherited: false, | |||
buyingPriceInherited: false, | |||
buyingPriceWithTaxInherited: false, | |||
expirationDateInherited: false, | |||
availableQuantityInherited: false, | |||
availableQuantityDefaultInherited: false | |||
}, window.productForm[this.keyForm]) | |||
}, | |||
mounted: function () { | |||
@@ -70,104 +126,41 @@ Vue.component('product-form', { | |||
this.updateProductView(); | |||
}, | |||
methods: { | |||
getUnitReference: function () { | |||
if (this.productFamily.unit == 'g') { | |||
return 'kg'; | |||
} else if (this.productFamily.unit == 'ml') { | |||
return 'L'; | |||
} else { | |||
return this.productFamily.unit; | |||
} | |||
}, | |||
updateProductForm: function () { | |||
this.changePriceWithTax(); | |||
$('#productfamily_products_' + this.keyForm + '_unit').find('option').hide(); | |||
log('fefe'); | |||
this.changeBuyingPriceWithTax(); | |||
//EDIT UNIT | |||
/* $('#productfamily_products_' + this.keyForm + '_unit').find('option').hide(); | |||
switch (this.productFamily.unit) { | |||
case 'kg' : | |||
case 'g' : | |||
$('.products-collection-table').find('th.step, td.step').show(); | |||
$('.products-collection-table').find('th.weight, td.weight').hide(); | |||
$('#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' : | |||
$('.products-collection-table').find('th.step, td.step').show(); | |||
$('.products-collection-table').find('th.weight, td.weight').hide(); | |||
$('#productfamily_products_' + this.keyForm + '_unit').find('option[value="ml"]').show(); | |||
$('#productfamily_products_' + this.keyForm + '_unit').find('option[value="L"]').show(); | |||
break; | |||
case 'piece': | |||
$('.products-collection-table').find('th.step, td.step').hide(); | |||
$('.products-collection-table').find('th.weight, td.weight').show(); | |||
$('#productfamily_products_' + this.keyForm + '_unit').find('option[value="piece"]').show(); | |||
break; | |||
} | |||
}*/ | |||
}, | |||
updateProductView: function () { | |||
//NE PAS SUPPRIMER | |||
/* for (i = 0; i < this.fieldToUpdate.length; i++) { | |||
value = this[this.fieldToUpdate[i]]; | |||
inherited = this[this.fieldToUpdate[i]+'Inherited']; | |||
inheritedValue = this['productFamily'][this.fieldToUpdate[i]]; | |||
if (value) { | |||
this[this.fieldToUpdate[i]+'Inherited'] = false; | |||
$('#product-item-' + this.keyForm).find('.'+this.fieldToUpdate[i]).html(value); | |||
} else { | |||
this[this.fieldToUpdate[i]+'Inherited'] = true; | |||
$('#product-item-' + this.keyForm).find('.'+this.fieldToUpdate[i]).html('<span class="inherited">' + inheritedValue + '</span>'); | |||
} | |||
}*/ | |||
if (this.title) { | |||
this.titleInherited = false; | |||
$('#product-item-' + this.keyForm).find('.title').html(this.title); | |||
} else { | |||
this.titleInherited = true; | |||
$('#product-item-' + this.keyForm).find('.title').html('<span class="inherited">' + this.productFamily.title + '</span>'); | |||
log(this.unitValue); | |||
if(this.unitValue == 'piece'){ | |||
$('.priceByRefUnit').hide(); | |||
}else{ | |||
$('.priceByRefUnit').show(); | |||
} | |||
if (this.unit) { | |||
this.unitInherited = false; | |||
$('#product-item-' + this.keyForm).find('.unit').html(this.unit); | |||
} else { | |||
this.unitInherited = true; | |||
$('#product-item-' + this.keyForm).find('.unit').html('<span class="inherited">' + this.productFamily.unit + '</span>'); | |||
} | |||
if (this.step) { | |||
this.stepInherited = false; | |||
$('#product-item-' + this.keyForm).find('.step').html(this.step + ' / '+this.unit); | |||
} else { | |||
this.stepInherited = true; | |||
$('#product-item-' + this.keyForm).find('.step').html('<span class="inherited">' + this.productFamily.step + ' / '+ this.productFamily.unit+'</span>'); | |||
} | |||
if (this.weight) { | |||
this.weightInherited = false; | |||
$('#product-item-' + this.keyForm).find('.weight').html(this.weight + ' / '+this.getUnitReference()); | |||
} else { | |||
this.weightInherited = true; | |||
$('#product-item-' + this.keyForm).find('.weight').html('<span class="inherited">' + this.productFamily.weight + ' / '+this.getUnitReference()+'</span>'); | |||
} | |||
if (this.price) { | |||
this.priceInherited = false; | |||
$('#product-item-' + this.keyForm).find('.price').html(this.price + ' € HT / '+this.getUnitReference()); | |||
} else { | |||
this.priceInherited = true; | |||
$('#product-item-' + this.keyForm).find('.price').html('<span class="inherited">' + this.productFamily.price + ' € HT/ '+this.getUnitReference()+'</span>'); | |||
} | |||
log(this.productFamily.behaviorCountStock); | |||
if (this.productFamily.behaviorCountStock == 'by-product-family') { | |||
if (this.productFamily.behaviorCountStock == 'by-product-family' || this.productFamily.behaviorCountStock == 'by-quantity') { | |||
$('.products-collection-table').find('.stock').hide(); | |||
} else { | |||
$('.products-collection-table').find('.stock').show(); | |||
$('#product-item-' + this.keyForm).find('.stock').html(this.availableQuantity + ' / '+this.getUnitReference()); | |||
$('#product-item-' + this.keyForm).find('.stock').html(this.availableQuantity + ' / ' + this.unitReference); | |||
} | |||
}, | |||
saveProductForm: function () { | |||
@@ -176,22 +169,24 @@ Vue.component('product-form', { | |||
$('#form-product-modal-' + this.keyForm).modal('hide'); | |||
}, | |||
deleteProductForm: function () { | |||
if(confirm('Êtes-vous sur de cette action ?')) { | |||
this.$parent.formProductArray.splice(this.keyForm, 1); | |||
} | |||
}, | |||
}, | |||
watch: { | |||
titleInherited: function (val) { | |||
if(val)this.title = null; | |||
if (val) this.title = null; | |||
}, | |||
unitInherited: function (val) { | |||
if(val)this.unit = null; | |||
}, | |||
weightInherited: function (val) { | |||
if(val)this.weight = null; | |||
if (val) this.unit = null; | |||
}, | |||
stepInherited: function (val) { | |||
if(val)this.step = null; | |||
quantityInherited: function (val) { | |||
if (val) this.quantity = null; | |||
}, | |||
priceInherited: function (val) { | |||
if(val)this.price = null; | |||
if (val) this.price = null; | |||
}, | |||
} | |||
}); | |||
@@ -206,13 +201,24 @@ appProductFamily = new Vue({ | |||
'title': this.title, | |||
'behaviorCountStock': this.behaviorCountStock, | |||
'unit': this.$refs.productUnitPrice.unit, | |||
'step': this.$refs.productUnitPrice.step, | |||
'weight': this.$refs.productUnitPrice.weight, | |||
'quantity': this.$refs.productUnitPrice.quantity, | |||
'price': this.$refs.productUnitPrice.price, | |||
'priceWithTax': this.$refs.productUnitPrice.priceWithTax, | |||
'buyingPrice': this.$refs.productUnitPrice.buyingPrice, | |||
'buyingPriceWithTax': this.$refs.productUnitPrice.buyingPriceWithTax, | |||
'priceByRefUnit': this.$refs.productUnitPrice.priceByRefUnit, | |||
'priceByRefUnitWithTax': this.$refs.productUnitPrice.priceByRefUnitWithTax, | |||
'taxRate': this.$refs.productUnitPrice.taxRate, | |||
'taxRateValue': this.$refs.productUnitPrice.taxRateValue | |||
'supplierTaxRate': this.$refs.productUnitPrice.supplierTaxRate, | |||
'multiplyingFactor': this.$refs.productUnitPrice.multiplyingFactor, | |||
'taxRateValue': this.$refs.productUnitPrice.taxRateValue, | |||
'expirationDate': this.expirationDate | |||
}; | |||
}, | |||
unitReference: function () { | |||
this.getUnitReference(); | |||
} | |||
}, | |||
data() { | |||
@@ -221,6 +227,9 @@ appProductFamily = new Vue({ | |||
indexFormProduct: 0, | |||
title: null, | |||
activeProducts: false, | |||
isNovelty: null, | |||
isOrganic: null, | |||
expirationDate:null, | |||
behaviorCountStock: null, | |||
formProductArray: [], | |||
currentSection: 'general', | |||
@@ -236,9 +245,25 @@ appProductFamily = new Vue({ | |||
{ | |||
name: 'products', | |||
nameDisplay: 'Déclinaisons' | |||
}, | |||
{ | |||
name: 'stock', | |||
nameDisplay: 'Stock' | |||
}, | |||
{ | |||
name: 'property', | |||
nameDisplay: 'Caractéristiques' | |||
}, | |||
{ | |||
name: 'note', | |||
nameDisplay: 'Note interne' | |||
} | |||
] | |||
}, window.appProductFamilyValues); | |||
}, | |||
mounted: function () { | |||
}, | |||
methods: { | |||
@@ -247,26 +272,15 @@ appProductFamily = new Vue({ | |||
this.currentSection = section.name; | |||
}, | |||
addProductForm: function () { | |||
var $collectionHolder = $('tbody.products-collection'); | |||
var $collectionHolder = $('table.products-collection-table'); | |||
var prototype = $collectionHolder.data('prototype'); | |||
var newForm = prototype; | |||
newForm = newForm.replace(/__name__/g, this.indexFormProduct); | |||
this.formProductArray.push(newForm); | |||
this.indexFormProduct++; | |||
}, | |||
editProductForm: function (key) { | |||
$('#form-product-modal-' + key).modal(); | |||
this.updateChild(); | |||
//updateSortableProducts(); | |||
}, | |||
deleteProductForm: function (key) { | |||
this.formProductArray.splice(key, 1); | |||
}, | |||
getUnitReference: function () { | |||
if (typeof this.$refs.productUnitPrice !== 'undefined') { | |||
return this.$refs.productUnitPrice.getUnitReference(); | |||
} | |||
}, | |||
updateChild: function () { | |||
if (typeof this.$refs.productForm !== 'undefined') { | |||
for (i = 0; i < this.$refs.productForm.length; i++) { | |||
@@ -274,6 +288,11 @@ appProductFamily = new Vue({ | |||
this.$refs.productForm[i].updateProductView(); | |||
} | |||
} | |||
}, | |||
getUnitReference: function () { | |||
if (typeof this.$refs.productUnitPrice !== 'undefined') { | |||
return this.$refs.productUnitPrice.unitReference; | |||
} | |||
} | |||
}, | |||
watch: { |
@@ -1,63 +0,0 @@ | |||
{{ form_start(form) }} | |||
<div id="lc-product-edit"> | |||
<div class="form"> | |||
{{ form_row(form.title) }} | |||
{{ form_row(form.unit, {"attr":{'v-model': 'unit'}}) }} | |||
<div class="col-10"> | |||
<div v-if="unit == 'piece'" class="form-group field-weight"> | |||
{{ form_label(form.weight) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.weight) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">g</span> | |||
</div> | |||
</div> | |||
{{ form_help(form.weight) }} | |||
</div> | |||
</div> | |||
<div v-else class="form-group field-step"> | |||
{{ form_label(form.step) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.step) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">${ unit }</span> | |||
</div> | |||
</div> | |||
{{ form_help(form.step) }} | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-10"> | |||
<div class="form-group field-price"> | |||
{{ form_label(form.price) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.price) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ HT / ${ getUnitReference() }</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-10"> | |||
<div class="form-group field-price"> | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.priceWithTax) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ TTC / ${ getUnitReference() }</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
{{ form_end(form) }} | |||
@@ -1,198 +0,0 @@ | |||
{% macro printProductRow(product) %} | |||
<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 v-if="unit == 'piece'" class="form-group row field-weight"> | |||
{{ form_label(product.weight, null, {'label_attr': {'class': 'col-2 col-form-label text-right'}}) }} | |||
<div class="form-widget col-10"> | |||
{{ form_widget(product.weightInherited, {'label': 'Utiliser la valeur par défaut : {{ productFamily.weight }}','attr' : {'v-model' : 'weightInherited'}}) }} | |||
<div v-show="weightInherited == false" class="input-group"> | |||
{{ form_widget(product.weight, {'attr' : {'v-model' : 'weight'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">g</span> | |||
</div> | |||
</div> | |||
{{ form_help(product.weight) }} | |||
</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 %}{{ getUnitReference() }}{% endverbatim %}</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="form-group row field-price"> | |||
<div class="col-2"> </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 %}{{ getUnitReference() }}{% 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 %}{{ getUnitReference() }}{% 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> | |||
{% 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>Unité</span> | |||
</th> | |||
<th class="weight"> | |||
<span>Poids</span> | |||
</th> | |||
<th class="step"> | |||
<span>Pas</span> | |||
</th> | |||
<th class="price"> | |||
<span>Prix HT</span> | |||
</th> | |||
<th class="stock"> | |||
<span>Stock</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"> | |||
<td><i class="fa fa-fw fa-sort"></i></td> | |||
<td class="title"></td> | |||
<td class="unit"></td> | |||
<td class="weight"></td> | |||
<td class="step"></td> | |||
<td class="price"></td> | |||
<td class="stock"></td> | |||
<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> | |||
<product-form ref="productForm" v-bind:product-family="productFamily" :template="formProduct" | |||
:key-form="key"></product-form> | |||
</td> | |||
</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.step %}step: parseInt({{ product.vars.value.step }}),{% endif %} | |||
{% if product.vars.value.weight %}weight: parseFloat({{ product.vars.value.weight }}),{% 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 %} | |||
@@ -1,191 +0,0 @@ | |||
{{ form_start(form, {"attr": {'@change' : 'formUpdated'}}) }} | |||
<div class="lc-vue-js-container" id="lc-product-family-edit"> | |||
<div id="nav-params"> | |||
<button type="button" v-for="section in sectionsArray" | |||
v-if="(section.name == 'products' && activeProducts == true) || (section.name != 'products')" | |||
:class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')" | |||
@click="changeSection(section)"> | |||
${ section.nameDisplay } | |||
<span v-if="section.name == 'products'">({{ form.products|length }})</span> | |||
<span class="glyphicon glyphicon-triangle-bottom"></span> | |||
</button> | |||
</div> | |||
<div class="form"> | |||
<script>// rendered by server | |||
window.appProductFamilyValues = { | |||
{% if form.vars.value.title %}title: "{{ form.vars.value.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.activeProducts %}activeProducts: "{{ form.vars.value.activeProducts }}"{% endif %} | |||
}; | |||
window.productUnitPriceValues = { | |||
{% if form.vars.value.unit %}unit: "{{ form.vars.value.unit }}",{% endif %} | |||
{% if form.vars.value.step %}step: parseInt({{ form.vars.value.step }}),{% endif %} | |||
{% if form.vars.value.weight %}weight: parseFloat({{ form.vars.value.weight }}),{% 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 %} | |||
} | |||
</script> | |||
<div v-show="currentSection == 'general'" class="panel panel-default"> | |||
<div class="row"> | |||
<div class="field-group col-8"> | |||
<fieldset> | |||
<legend>Général</legend> | |||
<div class="row"> | |||
<div class="col-12"> | |||
{{ form_row(form.supplier) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.title, {"attr" : {"v-model" : "title"}}) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.image) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.description) }} | |||
</div> | |||
</div> | |||
</fieldset> | |||
</div> | |||
<div class="field-group col-4" id="product-categories"> | |||
<fieldset> | |||
<legend>Catégories</legend> | |||
<div class="row"> | |||
{% for category in categories %} | |||
{% set child = 'category_' ~ category.id %} | |||
{{ form_row(attribute(form.productCategories, child)) }} | |||
{% for children in category.childrens %} | |||
<div class="children"> | |||
{% set child = 'category_children_' ~ children.id %} | |||
{{ form_row(attribute(form.productCategories, child), {attrs: {class: 'test'}}) }} | |||
</div> | |||
{% endfor %} | |||
{% endfor %} | |||
</div> | |||
</fieldset> | |||
</div> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'price'" class="panel panel-default"> | |||
<div class="row" id="lc-app-unit"> | |||
<div class="field-group col-6"> | |||
<fieldset> | |||
<legend>Prix</legend> | |||
<product-unit-price ref="productUnitPrice" inline-template key-form="productfamily"> | |||
<div class="row"> | |||
<div class="col-10"> | |||
{{ form_row(form.taxRate, {'attr': {'v-model':'taxRate'}}) }} | |||
</div> | |||
<div class="col-10"> | |||
{{ form_row(form.unit, {"attr":{'v-model': 'unit'}}) }} | |||
</div> | |||
<div class="col-10"> | |||
<div v-if="unit == 'piece'" class="form-group field-weight"> | |||
{{ form_label(form.weight) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.weight, {'attr' : {'v-model': 'weight'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">g</span> | |||
</div> | |||
</div> | |||
{{ form_help(form.weight) }} | |||
</div> | |||
</div> | |||
<div v-else class="form-group field-step"> | |||
{{ form_label(form.step) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.step, {'attr' : {'v-model': 'step'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">${ unit }</span> | |||
</div> | |||
</div> | |||
{{ form_help(form.step) }} | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-10"> | |||
<div class="form-group field-price"> | |||
{{ form_label(form.price) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.price, {'attr' : {'v-model': 'price', '@change' : 'changePriceWithTax'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ HT / ${ getUnitReference() }</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-10"> | |||
<div class="form-group field-price"> | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.priceWithTax, {'attr' : {'v-model': 'priceWithTax', '@change' : 'changePrice'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ TTC / ${ getUnitReference() }</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</product-unit-price> | |||
</fieldset> | |||
</div> | |||
<div class="field-group col-6"> | |||
<fieldset> | |||
<legend>Déclinaisons</legend> | |||
{{ form_row(form.activeProducts, {"attr": {"v-model": 'activeProducts'}}) }} | |||
</fieldset> | |||
<fieldset> | |||
<legend>Stock</legend> | |||
<div class="row"> | |||
<div class="col-12"> | |||
{{ form_label(form.behaviorCountStock) }} | |||
{% for field in form.behaviorCountStock %} | |||
{% if field.vars.value == "by-product" %} | |||
<div v-if="activeProducts == true"> | |||
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorCountStock'}}) }} | |||
</div> | |||
{% else %} | |||
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorCountStock'}}) }} | |||
{% endif %} | |||
{% endfor %} | |||
<div v-show="behaviorCountStock == 'by-product-family'" class="form-group"> | |||
{{ form_label(form.availableQuantity) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.availableQuantity) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">${ getUnitReference() }</span> | |||
</div> | |||
</div> | |||
{{ form_help(form.availableQuantity) }} | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</fieldset> | |||
</div> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'products'" class="panel panel-default"> | |||
{% include '@LcShop/backend/default/product_macro.html.twig' %} | |||
</div> | |||
</div> | |||
</div> | |||
{{ form_end(form) }} | |||
@@ -39,14 +39,14 @@ | |||
{% endif %} | |||
{% if has_input_groups %}</div>{% endif %} | |||
{% if _field_type in ['datetime', 'datetime_immutable', 'date', 'date_immutable', 'dateinterval', 'time', 'time_immutable', 'birthday'] and easyadmin.field.nullable|default(false) %} | |||
{#{% if _field_type in ['datetime', 'datetime_immutable', 'date', 'date_immutable', 'dateinterval', 'time', 'time_immutable', 'birthday'] and easyadmin.field.nullable|default(false) %} | |||
<div class="nullable-control"> | |||
<label> | |||
<input type="checkbox" {% if data is null %}checked="checked"{% endif %}> | |||
{{ 'label.nullable_field'|trans({}, 'EasyAdminBundle') }} | |||
</label> | |||
</div> | |||
{% endif %} | |||
{% endif %}#} | |||
{% if easyadmin.field.help|default(form.vars.help) != '' %} | |||
<small class="form-help">{{ easyadmin.field.help|default(form.vars.help)|trans(domain = form.vars.translation_domain)|raw }}</small> |
@@ -0,0 +1,219 @@ | |||
{% 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"> </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 %} | |||
@@ -1,5 +1,5 @@ | |||
{% extends '@EasyAdmin/default/edit.html.twig' %} | |||
{% block entity_form %} | |||
{% include '@LcShop/backend/default/productfamily_form.html.twig' %} | |||
{% include '@LcShop/backend/productfamily/form.html.twig' %} | |||
{% endblock entity_form %} |
@@ -0,0 +1,85 @@ | |||
{{ form_start(form, {"attr": {'@change' : 'formUpdated'}}) }} | |||
<div class="lc-vue-js-container" id="lc-product-family-edit"> | |||
<div id="nav-params"> | |||
<button type="button" v-for="section in sectionsArray" | |||
v-if="(section.name == 'products' && activeProducts == true) || (section.name != 'products')" | |||
:class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')" | |||
@click="changeSection(section)"> | |||
${ section.nameDisplay } | |||
<span v-if="section.name == 'products'">({{ form.products|length }})</span> | |||
<span class="glyphicon glyphicon-triangle-bottom"></span> | |||
</button> | |||
</div> | |||
<div class="form"> | |||
<script>// rendered by server | |||
window.mixinUnitValues = { | |||
unitArray: {{ getUnitsList()|json_encode|raw }} | |||
} | |||
window.appProductFamilyValues = { | |||
{% if form.vars.value.title %}title: "{{ form.vars.value.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 %} | |||
}; | |||
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 form.supplierTaxRate.vars.value != 0 %}differentSupplierTaxRate: true{% endif %} | |||
} | |||
</script> | |||
<div v-show="currentSection == 'general'" class="panel panel-default"> | |||
{% include '@LcShop/backend/productfamily/panel_general.html.twig' %} | |||
</div> | |||
<div v-show="currentSection == 'price'" class="panel panel-default"> | |||
{% 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 == 'note'" class="panel panel-default"> | |||
<div class="row" id="lc-app-unit"> | |||
<div class="field-group col-12"> | |||
<fieldset> | |||
<legend>Note interne</legend> | |||
{{ form_row(form.note) }} | |||
</fieldset> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="row"> | |||
<div class="field-group col-12"> | |||
<fieldset> | |||
<legend>Note interne</legend> | |||
{{ entity.note|raw }} | |||
</fieldset> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
{{ form_end(form) }} | |||
@@ -1,5 +1,5 @@ | |||
{% extends '@EasyAdmin/default/new.html.twig' %} | |||
{% block entity_form %} | |||
{% include '@LcShop/backend/default/productfamily_form.html.twig' %} | |||
{% include '@LcShop/backend/productfamily/form.html.twig' %} | |||
{% endblock entity_form %} |
@@ -0,0 +1,51 @@ | |||
<div class="row"> | |||
<div class="field-group col-8"> | |||
<fieldset> | |||
<legend>Général</legend> | |||
<div class="row"> | |||
<div class="col-12"> | |||
{{ form_row(form.supplier) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.title, {"attr" : {"v-model" : "title"}}) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.subTitle) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.image) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.description) }} | |||
</div> | |||
</div> | |||
</fieldset> | |||
</div> | |||
<div class="field-group col-4" id="product-categories"> | |||
<fieldset> | |||
<legend>Déclinaisons</legend> | |||
{{ form_row(form.activeProducts, {"attr": {"v-model": 'activeProducts'}}) }} | |||
<div v-show="activeProducts == true"> | |||
{{ form_row(form.productsType) }} | |||
</div> | |||
</fieldset> | |||
<fieldset> | |||
<legend>Catégories</legend> | |||
<div class="row"> | |||
{% for category in categories %} | |||
{% set child = 'category_' ~ category.id %} | |||
{{ form_row(attribute(form.productCategories, child)) }} | |||
{% for children in category.childrens %} | |||
<div class="children"> | |||
{% set child = 'category_children_' ~ children.id %} | |||
{{ form_row(attribute(form.productCategories, child), {attrs: {class: 'test'}}) }} | |||
</div> | |||
{% endfor %} | |||
{% endfor %} | |||
</div> | |||
</fieldset> | |||
</div> | |||
</div> |
@@ -0,0 +1,126 @@ | |||
<product-unit-price ref="productUnitPrice" inline-template key-form="productfamily"> | |||
<div class="row"> | |||
<div class="field-group col-8"> | |||
<fieldset> | |||
<legend>Prix</legend> | |||
<div class="form-group field-price"> | |||
<div class="col-12"> | |||
{{ form_label(form.buyingPrice) }} | |||
</div> | |||
<div class="col-6"> | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.buyingPrice, {'attr' : {'v-model': 'buyingPrice', '@change' : 'changeBuyingPriceWithTax'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ HT {#${ unitReference }#}</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-6"> | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.buyingPriceWithTax, {'attr' : {'v-model': 'buyingPriceWithTax', '@change' : 'changeBuyingPrice'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ TTC</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-10 align-content-center"> | |||
{{ form_row(form.multiplyingFactor, {'attr': {'v-model':'multiplyingFactor', '@change' : 'updateMultiplyingFactor'}}) }} | |||
</div> | |||
<div class="form-group field-price"> | |||
<div class="col-12"> | |||
{{ form_label(form.price) }} | |||
</div> | |||
<div class="col-6"> | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.price, {'attr' : {'v-model': 'price', '@change' : 'changePriceWithTax'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ HT</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-6"> | |||
<div class="input-group"> | |||
{{ form_widget(form.priceWithTax, {'attr' : {'v-model': 'priceWithTax', '@change' : 'changePrice'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ TTC</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="form-group field-price" v-show="unit != 'piece'"> | |||
<div class="col-12"> | |||
{{ form_label(form.priceByRefUnit) }} | |||
</div> | |||
<div class="col-6"> | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.priceByRefUnit, {'attr' : {'v-model': 'priceByRefUnit', 'readonly':'readonly'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ HT / ${ unitReference }</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="col-6"> | |||
<div class="input-group"> | |||
{{ form_widget(form.priceByRefUnitWithTax, {'attr' : {'v-model': 'priceByRefUnitWithTax','readonly':'readonly'}}) }} | |||
<div class="input-group-append"> | |||
<span class="input-group-text">€ TTC / ${ unitReference }</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</fieldset> | |||
</div> | |||
<div class="field-group col-4"> | |||
<fieldset> | |||
<legend>TVA</legend> | |||
<div class="col-12"> | |||
{{ form_row(form.taxRate, {'attr': {'v-model':'taxRate'}}) }} | |||
</div> | |||
<div class="col-12"> | |||
{{ form_row(form.differentSupplierTaxRate, {'attr': {'v-model':'differentSupplierTaxRate'}}) }} | |||
</div> | |||
<div class="col-12" v-show="differentSupplierTaxRate == true"> | |||
{{ form_row(form.supplierTaxRate, {'attr': {'v-model':'supplierTaxRate'}}) }} | |||
</div> | |||
</fieldset> | |||
<fieldset> | |||
<legend>Unité et quantité</legend> | |||
<div class="col-12"> | |||
{{ form_row(form.unit, {"attr":{'v-model': 'unit', '@change': "priceByRefUnitUpdate"}}) }} | |||
</div> | |||
<div class="col-12"> | |||
<div class="form-group field-weight"> | |||
{{ form_label(form.quantity) }} | |||
<div class="form-widget"> | |||
<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> | |||
</div> | |||
</div> | |||
{{ form_help(form.quantity) }} | |||
</div> | |||
</div> | |||
</div> | |||
</fieldset> | |||
</div> | |||
</div> | |||
</product-unit-price> |
@@ -0,0 +1,280 @@ | |||
{% macro printProductRow(product) %} | |||
<tr class="lc-draggable"> | |||
<td><i class="fa fa-fw fa-sort"></i></td> | |||
<td colspan="3" class="title" v-on:click="titleInherited = true"> | |||
<div v-show="titleInherited == false"> | |||
<div v-if="title" class="blop"> | |||
{% verbatim %}{{ title }}{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.title }}{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="titleInherited == true"> | |||
{{ form_widget(product.title, {'attr' : {'v-model' : 'title', 'v-on:focusout': 'titleInherited = false'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="1" class="quantity" v-on:click="quantityInherited = true"> | |||
<div v-show="quantityInherited == false"> | |||
<div v-if="quantity" class="blop"> | |||
{% verbatim %}{{ quantity }}{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.quantity }}{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="quantityInherited == true"> | |||
{{ form_widget(product.quantity, {'attr' : {'v-model' : 'quantity', 'v-on:focusout': 'quantityInherited = false'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="2" class="unit" v-on:click="unitInherited = true"> | |||
<div v-show="unitInherited == false"> | |||
<div v-if="unit" class="blop"> | |||
{% verbatim %}{{ unit }}{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.unit }}{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="unitInherited == true"> | |||
{{ form_widget(product.unit, {'attr' : {'v-model' : 'unit', 'v-on:focusout': 'unitInherited = false'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="2" class="buyingPrice" v-on:click="buyingPriceInherited = true"> | |||
<div v-show="buyingPriceInherited == false"> | |||
<div v-if="buyingPrice" class="blop"> | |||
{% verbatim %}{{ buyingPrice }}€{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.buyingPrice }}€{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="buyingPriceInherited == true"> | |||
{{ form_widget(product.buyingPrice, {'attr' : {'v-model' : 'buyingPrice', 'v-on:focusout': 'buyingPriceInherited = false', '@change' : 'changeBuyingPriceWithTax'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="2" class="buyingPriceWithTax" v-on:click="buyingPriceWithTaxInherited = true"> | |||
<div v-show="buyingPriceWithTaxInherited == false"> | |||
<div v-if="buyingPriceWithTax" class="blop"> | |||
{% verbatim %}{{ buyingPriceWithTax }}€{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.buyingPriceWithTax }}€{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="buyingPriceWithTaxInherited == true"> | |||
{{ form_widget(product.buyingPriceWithTax, {'attr' : {'v-model' : 'buyingPriceWithTax', 'v-on:focusout': 'buyingPriceWithTaxInherited = false' , '@change' : 'changeBuyingPrice'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="2" class="multiplyingFactor" v-on:click="multiplyingFactorInherited = true"> | |||
<div v-show="multiplyingFactorInherited == false"> | |||
<div v-if="multiplyingFactor"> | |||
{% verbatim %}{{ multiplyingFactor }}{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.multiplyingFactor }}{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="multiplyingFactorInherited == true"> | |||
{{ form_widget(product.multiplyingFactor, {'attr' : {'v-model' : 'multiplyingFactor', 'v-on:focusout': 'multiplyingFactorInherited = false', '@change' : 'updateMultiplyingFactor'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="2" class="price" v-on:click="priceInherited = true"> | |||
<div v-show="priceInherited == false"> | |||
<div v-if="price" > | |||
{% verbatim %}{{ price }}€{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.price }}€{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="priceInherited == true"> | |||
{{ form_widget(product.price, {'attr' : {'v-model' : 'price', 'v-on:focusout': 'priceInherited = false', '@change' : 'changePriceWithTax'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="2" class="priceWithTax" v-on:click="priceWithTaxInherited = true"> | |||
<div v-show="priceWithTaxInherited == false"> | |||
<div v-if="priceWithTax"> | |||
{% verbatim %}{{ priceWithTax }}€{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.priceWithTax }}€{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="priceWithTaxInherited == true"> | |||
{{ form_widget(product.priceWithTax, {'attr' : {'v-model' : 'priceWithTax', 'v-on:focusout': 'priceWithTaxInherited = false', '@change' : 'changePrice'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="2" class="priceByRefUnit"> | |||
<div v-if="priceByRefUnit"> | |||
{% verbatim %}{{ priceByRefUnit }}€{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.priceByRefUnit }}€{% endverbatim %} | |||
</div> | |||
</td> | |||
<td colspan="2" class="priceByRefUnit priceByRefUnitWithTax"> | |||
<div v-if="priceByRefUnitWithTax"> | |||
{% verbatim %}{{ priceByRefUnitWithTax }}€{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.priceByRefUnitWithTax }}€{% endverbatim %} | |||
</div> | |||
</td> | |||
<td class="stock availableQuantity " v-on:click="availableQuantityInherited = true"> | |||
<div v-show="availableQuantityInherited == false"> | |||
<div v-if="availableQuantity"> | |||
{% verbatim %}{{ availableQuantity }} {{ unitReference }}{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.availableQuantity }} {{ unitReference }}{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="availableQuantityInherited == true"> | |||
{{ form_widget(product.availableQuantity, {'attr' : {'v-model' : 'availableQuantity', 'v-on:focusout': 'availableQuantityInherited = false'}}) }} | |||
</div> | |||
</td> | |||
<td class="stock availableQuantityDefault" v-on:click="availableQuantityDefaultInherited = true"> | |||
<div v-show="availableQuantityDefaultInherited == false"> | |||
<div v-if="availableQuantityDefault"> | |||
{% verbatim %}{{ availableQuantityDefault }}{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ productFamily.availableQuantityDefault }}{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="availableQuantityDefaultInherited == true"> | |||
{{ form_widget(product.availableQuantityDefault, {'attr' : {'v-model' : 'availableQuantityDefault', 'v-on:focusout': 'availableQuantityDefaultInherited = false'}}) }} | |||
</div> | |||
</td> | |||
<td colspan="2" class="expirationDate" v-on:click="expirationDateInherited = true"> | |||
<div v-show="expirationDateInherited == false"> | |||
<div v-if="expirationDate"> | |||
{% verbatim %}{{ expirationDateFormated }}{% endverbatim %} | |||
</div> | |||
<div v-else class="inherited"> | |||
{% verbatim %}{{ expirationDateFormated }}{% endverbatim %} | |||
</div> | |||
</div> | |||
<div v-show="expirationDateInherited == true"> | |||
{{ form_widget(product.expirationDate, {'attr' : {'v-model' : 'expirationDate', 'v-on:focusout': 'expirationDateInherited = false'}}) }} | |||
</div> | |||
</td> | |||
<td> | |||
<button type="button" class="btn-remove-product btn btn-default" @click="deleteProductForm()"> | |||
<i class="fa fa-trash"></i> | |||
</button> | |||
{{ form_widget(product.position, {'attr' : {'class': "field-position"}}) }} | |||
</td> | |||
</tr> | |||
{% endmacro %} | |||
{% import _self as formMacros %} | |||
<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> | |||
<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"> | |||
<template v-for="(formProduct, key) in formProductArray"> | |||
<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> | |||
<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.quantity %}quantity: "{{ product.vars.value.quantity }}",{% endif %} | |||
{% if product.vars.value.unit %}unit: "{{ product.vars.value.unit }}",{% endif %} | |||
{% if product.vars.value.buyingPrice %}buyingPrice: "{{ product.vars.value.buyingPrice }}",{% 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 %} | |||
{% if product.vars.value.availableQuantityDefault %}availableQuantityDefault: parseInt({{ product.vars.value.availableQuantityDefault }}){% endif %} | |||
{% if product.vars.value.expirationDate %}expirationDate: {{ product.vars.value.expirationDate }}{% endif %} | |||
}; | |||
jQuery(window).on('load', function () { | |||
var formProduct = '{{ formMacros.printProductRow(product)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; | |||
appProductFamily.formProductArray.push(formProduct); | |||
appProductFamily.indexFormProduct++; | |||
}); | |||
</script> | |||
{% endfor %} | |||
{% do form.products.setRendered %} | |||
@@ -0,0 +1,39 @@ | |||
<div class="row"> | |||
<div class="field-group col-7"> | |||
<fieldset> | |||
<legend>Caractéristiques</legend> | |||
<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 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 class="row"> | |||
<div class="col"> | |||
{{ form_row(form.largeVolume) }} | |||
</div> | |||
</div> | |||
</fieldset> | |||
</div> | |||
<div class="field-group col-5"> | |||
<fieldset> | |||
<legend>Date d'expiration</legend> | |||
<div class="row"> | |||
<div class="col"> | |||
{{ form_row(form.expirationDate, {'attr': {'v-model':'expirationDate'}}) }} | |||
</div> | |||
</div> | |||
</fieldset> | |||
</div> | |||
</div> |
@@ -0,0 +1,47 @@ | |||
<div class="row"> | |||
<div class="field-group col-12"> | |||
<fieldset> | |||
<legend>Stock</legend> | |||
<div class="row"> | |||
<div class="col"> | |||
{{ form_label(form.behaviorCountStock) }} | |||
{% for field in form.behaviorCountStock %} | |||
{% if field.vars.value == "by-product" %} | |||
<div v-if="activeProducts == true"> | |||
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorCountStock'}}) }} | |||
</div> | |||
{% else %} | |||
{{ form_widget(field, {"attr" : {"v-model" : 'behaviorCountStock'}}) }} | |||
{% endif %} | |||
{% endfor %} | |||
</div> | |||
<div class="col"> | |||
<div v-show="behaviorCountStock == 'by-product-family' || behaviorCountStock == 'by-quantity'" | |||
class="form-group"> | |||
{{ form_label(form.availableQuantity) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.availableQuantity) }} | |||
<div v-show="behaviorCountStock == 'by-quantity'" class="input-group-append"> | |||
<span class="input-group-text">${ getUnitReference() }</span> | |||
</div> | |||
</div> | |||
{{ form_help(form.availableQuantity) }} | |||
</div> | |||
{{ form_label(form.availableQuantityDefault) }} | |||
<div class="form-widget"> | |||
<div class="input-group"> | |||
{{ form_widget(form.availableQuantityDefault) }} | |||
<div v-show="behaviorCountStock == 'by-quantity'" class="input-group-append"> | |||
<span class="input-group-text">${ getUnitReference() }</span> | |||
</div> | |||
</div> | |||
{{ form_help(form.availableQuantityDefault) }} | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</fieldset> | |||
</div> | |||
</div> |
@@ -4,6 +4,57 @@ namespace Lc\ShopBundle\Services; | |||
class Utils | |||
{ | |||
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 static function getDayByNumber($number) | |||
{ | |||
$daysArray = [ | |||
@@ -23,4 +74,17 @@ class Utils | |||
return '' ; | |||
} | |||
public function getUnitsListFormatedForType(){ | |||
foreach ($this->unitsArray as $unit=>$unitInfo){ | |||
$choices[$unitInfo['wording_unit']] = $unit; | |||
}; | |||
return $choices; | |||
} | |||
public function getUnitsList(){ | |||
return $this->unitsArray; | |||
} | |||
} |
@@ -20,6 +20,7 @@ class BridgeTwigExtension extends AbstractExtension | |||
{ | |||
return array( | |||
new TwigFunction('getDayByNumber', [$this, 'getDayByNumber']), | |||
new TwigFunction('getUnitsList', [$this, 'getUnitsList']), | |||
); | |||
} | |||
@@ -34,4 +35,9 @@ class BridgeTwigExtension extends AbstractExtension | |||
return $this->utils->getDayByNumber($number) ; | |||
} | |||
public function getUnitsList() | |||
{ | |||
return $this->utils->getUnitsList() ; | |||
} | |||
} |