'label' => 'TVA', | 'label' => 'TVA', | ||||
'choices' => $choicesTaxRate, | 'choices' => $choicesTaxRate, | ||||
'mapped' => false, | 'mapped' => false, | ||||
'data'=> 0, | |||||
'choice_attr' => function ($choice, $key, $value) { | 'choice_attr' => function ($choice, $key, $value) { | ||||
return ['data-tax-rate-value' => $this->choicesTaxRateParam[$choice]]; | return ['data-tax-rate-value' => $this->choicesTaxRateParam[$choice]]; | ||||
}, | }, | ||||
$formBuilder->add('behaviorCountStock', ChoiceType::class, array( | $formBuilder->add('behaviorCountStock', ChoiceType::class, array( | ||||
'label' => 'Stock', | 'label' => 'Stock', | ||||
'empty_data' => 'by-product-family', | |||||
'choices' => array( | 'choices' => array( | ||||
'Gèrer le stock par déclinaison' => 'by-product', | |||||
'Gèrer le stock par produit' => 'by-product-family' | |||||
'Gèrer le stock par produit' => 'by-product-family', | |||||
'Gèrer le stock par déclinaison' => 'by-product' | |||||
), | ), | ||||
'multiple' => false, | 'multiple' => false, | ||||
'expanded' => true | 'expanded' => true | ||||
protected function processProducts($entity) | protected function processProducts($entity) | ||||
{ | { | ||||
//si il existe un et un seul produit pour ce product family n'ajoute rien supprime rien | |||||
if(count($entity->getProducts()) == 0) { | if(count($entity->getProducts()) == 0) { | ||||
$product = new Product(); | $product = new Product(); | ||||
$product->setTitle($entity->getTitle()) ; | |||||
$product->setCreatedBy($this->getUser()) ; | $product->setCreatedBy($this->getUser()) ; | ||||
$product->setUpdatedBy($this->getUser()) ; | $product->setUpdatedBy($this->getUser()) ; | ||||
$product->setProductFamily($entity) ; | $product->setProductFamily($entity) ; | ||||
$entity->addProduct($product) ; | $entity->addProduct($product) ; | ||||
} | } | ||||
else { | else { | ||||
foreach($entity->getProducts() as $product) { | foreach($entity->getProducts() as $product) { | ||||
$product->setProductFamily($entity) ; | $product->setProductFamily($entity) ; | ||||
$product->setCreatedBy($this->getUser()) ; | $product->setCreatedBy($this->getUser()) ; | ||||
$product->setUpdatedBy($this->getUser()) ; | $product->setUpdatedBy($this->getUser()) ; | ||||
$this->em->persist($product); | |||||
$entity->addProduct($product) ; | |||||
// die('ncici'); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
$editForm = $this->executeDynamicMethod('create<EntityName>EditForm', [$entity, $fields]); | $editForm = $this->executeDynamicMethod('create<EntityName>EditForm', [$entity, $fields]); | ||||
$deleteForm = $this->createDeleteForm($this->entity['name'], $id); | $deleteForm = $this->createDeleteForm($this->entity['name'], $id); | ||||
$sortableProductsField = array(); | |||||
foreach($editForm->get('products')->getData() as $k=>$product){ | |||||
$sortableProductsField[$product->getPosition()] = $k; | |||||
} | |||||
ksort($sortableProductsField); | |||||
$editForm->handleRequest($this->request); | $editForm->handleRequest($this->request); | ||||
if ($editForm->isSubmitted() && $editForm->isValid()) { | if ($editForm->isSubmitted() && $editForm->isValid()) { | ||||
'entity_fields' => $fields, | 'entity_fields' => $fields, | ||||
'entity' => $entity, | 'entity' => $entity, | ||||
'delete_form' => $deleteForm->createView(), | 'delete_form' => $deleteForm->createView(), | ||||
'categories' => $categories | |||||
'categories' => $categories, | |||||
'sortableProductsField' => $sortableProductsField | |||||
]; | ]; | ||||
return $this->executeDynamicMethod('render<EntityName>Template', ['edit', $this->entity['templates']['edit'], $parameters]); | return $this->executeDynamicMethod('render<EntityName>Template', ['edit', $this->entity['templates']['edit'], $parameters]); | ||||
$this->dispatch(EasyAdminEvents::POST_NEW, [ | $this->dispatch(EasyAdminEvents::POST_NEW, [ | ||||
'entity_fields' => $fields, | 'entity_fields' => $fields, | ||||
'form' => $newForm, | 'form' => $newForm, | ||||
'entity' => $entity, | |||||
'entity' => $entity | |||||
]); | ]); | ||||
'entity_fields' => $fields, | 'entity_fields' => $fields, | ||||
'entity' => $entity, | 'entity' => $entity, | ||||
'categories' => $categories, | 'categories' => $categories, | ||||
'sortableProductsField' => array() | |||||
]; | ]; | ||||
return $this->executeDynamicMethod('render<EntityName>Template', ['new', $this->entity['templates']['new'], $parameters]); | return $this->executeDynamicMethod('render<EntityName>Template', ['new', $this->entity['templates']['new'], $parameters]); |
use Lc\ShopBundle\Context\ProductFamilyInterface; | use Lc\ShopBundle\Context\ProductFamilyInterface; | ||||
use Lc\ShopBundle\Context\ProductInterface; | use Lc\ShopBundle\Context\ProductInterface; | ||||
use Lc\ShopBundle\Context\TaxRateInterface; | use Lc\ShopBundle\Context\TaxRateInterface; | ||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | |||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType; | use Symfony\Component\Form\Extension\Core\Type\HiddenType; | ||||
use Symfony\Component\Form\Extension\Core\Type\NumberType; | use Symfony\Component\Form\Extension\Core\Type\NumberType; | ||||
use function PHPSTORM_META\type; | use function PHPSTORM_META\type; | ||||
use Symfony\Component\Form\AbstractType; | use Symfony\Component\Form\AbstractType; | ||||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||||
use Symfony\Component\Form\FormBuilderInterface; | use Symfony\Component\Form\FormBuilderInterface; | ||||
use Symfony\Component\OptionsResolver\OptionsResolver; | use Symfony\Component\OptionsResolver\OptionsResolver; | ||||
public function buildForm(FormBuilderInterface $builder, array $options) | public function buildForm(FormBuilderInterface $builder, array $options) | ||||
{ | { | ||||
$builder->add('title') ; | |||||
$builder->add('titleInherited', CheckboxType::class, array( | |||||
'mapped'=>false, | |||||
'required'=>false | |||||
)); | |||||
$builder->add('title', TextType::class, array( | |||||
"required" => false | |||||
)) ; | |||||
$builder->add('unitInherited', CheckboxType::class, array( | |||||
'mapped'=>false, | |||||
'required'=>false | |||||
)); | |||||
$builder->add('unit', ChoiceType::class, array( | $builder->add('unit', ChoiceType::class, array( | ||||
'label' => 'Unité', | 'label' => 'Unité', | ||||
"required" => false, | |||||
'choices' => array( | 'choices' => array( | ||||
'pièce' => 'piece', | 'pièce' => 'piece', | ||||
'g' => 'g', | 'g' => 'g', | ||||
), | ), | ||||
)); | )); | ||||
$builder->add('weightInherited', CheckboxType::class, array( | |||||
'mapped'=>false, | |||||
'required'=>false | |||||
)); | |||||
$builder->add('weight', NumberType::class, array( | $builder->add('weight', NumberType::class, array( | ||||
'label' => 'Poids', | 'label' => 'Poids', | ||||
"required" => false, | |||||
'attr' => [ | 'attr' => [ | ||||
'append_html' => 'g' | 'append_html' => 'g' | ||||
] | ] | ||||
)); | )); | ||||
$builder->add('stepInherited', CheckboxType::class, array( | |||||
'mapped'=>false, | |||||
'required'=>false | |||||
)); | |||||
$builder->add('step', NumberType::class, array( | $builder->add('step', NumberType::class, array( | ||||
'label' => 'Pas', | 'label' => 'Pas', | ||||
"required" => false, | |||||
'help' => 'Quantité à incrémenter / décrémenter lors des mouvements de quantité', | 'help' => 'Quantité à incrémenter / décrémenter lors des mouvements de quantité', | ||||
)); | )); | ||||
$builder->add('priceInherited', CheckboxType::class, array( | |||||
'mapped'=>false, | |||||
'required'=>false | |||||
)); | |||||
$builder->add('price', NumberType::class, array( | $builder->add('price', NumberType::class, array( | ||||
'label' => 'Prix', | 'label' => 'Prix', | ||||
"required" => false | |||||
)); | )); | ||||
$builder->add('priceWithTax', NumberType::class, array( | $builder->add('priceWithTax', NumberType::class, array( | ||||
'required' => false, | 'required' => false, | ||||
)); | )); | ||||
$builder->add('position', HiddenType::class); | |||||
} | } | ||||
public function configureOptions(OptionsResolver $resolver) | public function configureOptions(OptionsResolver $resolver) |
namespace Lc\ShopBundle\Model; | namespace Lc\ShopBundle\Model; | ||||
use Doctrine\ORM\Mapping as ORM; | use Doctrine\ORM\Mapping as ORM; | ||||
use Lc\ShopBundle\Context\SortableInterface; | |||||
/** | /** | ||||
* @ORM\MappedSuperclass() | * @ORM\MappedSuperclass() | ||||
*/ | */ | ||||
abstract class Product extends AbstractEntity | |||||
abstract class Product extends AbstractEntity implements SortableInterface | |||||
{ | { | ||||
use SortableTrait; | |||||
/** | /** | ||||
* @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface", inversedBy="products") | * @ORM\ManyToOne(targetEntity="Lc\ShopBundle\Context\ProductFamilyInterface", inversedBy="products") | ||||
* @ORM\JoinColumn(nullable=false) | * @ORM\JoinColumn(nullable=false) | ||||
protected $productFamily; | protected $productFamily; | ||||
/** | /** | ||||
* @ORM\Column(type="string", length=255) | |||||
* @ORM\Column(type="string", length=255, nullable=true) | |||||
*/ | */ | ||||
protected $title; | protected $title; | ||||
*/ | */ | ||||
protected $behaviorCountStock; | protected $behaviorCountStock; | ||||
/** | |||||
* @ORM\Column(type="boolean") | |||||
*/ | |||||
protected $activeProducts; | |||||
public function __construct() | public function __construct() | ||||
{ | { | ||||
$this->productCategories = new ArrayCollection(); | $this->productCategories = new ArrayCollection(); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getActiveProducts(): ?bool | |||||
{ | |||||
return $this->activeProducts; | |||||
} | |||||
public function setActiveProducts(bool $activeProducts): self | |||||
{ | |||||
$this->activeProducts = $activeProducts; | |||||
return $this; | |||||
} | |||||
} | } |
- '/bundles/lcshop/js/backend/script/setup-ckfinder.js' | - '/bundles/lcshop/js/backend/script/setup-ckfinder.js' | ||||
- '/bundles/lcshop/js/backend/script/utils.js' | - '/bundles/lcshop/js/backend/script/utils.js' | ||||
- '/bundles/lcshop/js/backend/script/custom.js' | - '/bundles/lcshop/js/backend/script/custom.js' | ||||
- '/bundles/lcshop/js/backend/script/vueapp.js' | |||||
- '/bundles/lcshop/js/backend/script/vuejs-mixins.js' | |||||
- '/bundles/lcshop/js/backend/script/vuejs-product-family.js' | |||||
css: | css: | ||||
- '/bundles/lcshop/css/backend/custom.css' | - '/bundles/lcshop/css/backend/custom.css' | ||||
text-align: right ; | text-align: right ; | ||||
} | } | ||||
.new-productfamily .btn-remove-product, | |||||
.edit-productfamily .btn-remove-product { | |||||
position: absolute ; | |||||
top: 30px ; | |||||
right: 20px ; | |||||
} | |||||
/* Product */ | |||||
.product-form-modal{display: none;} | |||||
.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{} |
custom_switch_merchants(); | custom_switch_merchants(); | ||||
initLcSortableList(); | initLcSortableList(); | ||||
initLcCkEditor(); | initLcCkEditor(); | ||||
initLcSortableProductsList(); | |||||
initLcSortableList(); | |||||
}); | }); | ||||
function custom_switch_merchants() { | function custom_switch_merchants() { | ||||
}); | }); | ||||
} | } | ||||
function initLcSortableProductsList(){ | |||||
$('.lc-sortable-products tbody').sortable({ | |||||
placeholder: "ui-state-highlight" | |||||
}); | |||||
$('.lc-sortable-products tbody').on("sortupdate", function (event, ui) { | |||||
updateSortableProducts(); | |||||
}); | |||||
} | |||||
function updateSortableProducts(){ | |||||
$('.lc-sortable-products tr.lc-draggable').each(function (index, li) { | |||||
$(li).find('.field-position').val(index); | |||||
}); | |||||
} | |||||
function initLcSortableList() { | function initLcSortableList() { | ||||
$('.lc-sortable tbody').sortable({ | $('.lc-sortable tbody').sortable({ |
// Reference array sent to dynamic staticRenderFns | |||||
var staticRenderFns = []; | |||||
Vue.component('component-unit', { | |||||
props: ['template', 'keyForm', 'taxRateValue'], | |||||
data() { | |||||
return { | |||||
templateRender: null, | |||||
unit: null, | |||||
price: null, | |||||
priceWithTax: null | |||||
}; | |||||
}, | |||||
mounted: function() { | |||||
this.unit = $('#value-unit-'+this.keyForm).val() ; | |||||
this.price = parseFloat($('#value-price-'+this.keyForm).val()).toFixed(3) ; | |||||
this.priceUpdate('priceWithTax') ; | |||||
}, | |||||
methods: { | |||||
getUnitReference: function () { | |||||
if (this.unit == 'g') { | |||||
return 'kg'; | |||||
} else if (this.unit == 'ml') { | |||||
return 'L'; | |||||
} else { | |||||
return this.unit; | |||||
} | |||||
}, | |||||
changeTaxRate: function() { | |||||
this.$emit('tax-rate-change') ; | |||||
this.changePriceWithTax() ; | |||||
}, | |||||
changePrice: function() { | |||||
this.priceUpdate('price') ; | |||||
}, | |||||
changePriceWithTax: function() { | |||||
this.priceUpdate('priceWithTax') ; | |||||
}, | |||||
priceUpdate: function(priceType) { | |||||
var taxRate = this.getTaxRate() ; | |||||
if(priceType == 'priceWithTax') { | |||||
this.price = parseFloat(this.price.replace(',','.')).toFixed(3) ; | |||||
this.priceWithTax = getPriceWithTax(this.price, taxRate); | |||||
} | |||||
else { | |||||
this.priceWithTax = parseFloat(this.priceWithTax.replace(',','.')).toFixed(2) ; | |||||
this.price = getPrice(this.priceWithTax, taxRate) ; | |||||
} | |||||
}, | |||||
getTaxRate: function() { | |||||
var taxRate = this.taxRateValue ; | |||||
if(this.taxRateValue == -1) { | |||||
var taxRate = $('#productfamily_taxRate').find('option:selected').data('tax-rate-value'); | |||||
if(typeof taxRate == 'undefined') { | |||||
taxRate = 0 ; | |||||
} | |||||
} | |||||
return taxRate ; | |||||
} | |||||
}, | |||||
render(h) { | |||||
if (!this.templateRender) { | |||||
return h('div', 'loading...'); | |||||
} else { // If there is a template, I'll show it | |||||
return this.templateRender(); | |||||
} | |||||
}, | |||||
watch: { | |||||
taxRateValue: function(newVal, oldVal) { | |||||
this.changePriceWithTax() ; | |||||
}, | |||||
// Every time the template prop changes, I recompile it to update the DOM | |||||
template: { | |||||
immediate: true, // makes the watcher fire on first render, too. | |||||
handler() { | |||||
if (this.template) { | |||||
var res = Vue.compile(this.template); | |||||
this.templateRender = res.render; | |||||
// staticRenderFns belong into $options, | |||||
// appearantly | |||||
this.$options.staticRenderFns = [] | |||||
// clean the cache of static elements | |||||
// this is a cache with the results from the staticRenderFns | |||||
this._staticTrees = [] | |||||
// Fill it with the new staticRenderFns | |||||
for (var i in res.staticRenderFns) { | |||||
//staticRenderFns.push(res.staticRenderFns[i]); | |||||
this.$options.staticRenderFns.push(res.staticRenderFns[i]) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
}); | |||||
appProductFamily = new Vue({ | |||||
el: '#lc-product-family-edit', | |||||
delimiters: ['${', '}'], | |||||
data: { | |||||
indexFormProduct: 0, | |||||
taxRateValue: -1, | |||||
formProductArray: [], | |||||
currentSection: 'general', | |||||
sectionsArray: [ | |||||
{ | |||||
name: 'general', | |||||
nameDisplay: 'Général' | |||||
}, | |||||
{ | |||||
name: 'price', | |||||
nameDisplay: 'Prix / stock' | |||||
}, | |||||
{ | |||||
name: 'products', | |||||
nameDisplay: 'Déclinaisons' | |||||
} | |||||
] | |||||
}, | |||||
methods: { | |||||
changeSection: function (section) { | |||||
this.currentSection = section.name; | |||||
}, | |||||
setTaxRateValue: function() { | |||||
this.taxRateValue = $('#productfamily_taxRate').find('option:selected').data('tax-rate-value') ; | |||||
}, | |||||
addFormProduct: function() { | |||||
var collectionHolder = $('ul.products'); | |||||
var prototype = collectionHolder.data('prototype'); | |||||
var newForm = prototype; | |||||
newForm = newForm.replace(/__name__/g, this.indexFormProduct); | |||||
this.formProductArray.push(newForm) ; | |||||
this.indexFormProduct ++ ; | |||||
}, | |||||
deleteFormProduct: function(key) { | |||||
this.formProductArray.splice(key, 1) ; | |||||
} | |||||
}, | |||||
mounted() { | |||||
} | |||||
}); |
let mixinPriceProduct = { | |||||
data() { | |||||
return { | |||||
price: null, | |||||
priceWithTax: null | |||||
}; | |||||
}, | |||||
methods: { | |||||
changePrice: function () { | |||||
this.priceUpdate('price'); | |||||
}, | |||||
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 ); | |||||
} | |||||
} | |||||
} | |||||
}; | |||||
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(); | |||||
},*/ | |||||
changePrice: function () { | |||||
this.priceUpdate('price'); | |||||
}, | |||||
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.taxRateValue ); | |||||
} else if (this.priceWithTax){ | |||||
this.priceWithTax = parseFloat(this.priceWithTax.replace(',', '.')).toFixed(2); | |||||
this.price = getPrice(this.priceWithTax, this.taxRateValue ); | |||||
} | |||||
}, | |||||
setTaxRateValue: function () { | |||||
this.taxRateValue = $('#productfamily_taxRate').find('option:selected').data('tax-rate-value'); | |||||
} | |||||
}, | |||||
watch:{ | |||||
taxRate: function (){ | |||||
this.setTaxRateValue(); | |||||
this.changePriceWithTax(); | |||||
} | |||||
} | |||||
}; | |||||
let mixinTemplate = { | |||||
data() { | |||||
return { | |||||
templateRender: null, | |||||
} | |||||
}, | |||||
render(h) { | |||||
if (!this.templateRender) { | |||||
return h('div', 'loading...'); | |||||
} else { // If there is a template, I'll show it | |||||
return this.templateRender(); | |||||
} | |||||
}, | |||||
watch: { | |||||
// Every time the template prop changes, I recompile it to update the DOM | |||||
template: { | |||||
immediate: true, // makes the watcher fire on first render, too. | |||||
handler() { | |||||
if (this.template) { | |||||
var res = Vue.compile(this.template); | |||||
this.templateRender = res.render; | |||||
// staticRenderFns belong into $options, | |||||
// appearantly | |||||
this.$options.staticRenderFns = [] | |||||
// clean the cache of static elements | |||||
// this is a cache with the results from the staticRenderFns | |||||
this._staticTrees = [] | |||||
// Fill it with the new staticRenderFns | |||||
for (var i in res.staticRenderFns) { | |||||
//staticRenderFns.push(res.staticRenderFns[i]); | |||||
this.$options.staticRenderFns.push(res.staticRenderFns[i]) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// Reference array sent to dynamic staticRenderFns | |||||
var staticRenderFns = []; | |||||
Vue.component('product-unit-price', { | |||||
mixins: [mixinPriceWithTaxField, mixinTemplate], | |||||
props: ['template', 'keyForm'], | |||||
data() { | |||||
return Object.assign( | |||||
{ | |||||
step: null, | |||||
unit: null, | |||||
weight: null | |||||
}, window.productUnitPriceValues); | |||||
}, | |||||
methods: { | |||||
getUnitReference: function () { | |||||
if (this.unit == 'g') { | |||||
return 'kg'; | |||||
} else if (this.unit == 'ml') { | |||||
return 'L'; | |||||
} else { | |||||
return this.unit; | |||||
} | |||||
} | |||||
}, | |||||
mounted: function () { | |||||
this.priceUpdate('priceWithTax'); | |||||
}, | |||||
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'));*/ | |||||
} | |||||
}); | |||||
Vue.component('product-form', { | |||||
mixins: [mixinPriceProduct, mixinTemplate], | |||||
props: ['template', 'keyForm', 'productFamily'], | |||||
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, | |||||
price: null, | |||||
priceInherited: null, | |||||
priceWithTax: null, | |||||
stock: null, | |||||
availableQuantity: null | |||||
}, window.productForm[this.keyForm]) | |||||
}, | |||||
mounted: function () { | |||||
//INIT VAR | |||||
updateSortableProducts(); | |||||
//METHOD | |||||
this.updateProductForm(); | |||||
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'); | |||||
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>'); | |||||
} | |||||
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') { | |||||
$('.products-collection-table').find('.stock').hide(); | |||||
} else { | |||||
$('.products-collection-table').find('.stock').show(); | |||||
$('#product-item-' + this.keyForm).find('.stock').html(this.availableQuantity + ' / '+this.getUnitReference()); | |||||
} | |||||
}, | |||||
saveProductForm: function () { | |||||
this.updateProductView(); | |||||
$('#form-product-modal-' + this.keyForm).modal('hide'); | |||||
}, | |||||
}, | |||||
watch: { | |||||
titleInherited: function (val) { | |||||
if(val)this.title = null; | |||||
}, | |||||
unitInherited: function (val) { | |||||
if(val)this.unit = null; | |||||
}, | |||||
weightInherited: function (val) { | |||||
if(val)this.weight = null; | |||||
}, | |||||
stepInherited: function (val) { | |||||
if(val)this.step = null; | |||||
}, | |||||
priceInherited: function (val) { | |||||
if(val)this.price = null; | |||||
}, | |||||
} | |||||
}); | |||||
appProductFamily = new Vue({ | |||||
el: '#lc-product-family-edit', | |||||
delimiters: ['${', '}'], | |||||
computed: { | |||||
productFamily: function () { | |||||
return { | |||||
'title': this.title, | |||||
'behaviorCountStock': this.behaviorCountStock, | |||||
'unit': this.$refs.productUnitPrice.unit, | |||||
'step': this.$refs.productUnitPrice.step, | |||||
'weight': this.$refs.productUnitPrice.weight, | |||||
'price': this.$refs.productUnitPrice.price, | |||||
'taxRate': this.$refs.productUnitPrice.taxRate, | |||||
'taxRateValue': this.$refs.productUnitPrice.taxRateValue | |||||
}; | |||||
}, | |||||
}, | |||||
data() { | |||||
return Object.assign( | |||||
{ | |||||
indexFormProduct: 0, | |||||
title: null, | |||||
activeProducts: false, | |||||
behaviorCountStock: null, | |||||
formProductArray: [], | |||||
currentSection: 'general', | |||||
sectionsArray: [ | |||||
{ | |||||
name: 'general', | |||||
nameDisplay: 'Général' | |||||
}, | |||||
{ | |||||
name: 'price', | |||||
nameDisplay: 'Prix / stock' | |||||
}, | |||||
{ | |||||
name: 'products', | |||||
nameDisplay: 'Déclinaisons' | |||||
} | |||||
] | |||||
}, window.appProductFamilyValues); | |||||
}, | |||||
methods: { | |||||
changeSection: function (section) { | |||||
this.updateChild(); | |||||
this.currentSection = section.name; | |||||
}, | |||||
addProductForm: function () { | |||||
var $collectionHolder = $('tbody.products-collection'); | |||||
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(); | |||||
}, | |||||
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++) { | |||||
this.$refs.productForm[i].updateProductForm(); | |||||
this.$refs.productForm[i].updateProductView(); | |||||
} | |||||
} | |||||
} | |||||
}, | |||||
watch: { | |||||
title: function () { | |||||
this.updateChild() | |||||
}, | |||||
} | |||||
}); |
{% 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 %} | |||||
{{ form_start(form) }} | |||||
{{ form_start(form, {"attr": {'@change' : 'formUpdated'}}) }} | |||||
<div class="lc-vue-js-container" id="lc-product-family-edit"> | <div class="lc-vue-js-container" id="lc-product-family-edit"> | ||||
<div id="nav-params"> | <div id="nav-params"> | ||||
<button type="button" v-for="section in sectionsArray" | <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')" | :class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')" | ||||
@click="changeSection(section)"> | @click="changeSection(section)"> | ||||
${ section.nameDisplay } | ${ section.nameDisplay } | ||||
</button> | </button> | ||||
</div> | </div> | ||||
<div class="form"> | <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 v-show="currentSection == 'general'" class="panel panel-default"> | ||||
<div class="row"> | <div class="row"> | ||||
<div class="field-group col-8"> | <div class="field-group col-8"> | ||||
{{ form_row(form.supplier) }} | {{ form_row(form.supplier) }} | ||||
</div> | </div> | ||||
<div class="col-12"> | <div class="col-12"> | ||||
{{ form_row(form.title) }} | |||||
{{ form_row(form.title, {"attr" : {"v-model" : "title"}}) }} | |||||
</div> | </div> | ||||
<div class="col-12"> | <div class="col-12"> | ||||
{{ form_row(form.image) }} | {{ form_row(form.image) }} | ||||
<div class="field-group col-6"> | <div class="field-group col-6"> | ||||
<fieldset> | <fieldset> | ||||
<legend>Prix</legend> | <legend>Prix</legend> | ||||
<component-unit inline-template key-form="productfamily" tax-rate-value="-1" v-on:tax-rate-change="setTaxRateValue"> | |||||
<product-unit-price ref="productUnitPrice" inline-template key-form="productfamily"> | |||||
<div class="row"> | <div class="row"> | ||||
<div class="col-10"> | <div class="col-10"> | ||||
{{ form_row(form.taxRate, {'attr': {'@change':'changeTaxRate'}}) }} | |||||
{{ form_row(form.taxRate, {'attr': {'v-model':'taxRate'}}) }} | |||||
</div> | </div> | ||||
<div class="col-10"> | <div class="col-10"> | ||||
{{ form_row(form.unit, {"attr":{'v-model': 'unit'}}) }} | {{ form_row(form.unit, {"attr":{'v-model': 'unit'}}) }} | ||||
{% if form.vars.value %} | |||||
<input type="hidden" :id="'value-unit-'+keyForm" value="{{ form.vars.value.unit }}" /> | |||||
{% endif %} | |||||
</div> | </div> | ||||
<div class="col-10"> | <div class="col-10"> | ||||
{{ form_label(form.weight) }} | {{ form_label(form.weight) }} | ||||
<div class="form-widget"> | <div class="form-widget"> | ||||
<div class="input-group"> | <div class="input-group"> | ||||
{{ form_widget(form.weight) }} | |||||
{{ form_widget(form.weight, {'attr' : {'v-model': 'weight'}}) }} | |||||
<div class="input-group-append"> | <div class="input-group-append"> | ||||
<span class="input-group-text">g</span> | <span class="input-group-text">g</span> | ||||
</div> | </div> | ||||
{{ form_label(form.step) }} | {{ form_label(form.step) }} | ||||
<div class="form-widget"> | <div class="form-widget"> | ||||
<div class="input-group"> | <div class="input-group"> | ||||
{{ form_widget(form.step) }} | |||||
{{ form_widget(form.step, {'attr' : {'v-model': 'step'}}) }} | |||||
<div class="input-group-append"> | <div class="input-group-append"> | ||||
<span class="input-group-text">${ unit }</span> | <span class="input-group-text">${ unit }</span> | ||||
</div> | </div> | ||||
<div class="input-group-append"> | <div class="input-group-append"> | ||||
<span class="input-group-text">€ HT / ${ getUnitReference() }</span> | <span class="input-group-text">€ HT / ${ getUnitReference() }</span> | ||||
</div> | </div> | ||||
{% if form.vars.value %} | |||||
<input type="hidden" :id="'value-price-'+keyForm" value="{{ form.vars.value.price }}" /> | |||||
{% endif %} | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</component-unit> | |||||
</product-unit-price> | |||||
</fieldset> | </fieldset> | ||||
</div> | </div> | ||||
<div class="field-group col-6"> | <div class="field-group col-6"> | ||||
<fieldset> | |||||
<legend>Déclinaisons</legend> | |||||
{{ form_row(form.activeProducts, {"attr": {"v-model": 'activeProducts'}}) }} | |||||
</fieldset> | |||||
<fieldset> | <fieldset> | ||||
<legend>Stock</legend> | <legend>Stock</legend> | ||||
<div class="row"> | <div class="row"> | ||||
<div class="col-12"> | <div class="col-12"> | ||||
{{ form_row(form.behaviorCountStock) }} | |||||
{{ form_row(form.availableQuantity) }} | |||||
{{ 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> | ||||
</div> | </div> | ||||
</fieldset> | </fieldset> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div v-show="currentSection == 'products'" class="panel panel-default"> | <div v-show="currentSection == 'products'" class="panel panel-default"> | ||||
{% macro printProductRow(product) %} | |||||
<div :id="'form-product-'+ keyForm"> | |||||
<div class="field-group"> | |||||
<fieldset> | |||||
<legend>Déclinaison</legend> | |||||
<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.title) }} | |||||
{{ form_help(product.title) }} | |||||
{% if product.vars.value %} | |||||
<input type="hidden" :id="'value-unit-'+keyForm" value="{{ product.vars.value.unit }}" /> | |||||
{% endif %} | |||||
</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.unit, {"attr":{'v-model': 'unit', 'class' : 'select-unit'}}) }} | |||||
{{ form_help(product.unit) }} | |||||
</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"> | |||||
<div class="input-group"> | |||||
{{ form_widget(product.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"> | |||||
<div class="input-group"> | |||||
{{ form_widget(product.step) }} | |||||
<div class="input-group-append"> | |||||
<span class="input-group-text">{% verbatim %}{{ 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"> | |||||
<div 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> | |||||
{% if product.vars.value %} | |||||
<input type="hidden" :id="'value-price-'+keyForm" value="{{ product.vars.value.price }}" /> | |||||
{% endif %} | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="form-group row field-price"> | |||||
<div class="col-2"> </div> | |||||
<div class="form-widget col-10"> | |||||
<div 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 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 col-10"> | |||||
{{ form_widget(product.availableQuantity) }} | |||||
</div> | |||||
</div> | |||||
</fieldset> | |||||
</div> | |||||
</div> | |||||
{% endmacro %} | |||||
{% import _self as formMacros %} | |||||
<ul class="products" :data-index="formProductArray.length" data-prototype="{{ formMacros.printProductRow(form.products.vars.prototype)|e('html_attr') }}"> | |||||
<li class="product" v-for="(formProduct, key) in formProductArray"> | |||||
<button type="button" class="btn-remove-product btn btn-default" @click="deleteFormProduct(key)"><i class="fa fa-trash"></i> Supprimer cette déclinaison</button> | |||||
<component-unit :template="formProduct" :key-form="key" :tax-rate-value="taxRateValue"></component-unit> | |||||
</li> | |||||
<li class="add"> | |||||
<button type="button" class="add_tag_link btn-add-product btn btn-default" @click="addFormProduct"><span class="fa fa-plus"></span> Ajouter une déclinaison</button> | |||||
</li> | |||||
{% for product in form.products %} | |||||
<script> | |||||
jQuery(document).ready(function() { | |||||
var formProduct = '{{ formMacros.printProductRow(product)|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}' ; | |||||
appProductFamily.formProductArray.push(formProduct) ; | |||||
appProductFamily.indexFormProduct ++ ; | |||||
}) ; | |||||
</script> | |||||
{% endfor %} | |||||
</ul> | |||||
{% include '@LcShop/backend/default/product_macro.html.twig' %} | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> |