'expanded' => true | 'expanded' => true | ||||
)); | )); | ||||
$formBuilder->add('behaviorDisplaySale', ChoiceType::class, array( | |||||
'empty_data' => ProductFamily::BEHAVIOR_DISPLAY_SALE_BY_QUANTITY, | |||||
'choices' => array( | |||||
'field.ProductFamily.behaviorDisplaySaleOptions.' . ProductFamily::BEHAVIOR_DISPLAY_SALE_BY_MEASURE => ProductFamily::BEHAVIOR_DISPLAY_SALE_BY_MEASURE, | |||||
'field.ProductFamily.behaviorDisplaySaleOptions.' . ProductFamily::BEHAVIOR_DISPLAY_SALE_BY_QUANTITY => ProductFamily::BEHAVIOR_DISPLAY_SALE_BY_QUANTITY, | |||||
), | |||||
'translation_domain' => 'lcshop', | |||||
'multiple' => false, | |||||
'expanded' => true | |||||
)); | |||||
$formBuilder->add('behaviorAddToCart', ChoiceType::class, array( | $formBuilder->add('behaviorAddToCart', ChoiceType::class, array( | ||||
'data' => $entity->getBehaviorAddToCart() ? $entity->getBehaviorAddToCart() : 'simple', | 'data' => $entity->getBehaviorAddToCart() ? $entity->getBehaviorAddToCart() : 'simple', | ||||
'choices' => array( | 'choices' => array( | ||||
'entity' => $entity, | 'entity' => $entity, | ||||
'delete_form' => $deleteForm->createView(), | 'delete_form' => $deleteForm->createView(), | ||||
'sortableProductsField' => $sortableProductsField, | 'sortableProductsField' => $sortableProductsField, | ||||
'totalProductOrdered' => $this->orderUtils->getTotalProductOrderedLastWeeks($entity) | |||||
'productsSalesStatistic' => $this->orderUtils->getProductsSalesStatistic($entity) | |||||
]; | ]; | ||||
return $this->executeDynamicMethod('render<EntityName>Template', ['edit', $this->entity['templates']['edit'], $parameters]); | return $this->executeDynamicMethod('render<EntityName>Template', ['edit', $this->entity['templates']['edit'], $parameters]); | ||||
'entity' => $entity, | 'entity' => $entity, | ||||
'categories' => $categories, | 'categories' => $categories, | ||||
'sortableProductsField' => array(), | 'sortableProductsField' => array(), | ||||
'totalProductOrdered' => array('total'=>0) | |||||
'productsSalesStatistic' => null | |||||
]; | ]; | ||||
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 Symfony\Component\Form\AbstractType; | use Symfony\Component\Form\AbstractType; | ||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
use Symfony\Component\Form\Extension\Core\Type\EmailType; | use Symfony\Component\Form\Extension\Core\Type\EmailType; | ||||
use Symfony\Component\Form\Extension\Core\Type\FileType; | |||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType; | use Symfony\Component\Form\Extension\Core\Type\TextareaType; | ||||
use Symfony\Component\Form\Extension\Core\Type\TextType; | 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; | ||||
use Symfony\Component\Security\Core\Security; | use Symfony\Component\Security\Core\Security; | ||||
use Symfony\Component\Validator\Constraints\File; | |||||
class TicketType extends AbstractType | class TicketType extends AbstractType | ||||
{ | { | ||||
]) | ]) | ||||
->add('message', TextareaType::class, [ | ->add('message', TextareaType::class, [ | ||||
'label' => 'Message' | 'label' => 'Message' | ||||
]) | |||||
->add('image', FileType::class, [ | |||||
'label' => 'Photo', | |||||
'mapped' => false, | |||||
'required' => false, | |||||
'constraints' => [ | |||||
new File([ | |||||
'maxSize' => '2048k', | |||||
'mimeTypes' => [ | |||||
'image/png', | |||||
'image/jpeg', | |||||
'image/jpg', | |||||
'image/gif', | |||||
], | |||||
'mimeTypesMessage' => "Mauvais format d'image (formats acceptés : jpeg, png, gif)", | |||||
]) | |||||
], | |||||
]); | ]); | ||||
} | } | ||||
<?php | |||||
namespace Lc\ShopBundle\Model; | |||||
use Doctrine\ORM\Mapping as ORM; | |||||
use Symfony\Component\HttpFoundation\File\File; | |||||
use Vich\UploaderBundle\Mapping\Annotation as Vich; | |||||
trait OpenGraphTrait | |||||
{ | |||||
/** | |||||
* @ORM\Column(type="string", nullable=true) | |||||
*/ | |||||
protected $openGraphTitle; | |||||
/** | |||||
* @ORM\Column(type="text", nullable=true) | |||||
*/ | |||||
protected $openGraphDescription; | |||||
/** | |||||
* @ORM\Column(type="string", length=255, nullable=true) | |||||
*/ | |||||
protected $openGraphImage; | |||||
/** | |||||
* @Vich\UploadableField(mapping="images", fileNameProperty="openGraphImage") | |||||
* @var File | |||||
*/ | |||||
protected $openGraphImageFile; | |||||
public function getOpenGraphTitle(): ?string | |||||
{ | |||||
return $this->openGraphTitle; | |||||
} | |||||
public function setOpenGraphTitle(string $openGraphTitle): self | |||||
{ | |||||
$this->openGraphTitle = $openGraphTitle; | |||||
return $this; | |||||
} | |||||
public function getOpenGraphDescription(): ?string | |||||
{ | |||||
return $this->openGraphDescription; | |||||
} | |||||
public function setOpenGraphDescription(?string $openGraphDescription): self | |||||
{ | |||||
$this->openGraphDescription = $openGraphDescription; | |||||
return $this; | |||||
} | |||||
public function getOpenGraphImage(): ?string | |||||
{ | |||||
return $this->openGraphImage; | |||||
} | |||||
public function setOpenGraphImage(?string $openGraphImage): self | |||||
{ | |||||
$this->openGraphImage = $openGraphImage; | |||||
return $this; | |||||
} | |||||
public function setOpenGraphImageFile(File $openGraphImageFile = null) | |||||
{ | |||||
$this->openGraphImageFile = $openGraphImageFile; | |||||
// VERY IMPORTANT: | |||||
// It is required that at least one field changes if you are using Doctrine, | |||||
// otherwise the event listeners won't be called and the file is lost | |||||
if ($openGraphImageFile) { | |||||
// if 'updatedAt' is not defined in your entity, use another property | |||||
$this->updatedAt = new \DateTime('now'); | |||||
} | |||||
} | |||||
public function getOpenGraphImageFile() | |||||
{ | |||||
return $this->openGraphImageFile ; | |||||
} | |||||
} |
const BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY = 'by-product-family' ; | const BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY = 'by-product-family' ; | ||||
const BEHAVIOR_COUNT_STOCK_BY_PRODUCT = 'by-product' ; | const BEHAVIOR_COUNT_STOCK_BY_PRODUCT = 'by-product' ; | ||||
const BEHAVIOR_DISPLAY_SALE_BY_MEASURE = 'by-measure' ; | |||||
const BEHAVIOR_DISPLAY_SALE_BY_QUANTITY = 'by-quantity' ; | |||||
const BEHAVIOR_STOCK_WEEK_RENEWABLE = 'renewable'; | const BEHAVIOR_STOCK_WEEK_RENEWABLE = 'renewable'; | ||||
const BEHAVIOR_STOCK_WEEK_RENEWABLE_VALIDATION = 'renewable-with-validation'; | const BEHAVIOR_STOCK_WEEK_RENEWABLE_VALIDATION = 'renewable-with-validation'; | ||||
const BEHAVIOR_STOCK_WEEK_NON_RENEWABLE = 'non-renewable'; | const BEHAVIOR_STOCK_WEEK_NON_RENEWABLE = 'non-renewable'; | ||||
*/ | */ | ||||
protected $behaviorCountStock; | protected $behaviorCountStock; | ||||
/** | |||||
* @ORM\Column(type="string", length=255) | |||||
*/ | |||||
protected $behaviorDisplaySale; | |||||
/** | /** | ||||
* @ORM\Column(type="date", nullable=true) | * @ORM\Column(type="date", nullable=true) | ||||
*/ | */ | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getBehaviorDisplaySale(): ?string | |||||
{ | |||||
return $this->behaviorDisplaySale; | |||||
} | |||||
public function setBehaviorDisplaySale(string $behaviorDisplaySale): self | |||||
{ | |||||
$this->behaviorDisplaySale = $behaviorDisplaySale; | |||||
return $this; | |||||
} | |||||
public function isPropertyNoveltyOnline(): ?bool | public function isPropertyNoveltyOnline(): ?bool | ||||
{ | { | ||||
if ($this->getPropertyNoveltyExpirationDate()) { | if ($this->getPropertyNoveltyExpirationDate()) { |
*/ | */ | ||||
protected $answerByAdmin; | protected $answerByAdmin; | ||||
/** | |||||
* @ORM\Column(type="string", length=255, nullable=true) | |||||
*/ | |||||
protected $imageFilename; | |||||
public function __toString() | public function __toString() | ||||
{ | { | ||||
return $this->message; | return $this->message; | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getImageFilename(): ?string | |||||
{ | |||||
return $this->imageFilename; | |||||
} | |||||
public function setImageFilename(?string $imageFilename): self | |||||
{ | |||||
$this->imageFilename = $imageFilename; | |||||
return $this; | |||||
} | |||||
} | } |
/* line 296, ../../sass/backend/custom.scss */ | /* line 296, ../../sass/backend/custom.scss */ | ||||
#lc-product-family-edit .btn-add-product { | #lc-product-family-edit .btn-add-product { | ||||
margin: 20px 0; | |||||
float: right; | float: right; | ||||
} | } | ||||
initNotice(); | initNotice(); | ||||
initBtnEditReminder(); | initBtnEditReminder(); | ||||
initBtnWriteToUser(); | initBtnWriteToUser(); | ||||
initCollectionWidget() | |||||
initCollectionWidget(); | |||||
initBtnShowTotalOrderProduct(); | |||||
$('form').on('focus', 'input[type=number]', function (e) { | $('form').on('focus', 'input[type=number]', function (e) { | ||||
$(this).on('wheel.disableScroll', function (e) { | $(this).on('wheel.disableScroll', function (e) { | ||||
e.preventDefault() | e.preventDefault() | ||||
resetNumItemsCollectionField($collectionWidget); | resetNumItemsCollectionField($collectionWidget); | ||||
}); | }); | ||||
} | } | ||||
function initBtnShowTotalOrderProduct(){ | |||||
$('.lc-show-products-sales-statistic').unbind('click').on('click', function (){ | |||||
$btn = $(this); | |||||
var url = $(this).data('url'); | |||||
$('#modal-products-sales-statistic').remove(); | |||||
$.ajax({ | |||||
url: url, | |||||
method: "POST", | |||||
dataType: "json", | |||||
success: function (response) { | |||||
$('body').append(response.data); | |||||
$('#modal-products-sales-statistic').modal('show'); | |||||
initModalProductsSalesStatistic(response.statistics); | |||||
} | |||||
}); | |||||
}); | |||||
} | |||||
function initModalProductsSalesStatistic(statistics) { | |||||
var chart = null; | |||||
$('.btn-products-sales-statistic').off('click'); | |||||
$('.btn-products-sales-statistic').on('click', function () { | |||||
$('.table-products-sales-statistic').hide(); | |||||
$('.btn-products-sales-statistic').addClass('btn-secondary').removeClass('btn-primary'); | |||||
$(this).removeClass('btn-secondary').addClass('btn-primary'); | |||||
$('#table-products-sales-statistic-'+$(this).data('property-name')).show() | |||||
if (chart) chart.destroy(); | |||||
$(this).removeClass('btn-secondary'); | |||||
chart = drawProductsSalesStatistic(statistics,$(this).data('property-name')) | |||||
}); | |||||
$('.btn-products-sales-statistic').first().click(); | |||||
} | |||||
function drawProductsSalesStatistic(statictics, propertyName) { | |||||
var options = { | |||||
bezierCurve : false, | |||||
tooltips: { | |||||
callbacks: { | |||||
label: (item) => item.yLabel , | |||||
}, | |||||
}, | |||||
}; | |||||
chart = new Chart(document.getElementById("chart"), { | |||||
"type": "line", | |||||
"data": { | |||||
"labels": Object.values(statictics.label), | |||||
"datasets": [{ | |||||
"label": "Vente de produits / semaine", | |||||
"data": Object.values(statictics.data[propertyName].data), | |||||
"fill": false, | |||||
"borderColor": "rgb(75, 192, 192)", | |||||
"lineTension": 0.1 | |||||
}] | |||||
}, | |||||
"options": options | |||||
}); | |||||
return chart; | |||||
} | |||||
}, | }, | ||||
behaviorPriceValue: function () { | behaviorPriceValue: function () { | ||||
return this.productFamily.behaviorPrice; | return this.productFamily.behaviorPrice; | ||||
} | |||||
}, | |||||
hasExportInfo: function () { | |||||
if((this.exportNote != null && this.exportNote != '') || (this.exportTitle != null && this.exportTitle != ''))return true | |||||
else return false; | |||||
}, | |||||
}, | }, | ||||
data() { | data() { | ||||
return Object.assign( | return Object.assign( | ||||
expirationDateInherited: false, | expirationDateInherited: false, | ||||
availableQuantityInherited: false, | availableQuantityInherited: false, | ||||
availableQuantityDefaultInherited: false, | availableQuantityDefaultInherited: false, | ||||
propertyExpirationDateInherited: false | |||||
propertyExpirationDateInherited: false, | |||||
exportTitle: null, | |||||
exportNote: null | |||||
}, window.productForm[this.keyForm]) | }, window.productForm[this.keyForm]) | ||||
}, | }, | ||||
mounted: function () { | mounted: function () { | ||||
}else{ | }else{ | ||||
this.status = 1; | this.status = 1; | ||||
$(this.$el).removeClass('disabled'); | $(this.$el).removeClass('disabled'); | ||||
if(this.hasExportInfo){ | |||||
alert('Cette déclinaison contient un titre ou une note à l\'export'); | |||||
} | |||||
} | } | ||||
}, | }, | ||||
decode(str){ | decode(str){ | ||||
var textArea = document.createElement('textarea'); | var textArea = document.createElement('textarea'); |
#lc-product-family-edit .products-collection-table th:last-child{border-right: 1px solid #dee2e6;} | #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; border-bottom: 1px solid #dee2e6;} | #lc-product-family-edit .products-collection-table td{border-left: 1px solid #dee2e6; text-align: center; font-size: 13px; border-bottom: 1px solid #dee2e6;} | ||||
#lc-product-family-edit .products-collection-table td:last-child{border-right: 1px solid #dee2e6; white-space: nowrap; } | #lc-product-family-edit .products-collection-table td:last-child{border-right: 1px solid #dee2e6; white-space: nowrap; } | ||||
#lc-product-family-edit .btn-add-product {margin: 20px 0; float: right;} | |||||
#lc-product-family-edit .btn-add-product {float: right;} | |||||
#lc-product-family-edit .inherited {color: #888; font-style: italic; font-weight: initial;} | #lc-product-family-edit .inherited {color: #888; font-style: italic; font-weight: initial;} | ||||
#lc-product-family-edit .products-collection-table td .value {min-width: 80%; margin: auto; min-height: 35px; cursor: pointer;} | #lc-product-family-edit .products-collection-table td .value {min-width: 80%; margin: auto; min-height: 35px; cursor: pointer;} | ||||
#lc-product-family-edit .products-collection-table td .modal {text-align: left;} | #lc-product-family-edit .products-collection-table td .modal {text-align: left;} |
initReduction: Réduction | initReduction: Réduction | ||||
export: Note à l'export | export: Note à l'export | ||||
stockNegative: Produits stocks négatif | stockNegative: Produits stocks négatif | ||||
purchaseOrder: Bons de commandes | |||||
ReductionCatalog: | ReductionCatalog: | ||||
info: Informations principal | info: Informations principal | ||||
conditions: Conditions d'application | conditions: Conditions d'application | ||||
waitingBankReturn: Commandes en attente de retour banque | waitingBankReturn: Commandes en attente de retour banque | ||||
list: Liste des commandes | list: Liste des commandes | ||||
giftVoucher: Commandes de bons cadeaux | giftVoucher: Commandes de bons cadeaux | ||||
multiplePayment: Paiements multiples | |||||
Ticket: | Ticket: | ||||
listMessages: Liste des messages | listMessages: Liste des messages | ||||
list: Tickets ouverts | list: Tickets ouverts | ||||
emailFromPurchaseOrder: "Email (From) : bons de commande" | emailFromPurchaseOrder: "Email (From) : bons de commande" | ||||
order: Commande | order: Commande | ||||
subject: Sujet | subject: Sujet | ||||
metaTitle: Meta title | |||||
metaDescription: Meta description | |||||
metaTitle: Titre (meta) | |||||
metaDescription: Description (meta) | |||||
users: Utilisateurs | users: Utilisateurs | ||||
total: Total | total: Total | ||||
products: Produits | products: Produits | ||||
ticketTypesNotification: Catégorie ticket | ticketTypesNotification: Catégorie ticket | ||||
newsletter: Newsletter | newsletter: Newsletter | ||||
isEligibleTicketRestaurant: Éligible ticket restaurant | isEligibleTicketRestaurant: Éligible ticket restaurant | ||||
openGraphTitle: Titre (OpenGraph) | |||||
openGraphDescription: Description (OpenGraph) | |||||
openGraphImageFile: Image (OpenGraph) | |||||
PointSale: | PointSale: | ||||
code: Code | code: Code | ||||
availableQuantityDefault: Quantité par défaut | availableQuantityDefault: Quantité par défaut | ||||
quantity: Quantité | quantity: Quantité | ||||
behaviorCountStock: Gestion du stock | behaviorCountStock: Gestion du stock | ||||
behaviorDisplaySale: Affichage du total des ventes | |||||
differentSupplierTaxRate: TVA différente pour le producteur | differentSupplierTaxRate: TVA différente pour le producteur | ||||
supplierTaxRate: TVA du producteur | supplierTaxRate: TVA du producteur | ||||
propertyNoveltyExpirationDateActive: Marquer le produit comme "nouveauté" jusqu'au | propertyNoveltyExpirationDateActive: Marquer le produit comme "nouveauté" jusqu'au | ||||
displayPriceUnitRef: Afficher le prix par unité de référence | displayPriceUnitRef: Afficher le prix par unité de référence | ||||
behaviorPrice: Travailler avec des tarifs | behaviorPrice: Travailler avec des tarifs | ||||
productsQuantityAsTitle: Titre équivalent à quantité | productsQuantityAsTitle: Titre équivalent à quantité | ||||
isDisabledOnPurchaseOrder: Automatiquement désactiver ce produit dans les bons de commandes | |||||
behaviorPriceOptions: | behaviorPriceOptions: | ||||
by-piece: À la pièce | by-piece: À la pièce | ||||
by-reference-unit: Par unité de référence | by-reference-unit: Par unité de référence | ||||
by-product-family: Gérer le stock par produit (à l'unité) | by-product-family: Gérer le stock par produit (à l'unité) | ||||
by-product: Gérer le stock par déclainaison | by-product: Gérer le stock par déclainaison | ||||
unlimited: Illimité | unlimited: Illimité | ||||
behaviorDisplaySaleOptions: | |||||
by-measure: Par unité de référence | |||||
by-quantity: Par quantité | |||||
behaviorStockWeek: Renouvelement du stock chaque semaine | behaviorStockWeek: Renouvelement du stock chaque semaine | ||||
behaviorStockWeekOptions: | behaviorStockWeekOptions: | ||||
renewable: Renouvelable | renewable: Renouvelable | ||||
product: | product: | ||||
editStock: Gérer les stocks | editStock: Gérer les stocks | ||||
editProductFamily: Éditer le produit | editProductFamily: Éditer le produit | ||||
statSales: Afficher plus de semaines | |||||
user: | user: | ||||
account: Mon compte | account: Mon compte | ||||
logout: Me déconnecter | logout: Me déconnecter |
{% import '@LcShop/backend/productfamily/macros.html.twig' as macros %} | |||||
{{ macros.product_family_sales_statistic(orderUtils.getProductsSalesStatistic(item, 2), item) }} |
{% import '@LcShop/backend/productfamily/macros.html.twig' as macros %} | |||||
{{ macros.total_order_product_family(orderUtils.getTotalProductOrderedLastWeeks(item, 2, true)['total'], item, true) }} |
{% extends '@LcShop/backend/default/list.html.twig' %} | |||||
{% import '@LcShop/backend/default/block/macros.html.twig' as macros %} | |||||
{% import '@LcShop/backend/productfamily/macros.html.twig' as product_family_macros %} | |||||
{% block table %} | |||||
<script> | |||||
window.mixinUnitValues = { | |||||
unitsList: {{ getUnitsList()|json_encode|raw }} | |||||
}; | |||||
window.mixinPriceValues = { | |||||
taxRatesList: {{ getTaxRatesList()|json_encode|raw }} | |||||
}; | |||||
window.appProductFamilyValues = {}; | |||||
window.productUnitPriceValues = {}; | |||||
window.productForm ={}; | |||||
window.formProductTemplate = {}; | |||||
</script> | |||||
<ul id="product-family-advanced-types-list"> | |||||
{% for i,advancedType in advancedTypes %} | |||||
{% set formValues = advancedType.vars.value %} | |||||
{% set productFamily = paginator.currentPageResults[i] %} | |||||
<script> | |||||
window.appProductFamilyValues[{{ i }}] = { | |||||
title: "{{ productFamily.title }}", | |||||
behaviorCountStock: "{{ productFamily.behaviorCountStock }}", | |||||
behaviorStockWeek: "{{ productFamily.behaviorStockWeek }}", | |||||
availableQuantity: "{{ productFamily.availableQuantity }}", | |||||
availableQuantityDefault: "{{ productFamily.availableQuantityDefault }}", | |||||
{% if productFamily.propertyNoveltyExpirationDate %}propertyNoveltyExpirationDate: {{ productFamily.propertyNoveltyExpirationDate }},{% endif %} | |||||
typeExpirationDate: "{{ productFamily.typeExpirationDate }}", | |||||
behaviorExpirationDate: "{{ productFamily.behaviorExpirationDate }}", | |||||
propertyExpirationDate: "{{ productFamily.propertyExpirationDate }}", | |||||
{% if productFamily.activeProducts %}activeProducts: {{ productFamily.activeProducts }},{% endif %} | |||||
}; | |||||
window.productUnitPriceValues[{{ i }}] = { | |||||
{% if productFamily.activeProducts %}activeProducts: {{ productFamily.activeProducts }},{% endif %} | |||||
behaviorPrice: "{{ productFamily.behaviorPrice }}", | |||||
unit: parseInt({{ productFamily.unit.id }}), | |||||
{% if productFamily.taxRate %}taxRate: parseInt({{ productFamily.taxRate.id }}),{% endif %} | |||||
{% if productFamily.supplierTaxRate %}supplierTaxRate: parseInt({{ productFamily.supplierTaxRate.id }}),{% endif %} | |||||
quantity: "{{ productFamily.quantity }}", | |||||
price: parseFloat({{ productFamily.price }}).toFixed(3), | |||||
priceByRefUnit: parseFloat({{ productFamily.priceByRefUnit }}).toFixed(3), | |||||
buyingPrice: parseFloat({{ productFamily.buyingPrice }}).toFixed(3), | |||||
buyingPriceByRefUnit: parseFloat({{ productFamily.buyingPriceByRefUnit }}).toFixed(3), | |||||
} | |||||
</script> | |||||
<li class="product-family-advanced-type-item"> | |||||
<div id="product-family-advanced-type-{{ i }}" class="product-family-advanced-type"> | |||||
{{ form_start(advancedType, {"attr": {"ref": 'advanced-type'}}) }} | |||||
<product-unit-price ref="productUnitPrice" inline-template key-form="productfamily"> | |||||
<div class="row"> | |||||
{{ form_row(advancedType.unit, {"attr":{'v-model': 'unit', '@change': "unitUpdated"}}) }} | |||||
<div class="input-group"> | |||||
{{ form_widget(advancedType.quantity, {'attr' : {'v-model': 'quantity', '@change': "quantityUpdated"}}) }} | |||||
<div class="input-group-append"> | |||||
<span class="input-group-text">${ unitWording }</span> | |||||
</div> | |||||
</div> | |||||
{{ macros.priceField(advancedType.buyingPrice, advancedType.buyingPriceWithTax, 'buyingPrice', 'by-piece') }} | |||||
{{ macros.priceField(advancedType.buyingPriceByRefUnit, advancedType.buyingPriceByRefUnitWithTax, 'buyingPriceByRefUnit', 'by-reference-unit') }} | |||||
<div class="input-group"> | |||||
{{ form_widget(advancedType.multiplyingFactor, {'attr': {'v-model':'multiplyingFactor', '@change' : 'multiplyingFactorUpdated'}}) }} | |||||
<div class="input-group-append"> | |||||
<span class="input-group-text">X</span> | |||||
</div> | |||||
</div> | |||||
{{ macros.priceField(advancedType.price, advancedType.priceWithTax, 'price', 'by-piece') }} | |||||
{{ macros.priceField(advancedType.priceByRefUnit, advancedType.priceByRefUnitWithTax, 'priceByRefUnit', 'by-reference-unit') }} | |||||
</div> | |||||
</product-unit-price> | |||||
<table class="table datagrid sortable lc-sortable-products products-collection-table" | |||||
:data-index="formProducts.length" | |||||
data-prototype="{{ product_family_macros.product_row(advancedType.products.vars.prototype)|e('html_attr') }}"> | |||||
<thead> | |||||
<tr> | |||||
<th> | |||||
</th> | |||||
<th colspan="4" class="string"> | |||||
Titre | |||||
</th> | |||||
<th colspan="2" class="string "> | |||||
Quantité | |||||
</th> | |||||
<th colspan="2" class="quantity"> | |||||
Unité | |||||
</th> | |||||
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'" | |||||
colspan="3" class="buyingPriceByRefUnit"> | |||||
PA HT / ${ getUnitReference() } | |||||
</th> | |||||
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'" | |||||
colspan="3" class="priceByRefUnit"> | |||||
PA TTC / ${ getUnitReference() } | |||||
</th> | |||||
<th colspan="3" class="price" | |||||
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'"> | |||||
PA HT | |||||
</th> | |||||
<th colspan="3" class="price"> | |||||
PA TTC | |||||
</th> | |||||
<th colspan="3" class=""> | |||||
Coef | |||||
</th> | |||||
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'" | |||||
colspan="3" class=""> | |||||
PV HT / ${ getUnitReference() } | |||||
</th> | |||||
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'" | |||||
colspan="3" class="price"> | |||||
PV TTC / ${ getUnitReference() } | |||||
</th> | |||||
<th colspan="3" class="price" | |||||
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'"> | |||||
PV HT | |||||
</th> | |||||
<th colspan="3" class="price"> | |||||
PV TTC | |||||
</th> | |||||
<th colspan="2"> | |||||
Marge HT | |||||
</th> | |||||
<th colspan="2" class="" | |||||
v-show="behaviorExpirationDate== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT') }}'"> | |||||
<span style="text-transform: uppercase"> ${typeExpirationDate}</span> | |||||
</th> | |||||
<th colspan="2" | |||||
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}'"> | |||||
Stock | |||||
</th> | |||||
<th colspan="2" | |||||
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' && behaviorStockWeek!= '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE') }}'"> | |||||
Stock par défaut | |||||
</th> | |||||
<th colspan="2" | |||||
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' || behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}'"> | |||||
Semaine / Commandés | |||||
</th> | |||||
<th colspan="2" class=""> | |||||
Action | |||||
</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody class="products-collection"> | |||||
<template> | |||||
<product-form v-for="(formProduct, blop) in formProducts" v-bind:key="formProductKey[blop]" | |||||
:key-form="formProductKey[blop]" ref="productForm" v-bind:product-family="productFamily" | |||||
:template="formProduct"></product-form> | |||||
</template> | |||||
</tbody> | |||||
<tfoot> | |||||
<th> | |||||
Rappel | |||||
</th> | |||||
<th colspan="4" class="string"> | |||||
${title} | |||||
</th> | |||||
<th colspan="2" class="string "> | |||||
${productFamily.quantity} | |||||
</th> | |||||
<th colspan="2" class="quantity"> | |||||
${productFamily.unitWording} | |||||
</th> | |||||
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'" | |||||
colspan="3" class="buyingPriceByRefUnit"> | |||||
${productFamily.buyingPriceByRefUnit} | |||||
</th> | |||||
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'" | |||||
colspan="3" class="priceByRefUnit"> | |||||
${productFamily.buyingPriceByRefUnitWithTax} | |||||
</th> | |||||
<th colspan="3" class="price" | |||||
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'"> | |||||
${productFamily.buyingPrice} | |||||
</th> | |||||
<th colspan="3" class="price"> | |||||
${productFamily.buyingPriceWithTax} | |||||
</th> | |||||
<th colspan="3" class=""> | |||||
${productFamily.multiplyingFactor} | |||||
</th> | |||||
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'" | |||||
colspan="3" class=""> | |||||
${productFamily.priceByRefUnit} | |||||
</th> | |||||
<th v-show="getBehaviorPrice() == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'" | |||||
colspan="3" class="price"> | |||||
${productFamily.priceByRefUnitWithTax} | |||||
</th> | |||||
<th colspan="3" class="price" | |||||
v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'"> | |||||
${productFamily.price} | |||||
</th> | |||||
<th colspan="3" class="price"> | |||||
${productFamily.priceWithTax} | |||||
</th> | |||||
<th colspan="2" class="price"> | |||||
${productFamily.marginProfit}€<br/> | |||||
${productFamily.marginProfitPercent}% | |||||
</td> | |||||
<th colspan="2" class="" | |||||
v-show="behaviorExpirationDate== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_EXPIRATION_DATE_BY_PRODUCT') }}'"> | |||||
${propertyExpirationDate} | |||||
</th> | |||||
<th colspan="2" | |||||
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}'"> | |||||
</th> | |||||
<th colspan="2" | |||||
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' && behaviorStockWeek!= '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE') }}'"> | |||||
</th> | |||||
<th colspan="2" | |||||
v-show="behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') }}' || behaviorCountStock== '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}'"> | |||||
</th> | |||||
<th colspan="2" class=""> | |||||
</th> | |||||
</tfoot> | |||||
</table> | |||||
<button type="button" class="add_tag_link btn-add-product btn btn-default" @click="addProductForm"><span | |||||
class="fa fa-plus"></span> Ajouter une déclinaison | |||||
</button> | |||||
<p> | |||||
<strong>Aide à l'utilisation - Raccourci clavier</strong> | |||||
<ul> | |||||
<li><strong>TAB</strong> : Champ suivant</li> | |||||
<li><strong>SHIFT + TAB</strong> : Champ précédent</li> | |||||
<li><strong>FLÈCHE BAS</strong> : Déclinaison suivante</li> | |||||
<li><strong>FLÈCHE HAUT</strong> : Déclinaison précédente</li> | |||||
<li><strong>SHIFT + [+]</strong> : Ajout d'une nouvelle déclinaison</li> | |||||
</ul> | |||||
</p> | |||||
<div class="clearfix"></div> | |||||
{% do advancedType.products.setRendered %} | |||||
<script> | |||||
window.productForm[{{ i }}] ={}; | |||||
window.formProductTemplate[{{ i }}] = {}; | |||||
{% for keyForm,y in sortableProductsField[i] %} | |||||
{% set product = advancedType.products[y] %} | |||||
window.productForm[{{ i }}][{{ keyForm }}] = { | |||||
{% if product.vars.value.position %}position: "{{ product.vars.value.position }}",{% endif %} | |||||
{% if product.vars.value.title %}title: "{{ product.vars.value.title }}",{% endif %} | |||||
{% if product.vars.value.quantity %}quantity: "{{ product.vars.value.quantity }}",{% endif %} | |||||
{% if product.vars.value.unit %}unit: {{ product.vars.value.unit.id }},{% endif %} | |||||
{% if product.vars.value.buyingPrice %}buyingPrice: parseFloat({{ product.vars.value.buyingPrice }}).toFixed(3),{% endif %} | |||||
{% if product.vars.value.buyingPriceByRefUnit %}buyingPriceByRefUnit: parseFloat({{ product.vars.value.buyingPriceByRefUnit }}).toFixed(3),{% endif %} | |||||
{% if product.vars.value.price %}price: parseFloat({{ product.vars.value.price }}).toFixed(3),{% endif %} | |||||
{% if product.vars.value.priceByRefUnit %}priceByRefUnit: parseFloat({{ product.vars.value.priceByRefUnit }}).toFixed(3),{% endif %} | |||||
{% if product.vars.value.availableQuantity %}availableQuantity: parseInt({{ product.vars.value.availableQuantity }}),{% endif %} | |||||
{% if product.vars.value.availableQuantityDefault %}availableQuantityDefault: parseInt({{ product.vars.value.availableQuantityDefault }}),{% endif %} | |||||
{% if product.vars.value.propertyExpirationDate %}propertyExpirationDate: "{{ product.vars.value.propertyExpirationDate }}",{% endif %} | |||||
{#{% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %}#} | |||||
}; | |||||
window.formProductTemplate[{{ i }}][{{ keyForm }}] = '{{ product_family_macros.product_row(product, totalProductOrdered[i][product.vars.value.id])|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; | |||||
{% endfor %} | |||||
</script> | |||||
{{ form_end(advancedType) }} | |||||
</div> | |||||
</li> | |||||
{% endfor %} | |||||
</ul> | |||||
{% endblock table %} | |||||
{% block head_stylesheets %} | |||||
{{ parent() }} | |||||
{% endblock %} | |||||
{% block plugin_javascript %} | |||||
{{ parent() }} | |||||
{% endblock %} | |||||
{% block script_javascript %} | |||||
{{ parent() }} | |||||
{% include '@LcShop/backend/default/block/script-vuejs.html.twig' %} | |||||
<script src="{{ asset('assets/js/backend/script/productfamily/vuejs-advanced-edition-product-family.js')|lc_cache }}"></script> | |||||
{% endblock %} |
<script src="{{ asset('bundles/lcshop/js/backend/plugin/daterange/moment.min.js')}}"></script> | <script src="{{ asset('bundles/lcshop/js/backend/plugin/daterange/moment.min.js')}}"></script> | ||||
<script src="{{ asset('bundles/lcshop/js/backend/plugin/daterange/daterangepicker.js')}}"></script> | <script src="{{ asset('bundles/lcshop/js/backend/plugin/daterange/daterangepicker.js')}}"></script> | ||||
<script src="{{ asset('bundles/lcshop/js/backend/plugin/chartjs/Chart.min.js') }}"></script> | |||||
{% endblock %} | {% endblock %} | ||||
{% block script_javascript %} | {% block script_javascript %} |
{% trans_default_domain 'lcshop' %} | {% trans_default_domain 'lcshop' %} | ||||
{% macro total_order_product(totalProductOrdered, productFamily=false) %} | |||||
{% for weekNumber, weekNumberQuantity in totalProductOrdered %} | |||||
{% macro product_sales_statistic(productsSalesStatistic, productFamily=false) %} | |||||
{% for weekNumber, weekNumberQuantity in productsSalesStatistic %} | |||||
<span class="text-success"><i class="fa fa-calendar"></i> {{ weekNumber }}</span> | <span class="text-success"><i class="fa fa-calendar"></i> {{ weekNumber }}</span> | ||||
<span class="text-info"><i class="fa fa-shopping-basket"></i> | <span class="text-info"><i class="fa fa-shopping-basket"></i> | ||||
<strong> | <strong> | ||||
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity}} | |||||
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity }} | |||||
</strong> | </strong> | ||||
</span> | </span> | ||||
<br /> | |||||
<br/> | |||||
{% endfor %} | {% endfor %} | ||||
{% endmacro total_order_product %} | |||||
{% macro total_order_product_family(totalProductOrdered, productFamily,forceByMeasure = false) %} | |||||
{% for weekNumber, weekNumberQuantity in totalProductOrdered %} | |||||
<span class="text-success"><i class="fa fa-calendar"></i> {{ weekNumber }}</span> | |||||
<span class="text-info"><i class="fa fa-shopping-basket"></i> | |||||
{% endmacro product_sales_statistic %} | |||||
{% macro product_family_sales_statistic(productsSalesStatistic, productFamily) %} | |||||
{% if productsSalesStatistic %} | |||||
<button type="button" data-product-family="{{ productFamily.id }}" | |||||
class="lc-show-products-sales-statistic btn btn-sm" | |||||
data-toggle="tooltip" title="{{ 'action.product.statSales'|trans }}" | |||||
data-url="{{ path('easyadmin', { action: 'showSalesStatistic', entity: 'ProductFamily', id: productFamily.id }) }}"> | |||||
{% for weekNumber, weekNumberQuantity in productsSalesStatistic['data']['total_sales']['data'] %} | |||||
<span class="text-success"><i class="fa fa-calendar"></i> {{ weekNumber }}</span> | |||||
<span class="text-info"><i class="fa fa-shopping-basket"></i> | |||||
<strong> | <strong> | ||||
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity}} | |||||
{% if productFamily and (productFamily.behaviorCountStock== constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') or forceByMeasure)%} | |||||
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity }} | |||||
{% if productFamily and (productFamily.behaviorDisplaySale== constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_DISPLAY_SALE_BY_MEASURE')) %} | |||||
{{ productFamily.unit.unitReference }} | {{ productFamily.unit.unitReference }} | ||||
{% endif %} | {% endif %} | ||||
</strong> | </strong> | ||||
</span> | </span> | ||||
<br /> | |||||
{% endfor %} | |||||
{% endmacro total_order_product_family %} | |||||
<br/> | |||||
{% endfor %} | |||||
</button> | |||||
{% endif %} | |||||
{% endmacro product_family_sales_statistic %} | |||||
{% macro product_field(colspan, field, field_name, field_display = false, display_suffix="",attr="") %} | {% macro product_field(colspan, field, field_name, field_display = false, display_suffix="",attr="") %} | ||||
{% if field_display == false %}{% set field_display = field_name %}{% endif %} | {% if field_display == false %}{% set field_display = field_name %}{% endif %} | ||||
<td {{ attr|raw }} colspan="{{ colspan }}" class="{{ field_name }}"> | <td {{ attr|raw }} colspan="{{ colspan }}" class="{{ field_name }}"> | ||||
<div class="value" v-show="{{ field_name }}Inherited == false" @click="setFocusOnField('{{ field_name }}Inherited', keyForm)"> | |||||
<div class="value" v-show="{{ field_name }}Inherited == false" | |||||
@click="setFocusOnField('{{ field_name }}Inherited', keyForm)"> | |||||
<div v-if="{{ field_name }}"> | <div v-if="{{ field_name }}"> | ||||
{% verbatim %}{{ {% endverbatim %}{{ field_display }} {% verbatim %}}}{% endverbatim %}{{ display_suffix }} | {% verbatim %}{{ {% endverbatim %}{{ field_display }} {% verbatim %}}}{% endverbatim %}{{ display_suffix }} | ||||
{% if field_name == 'priceWithTax' %} | {% if field_name == 'priceWithTax' %} | ||||
<br /> | |||||
<span class="text-danger" v-show="productFamily.reductionActive">{% verbatim %}{{ finalPriceWithTaxAndReduction }}{% endverbatim %}€</span> | |||||
<br/> | |||||
<span class="text-danger" | |||||
v-show="productFamily.reductionActive">{% verbatim %}{{ finalPriceWithTaxAndReduction }}{% endverbatim %}€</span> | |||||
{% endif %} | {% endif %} | ||||
</div> | </div> | ||||
<div v-else class="inherited"> | <div v-else class="inherited"> | ||||
{% verbatim %}{{ productFamily.{% endverbatim %}{{ field_display }} {% verbatim %}}}{% endverbatim %}{{ display_suffix }} | {% verbatim %}{{ productFamily.{% endverbatim %}{{ field_display }} {% verbatim %}}}{% endverbatim %}{{ display_suffix }} | ||||
{% if field_name == 'priceWithTax' %} | {% if field_name == 'priceWithTax' %} | ||||
<br /> | |||||
<span class="text-danger" v-show="productFamily.reductionActive">{% verbatim %}{{ finalPriceWithTaxAndReduction }}{% endverbatim %}€</span> | |||||
<br/> | |||||
<span class="text-danger" | |||||
v-show="productFamily.reductionActive">{% verbatim %}{{ finalPriceWithTaxAndReduction }}{% endverbatim %}€</span> | |||||
{% endif %} | {% endif %} | ||||
</div> | </div> | ||||
</td> | </td> | ||||
{% endmacro %} | {% endmacro %} | ||||
{% macro product_row(product, totalProductOrdered) %} | |||||
{% macro product_row(product, productsSalesStatistic) %} | |||||
<tr class="lc-draggable" v-show="originProduct != true && status >= 0 "> | <tr class="lc-draggable" v-show="originProduct != true && status >= 0 "> | ||||
<td> | <td> | ||||
{{ _self.product_field(3, product.buyingPrice, 'buyingPrice',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }} | {{ _self.product_field(3, product.buyingPrice, 'buyingPrice',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }} | ||||
{{ _self.product_field(3, product.buyingPriceWithTax, 'buyingPriceWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }} | {{ _self.product_field(3, product.buyingPriceWithTax, 'buyingPriceWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }} | ||||
<td class="buyingPrice" colspan="3" v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"> | |||||
<td class="buyingPrice" colspan="3" | |||||
v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"> | |||||
{% verbatim %}{{ finalBuyingPrice }}{% endverbatim %}€ | {% verbatim %}{{ finalBuyingPrice }}{% endverbatim %}€ | ||||
</td> | </td> | ||||
{{ _self.product_field(3, product.priceByRefUnitWithTax, 'priceByRefUnitWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') ~ '\'"') }} | {{ _self.product_field(3, product.priceByRefUnitWithTax, 'priceByRefUnitWithTax',false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') ~ '\'"') }} | ||||
<td class="price" colspan="3" v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"> | |||||
<td class="price" colspan="3" | |||||
v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"> | |||||
{% verbatim %}{{ finalPrice }}{% endverbatim %}€ | {% verbatim %}{{ finalPrice }}{% endverbatim %}€ | ||||
</td> | </td> | ||||
<td class="priceWithTax" colspan="3" v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"> | |||||
<td class="priceWithTax" colspan="3" | |||||
v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_REFERENCE_UNIT') }}'"> | |||||
{% verbatim %}{{ finalPriceWithTax }}{% endverbatim %}€ | {% verbatim %}{{ finalPriceWithTax }}{% endverbatim %}€ | ||||
<span class="text-danger" v-show="productFamily.reductionActive">{% verbatim %}{{ finalPriceWithTaxAndReduction }}{% endverbatim %}€</span> | |||||
<span class="text-danger" | |||||
v-show="productFamily.reductionActive">{% verbatim %}{{ finalPriceWithTaxAndReduction }}{% endverbatim %}€</span> | |||||
</td> | </td> | ||||
{{ _self.product_field(3, product.price, 'price', false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }} | {{ _self.product_field(3, product.price, 'price', false, '€', 'v-show="productFamily.behaviorPrice == \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') ~ '\'"') }} | ||||
<td colspan="2" v-show="productFamily.giftVoucherActive!= true"> | <td colspan="2" v-show="productFamily.giftVoucherActive!= true"> | ||||
<span v-if="productFamily.reductionActive" class="text-danger"> | <span v-if="productFamily.reductionActive" class="text-danger"> | ||||
{% verbatim %}{{ marginProfitWithReduction }}{% endverbatim %}€<br /> | |||||
{% verbatim %}{{ marginProfitWithReduction }}{% endverbatim %}€<br/> | |||||
{% verbatim %}{{ marginProfitPercentWithReduction }}{% endverbatim %}% | {% verbatim %}{{ marginProfitPercentWithReduction }}{% endverbatim %}% | ||||
</span> | </span> | ||||
<span v-else> | <span v-else> | ||||
{% verbatim %}{{ marginProfit }}{% endverbatim %}€<br /> | |||||
{% verbatim %}{{ marginProfit }}{% endverbatim %}€<br/> | |||||
{% verbatim %}{{ marginProfitPercent }}{% endverbatim %}% | {% verbatim %}{{ marginProfitPercent }}{% endverbatim %}% | ||||
</span> | </span> | ||||
</td> | </td> | ||||
{{ _self.product_field(2, product.availableQuantityDefault, 'availableQuantityDefault',false, '', 'v-show="productFamily.behaviorCountStock== \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') ~ '\' && productFamily.behaviorStockWeek!= \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE') ~ '\'"') }} | {{ _self.product_field(2, product.availableQuantityDefault, 'availableQuantityDefault',false, '', 'v-show="productFamily.behaviorCountStock== \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT') ~ '\' && productFamily.behaviorStockWeek!= \'' ~ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_STOCK_WEEK_NON_RENEWABLE') ~ '\'"') }} | ||||
<td colspan="2"> | |||||
<td colspan="2"> | |||||
{{ _self.total_order_product(totalProductOrdered) }} | |||||
{{ _self.product_sales_statistic(productsSalesStatistic) }} | |||||
</td> | </td> | ||||
{# <td colspan="4" v-show="productFamily.giftVoucherActive== true"> | |||||
{# <td colspan="4" v-show="productFamily.giftVoucherActive== true"> | |||||
{{ form_row(product.giftVoucherReductionCart, {"label": false, "attr" : {'v-model' : 'giftVoucherReductionCart', ':required': 'status ==1 && productFamily.giftVoucherActive'}}) }} | {{ form_row(product.giftVoucherReductionCart, {"label": false, "attr" : {'v-model' : 'giftVoucherReductionCart', ':required': 'status ==1 && productFamily.giftVoucherActive'}}) }} | ||||
</td>#} | |||||
<td colspan="3"> | |||||
<button type="button" class="btn-sm btn-info" @click="modalProductForm()"> | |||||
</td> #} | |||||
<td colspan="3"> | |||||
<button type="button" :class="hasExportInfo ? 'btn-sm btn-info' : 'btn-sm btn-secondary'" @click="modalProductForm()"> | |||||
<i class="fa fa-edit"></i> | <i class="fa fa-edit"></i> | ||||
</button> | </button> | ||||
<button type="button" class="btn-sm btn-info" @click="changeStatus()"> | <button type="button" class="btn-sm btn-info" @click="changeStatus()"> | ||||
</div> | </div> | ||||
<div class="modal-body"> | <div class="modal-body"> | ||||
<div class="col"> | <div class="col"> | ||||
{{ form_row(product.exportTitle) }} | |||||
{{ form_row(product.exportTitle, {'attr' : {"v-model" : 'exportTitle'}}) }} | |||||
</div> | </div> | ||||
<div class="col"> | <div class="col"> | ||||
{{ form_row(product.exportNote) }} | |||||
{{ form_row(product.exportNote, {'attr' : {"v-model" : 'exportNote'}}) }} | |||||
</div> | </div> | ||||
{% endfor %} | {% endfor %} | ||||
{% do form.sections.setRendered %} | {% do form.sections.setRendered %} | ||||
</div> | </div> | ||||
{{ macros.endCard() }} | |||||
{{ macros.endCard(true) }} | |||||
{{ macros.startCard(8, 'ProductFamily.main','light') }} | |||||
{{ macros.startCard(0, 'ProductFamily.main','light') }} | |||||
<div class="col-12"> | <div class="col-12"> | ||||
{{ form_row(form.supplier) }} | {{ form_row(form.supplier) }} | ||||
</div> | </div> |
<div class="row"> | <div class="row"> | ||||
{{ macros.startCard(12, 'ProductFamily.products', 'light', true) }} | {{ macros.startCard(12, 'ProductFamily.products', 'light', true) }} | ||||
<table class="table datagrid sortable lc-sortable-products products-collection-table" | |||||
<table class="table datagrid sortable lc-sortable-products products-collection-table" style="margin-bottom: 20px;" | |||||
:data-index="formProducts.length" | :data-index="formProducts.length" | ||||
data-prototype="{{ product_family_macros.product_row(form.products.vars.prototype)|e('html_attr') }}"> | data-prototype="{{ product_family_macros.product_row(form.products.vars.prototype)|e('html_attr') }}"> | ||||
<thead> | <thead> | ||||
<tr> | <tr> | ||||
<th> | <th> | ||||
</th> | </th> | ||||
<th colspan="4" class="string" v-show="productsQuantityAsTitle == false"> | |||||
<th colspan="4" class="string" v-show="productsQuantityAsTitle == false"> | |||||
Titre | Titre | ||||
<button v-on:click="emptyProductsField('title');" | <button v-on:click="emptyProductsField('title');" | ||||
class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button> | class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button> | ||||
<th colspan="3" class="price main-info"> | <th colspan="3" class="price main-info"> | ||||
PA HT | PA HT | ||||
<button v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'" v-on:click="emptyProductsField('buyingPrice');" | |||||
<button v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'" | |||||
v-on:click="emptyProductsField('buyingPrice');" | |||||
class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button> | class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button> | ||||
</th> | </th> | ||||
<th colspan="3" class="price" | <th colspan="3" class="price" | ||||
<th colspan="3" class="price"> | <th colspan="3" class="price"> | ||||
{# v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'"> #} | {# v-show="getBehaviorPrice() =='{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'"> #} | ||||
PV HT | PV HT | ||||
<button v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'" v-on:click="emptyProductsField('price');" | |||||
<button v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'" | |||||
v-on:click="emptyProductsField('price');" | |||||
class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button> | class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button> | ||||
</th> | </th> | ||||
<th colspan="3" class="price main-info"> | <th colspan="3" class="price main-info"> | ||||
PV TTC | PV TTC | ||||
<button v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'" v-on:click="emptyProductsField('priceWithTax');" | |||||
<button v-show="productFamily.behaviorPrice == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_PRICE_BY_PIECE') }}'" | |||||
v-on:click="emptyProductsField('priceWithTax');" | |||||
class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button> | class="btn btn-empty-field" type="button"><i class="fa fa-undo"></i></button> | ||||
</th> | </th> | ||||
<th colspan="2" v-show="giftVoucherActive!= true"> | |||||
<th colspan="2" v-show="giftVoucherActive!= true"> | |||||
Marge HT | Marge HT | ||||
</th> | </th> | ||||
<th colspan="2"> | <th colspan="2"> | ||||
Semaine / Commandés | Semaine / Commandés | ||||
</th> | </th> | ||||
{#<th colspan="4" | |||||
{# <th colspan="4" | |||||
v-show="giftVoucherActive== true"> | v-show="giftVoucherActive== true"> | ||||
Réduction "Bon cadeaux" | Réduction "Bon cadeaux" | ||||
</th>#} | |||||
</th> #} | |||||
<th colspan="3" class=""> | <th colspan="3" class=""> | ||||
Action | Action | ||||
</th> | </th> | ||||
<th colspan="3" class="price main-info"> | <th colspan="3" class="price main-info"> | ||||
${productFamily.priceWithTax} | ${productFamily.priceWithTax} | ||||
</th> | </th> | ||||
<th colspan="2" class="price" v-show="giftVoucherActive!= true"> | |||||
<th colspan="2" class="price" v-show="giftVoucherActive!= true"> | |||||
${productFamily.marginProfit}€<br/> | ${productFamily.marginProfit}€<br/> | ||||
${productFamily.marginProfitPercent}% | ${productFamily.marginProfitPercent}% | ||||
</td> | </td> | ||||
</th> | </th> | ||||
<th colspan="2"> | <th colspan="2"> | ||||
</th> | </th> | ||||
{#<th colspan="4" | |||||
{# <th colspan="4" | |||||
v-show="giftVoucherActive== true"> | v-show="giftVoucherActive== true"> | ||||
</th>#} | |||||
</th> #} | |||||
<th colspan="3" class=""> | <th colspan="3" class=""> | ||||
</th> | </th> | ||||
</table> | </table> | ||||
<div class="col-12"> | |||||
<div class="row" style="margin: 0 25px"> | |||||
<div class="col-3 form-group"> | |||||
{{ form_widget(form.productsQuantityAsTitle, {"attr":{'v-model' : 'productsQuantityAsTitle'}}) }} | |||||
</div> | |||||
<div class="col-3 form-group"></div> | |||||
<div class="col-6 form-group float-right"> | |||||
<button type="button" class="add_tag_link btn-add-product btn btn-default" @click="addProductForm"><span | <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 | class="fa fa-plus"></span> Ajouter une déclinaison | ||||
</button> | </button> | ||||
</div> | |||||
<div class="col-12"> | |||||
{{ form_row(form.productsQuantityAsTitle, {"attr":{'v-model' : 'productsQuantityAsTitle'}}) }} | |||||
<p> | <p> | ||||
<strong>Aide à l'utilisation - Raccourci clavier</strong> | <strong>Aide à l'utilisation - Raccourci clavier</strong> | ||||
<ul> | <ul> | ||||
</ul> | </ul> | ||||
</p> | </p> | ||||
</div> | </div> | ||||
</div> | |||||
<div class="clearfix"></div> | |||||
<div class="clearfix"></div> | |||||
{{ macros.endCard() }} | {{ macros.endCard() }} | ||||
</div> | </div> | ||||
{% if product.vars.value.availableQuantity %}availableQuantity: parseInt({{ product.vars.value.availableQuantity }}),{% 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.availableQuantityDefault %}availableQuantityDefault: parseInt({{ product.vars.value.availableQuantityDefault }}),{% endif %} | ||||
{% if product.vars.value.propertyExpirationDate %}propertyExpirationDate: "{{ product.vars.value.propertyExpirationDate }}",{% endif %} | {% if product.vars.value.propertyExpirationDate %}propertyExpirationDate: "{{ product.vars.value.propertyExpirationDate }}",{% endif %} | ||||
{#{% if product.vars.value.giftVoucherReductionCart %}giftVoucherReductionCart: {{ product.vars.value.giftVoucherReductionCart.id }},{% endif %}#} | |||||
{% if product.vars.value.exportTitle %}exportTitle: "{{ product.vars.value.exportTitle }}",{% endif %} | |||||
{% if product.vars.value.exportNote %}exportNote: "{{ product.vars.value.exportNote }}",{% endif %} | |||||
{# {% if product.vars.value.giftVoucherReductionCart %}giftVoucherReductionCart: {{ product.vars.value.giftVoucherReductionCart.id }},{% endif %} #} | |||||
{# {% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %} #} | {# {% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %} #} | ||||
}; | }; | ||||
window.formProductTemplate[{{ keyForm }}] = '{{ product_family_macros.product_row(product, totalProductOrdered[product.vars.value.id])|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; | |||||
window.formProductTemplate[{{ keyForm }}] = '{{ product_family_macros.product_row(product, productsSalesStatistic['data'][product.vars.value.id]['data'])|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; | |||||
{# {% endif %} #} | {# {% endif %} #} | ||||
{% endfor %} | {% endfor %} | ||||
{% endif %} | {% endif %} | ||||
{% endfor %} | {% endfor %} | ||||
{{ form_row(form.behaviorDisplaySale) }} | |||||
</div> | </div> | ||||
<div class="col"> | <div class="col"> | ||||
<div v-show="behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY') }}' || behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}'" | <div v-show="behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY') }}' || behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}'" | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<p v-show="behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY') }}' || behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}' || behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_UNLIMITED') }}' "> | <p v-show="behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY') }}' || behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') }}' || behaviorCountStock == '{{ constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_UNLIMITED') }}' "> | ||||
{{ product_family_macros.total_order_product_family(totalProductOrdered['total'], entity) }} | |||||
{{ product_family_macros.product_family_sales_statistic(productsSalesStatistic, entity) }} | |||||
</p> | </p> | ||||
</div> | </div> | ||||
{{ macros.endCard(true) }} | |||||
{{ macros.startCard(0, 'ProductFamily.export', 'light') }} | |||||
<div class="col"> | |||||
{{ form_row(form.exportTitle) }} | |||||
{{ form_row(form.exportNote) }} | |||||
</div> | |||||
{{ macros.endCard() }} | {{ macros.endCard() }} | ||||
{{ macros.startCard(4, 'ProductFamily.storage', 'light') }} | {{ macros.startCard(4, 'ProductFamily.storage', 'light') }} | ||||
<div class="col"> | <div class="col"> | ||||
{{ form_row(form.depositoryZone) }} | {{ form_row(form.depositoryZone) }} | ||||
</div> | </div> | ||||
{{ macros.endCard() }} | |||||
{{ macros.endCard(true) }} | |||||
{{ macros.startCard(8, 'ProductFamily.export', 'light') }} | |||||
{{ macros.startCard(0, 'ProductFamily.purchaseOrder', 'light') }} | |||||
<div class="col"> | <div class="col"> | ||||
{{ form_row(form.exportTitle) }} | |||||
{{ form_row(form.exportNote) }} | |||||
{{ form_row(form.isDisabledOnPurchaseOrder) }} | |||||
</div> | </div> | ||||
{{ macros.endCard() }} | {{ macros.endCard() }} | ||||
</div> | </div> |
{% endembed %} | {% endembed %} | ||||
{% endmacro box_total_spent %} | {% endmacro box_total_spent %} | ||||
{% macro box_prepaid_account(user) %} | |||||
{% embed '@LcShop/backend/default/block/embed_figure_box.twig' %} | |||||
{% set userMerchant = creditUtils.getUserMerchant() %} | |||||
{% trans_default_domain 'lcshop' %} | |||||
{% block class %}bg-blue{% endblock %} | |||||
{% block icon %}cash-register{% endblock %} | |||||
{% block label %} | |||||
<a class="text-white" href="{{ path('easyadmin', {"action" : 'show', 'entity': 'UserMerchant', 'id': userMerchant.id}) }}"> | |||||
<i class="fa fa-pen"></i> Éditer | |||||
</a> - Solde compte prépayé | |||||
{% endblock %} | |||||
{% block value %} | |||||
{{ userMerchant.getCredit()|format_price(false) }} | |||||
{% if userMerchant.getCreditActive() ==false %} | |||||
<small>(inactif)</small> | |||||
{% endif %} | |||||
{% endblock %} | |||||
{% endembed %} | |||||
{% endmacro box_prepaid_account %} | |||||
{% macro box_average_products(user) %} | |||||
{% embed '@LcShop/backend/default/block/embed_figure_box.twig' %} | |||||
{% trans_default_domain 'lcshop' %} | |||||
{% block class %}bg-navy{% endblock %} | |||||
{% block icon %}shopping-basket{% endblock %} | |||||
{% block label %} Panier moyen{% endblock %} | |||||
{% block value %} | |||||
{{ orderUtils.getAverageProductsByUser(user)|format_price|raw }} | |||||
{% endblock %} | |||||
{% endembed %} | |||||
{% endmacro box_average_products %} | |||||
{% macro box_rank_total_order(user) %} | {% macro box_rank_total_order(user) %} | ||||
{% embed '@LcShop/backend/default/block/embed_figure_box.twig' %} | {% embed '@LcShop/backend/default/block/embed_figure_box.twig' %} | ||||
{% block class %}bg-info{% endblock %} | {% block class %}bg-info{% endblock %} |
{% block global_actions %} | {% block global_actions %} | ||||
{% if entity is not null %} | {% if entity is not null %} | ||||
{% set action = {label : "action.user.switch", icon: 'user-secret', css_class: 'btn btn-sm btn-danger'} %} | {% set action = {label : "action.user.switch", icon: 'user-secret', css_class: 'btn btn-sm btn-danger'} %} | ||||
{% include '@LcShop/backend/user/block/user-switch.html.twig' with {item: entity, is_dropdown: false, action: action, translation_domain: 'lcshop', trans_parameters: {}, item_id: entity.id}%} | |||||
{% include '@LcShop/backend/user/block/user-switch.html.twig' with {item: entity, is_dropdown: false, action: action, translation_domain: 'lcshop', trans_parameters: {}, item_id: entity.id} %} | |||||
<button id="btn-ticket-write-to-user" | <button id="btn-ticket-write-to-user" | ||||
data-url="{{ path('easyadmin', {'entity': 'Ticket', 'action': 'new'}) }}" | data-url="{{ path('easyadmin', {'entity': 'Ticket', 'action': 'new'}) }}" | ||||
<div class="col-3"> | <div class="col-3"> | ||||
{{ user_macros.card_info(entity) }} | {{ user_macros.card_info(entity) }} | ||||
</div> | </div> | ||||
<div class="col-3"> | |||||
{{ user_macros.box_rank_total_order(entity) }} | |||||
{{ user_macros.box_total_order(entity) }} | |||||
</div> | |||||
<div class="col-3"> | |||||
{{ user_macros.box_rank_sum_order(entity) }} | |||||
{{ user_macros.box_total_spent(entity) }} | |||||
</div> | |||||
<div class="col-3"> | |||||
{{ user_macros.box_register_since(entity) }} | |||||
{{ user_macros.box_login_since(entity) }} | |||||
<div class="col-9 row"> | |||||
<div class="col-3"> | |||||
{{ user_macros.box_rank_total_order(entity) }} | |||||
{{ user_macros.box_total_order(entity) }} | |||||
</div> | |||||
<div class="col-3"> | |||||
{{ user_macros.box_rank_sum_order(entity) }} | |||||
{{ user_macros.box_total_spent(entity) }} | |||||
</div> | |||||
<div class="col-3"> | |||||
{{ user_macros.box_prepaid_account(entity) }} | |||||
{{ user_macros.box_average_products(entity) }} | |||||
</div> | |||||
<div class="col-3"> | |||||
{{ user_macros.box_register_since(entity) }} | |||||
{{ user_macros.box_login_since(entity) }} | |||||
</div> | |||||
</div> | </div> | ||||
<div class="col-6"> | <div class="col-6"> | ||||
{% set redeliveries = orderUtils.getRedeliveryByUser(entity) %} | {% set redeliveries = orderUtils.getRedeliveryByUser(entity) %} |
return $content; | return $content; | ||||
} else { | } else { | ||||
// log | // log | ||||
//return $response->getContent() ; | |||||
return false; | |||||
} | } | ||||
} | } | ||||
else { | else { |
public function getPriceByRefUnitWithTaxAndReduction(ProductPropertyInterface $product) | public function getPriceByRefUnitWithTaxAndReduction(ProductPropertyInterface $product) | ||||
{ | { | ||||
return $this->applyReductionCatalog( | |||||
return ($this->getPriceByRefUnitWithTax($product) * $this->getPriceWithTaxAndReduction($product)) | |||||
/ $this->getPriceWithTax($product) ; | |||||
/*return $this->applyReductionCatalog( | |||||
$product, | $product, | ||||
$this->getPriceByRefUnit($product), | $this->getPriceByRefUnit($product), | ||||
$this->getPriceByRefUnitWithTax($product) | $this->getPriceByRefUnitWithTax($product) | ||||
); | |||||
);*/ | |||||
} | } | ||||
use Lc\ShopBundle\Context\TicketMessageInterface; | use Lc\ShopBundle\Context\TicketMessageInterface; | ||||
use Lc\ShopBundle\Context\UserInterface; | use Lc\ShopBundle\Context\UserInterface; | ||||
use Lc\ShopBundle\Model\Ticket; | use Lc\ShopBundle\Model\Ticket; | ||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||||
use Symfony\Component\HttpFoundation\File\Exception\FileException; | |||||
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; | use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; | ||||
class TicketUtils | class TicketUtils | ||||
protected $merchantUtils ; | protected $merchantUtils ; | ||||
protected $mailUtils ; | protected $mailUtils ; | ||||
protected $authorizationChecker ; | protected $authorizationChecker ; | ||||
public function __construct(EntityManagerInterface $em, MerchantUtilsInterface $merchantUtils, MailUtils $mailUtils, AuthorizationCheckerInterface $authorizationChecker) | |||||
{ | |||||
protected $parameterBag ; | |||||
public function __construct( | |||||
EntityManagerInterface $em, | |||||
MerchantUtilsInterface $merchantUtils, | |||||
MailUtils $mailUtils, | |||||
AuthorizationCheckerInterface $authorizationChecker, | |||||
ParameterBagInterface $parameterBag | |||||
) { | |||||
$this->em = $em ; | $this->em = $em ; | ||||
$this->merchantUtils = $merchantUtils ; | $this->merchantUtils = $merchantUtils ; | ||||
$this->mailUtils = $mailUtils ; | $this->mailUtils = $mailUtils ; | ||||
$this->authorizationChecker = $authorizationChecker ; | $this->authorizationChecker = $authorizationChecker ; | ||||
$this->parameterBag = $parameterBag ; | |||||
} | } | ||||
public function getTicketsByUser($user){ | public function getTicketsByUser($user){ | ||||
return $ticketRepo->findBy(array('user'=>$user)); | return $ticketRepo->findBy(array('user'=>$user)); | ||||
} | } | ||||
public function uploadImageTicketMessage($formTicket) | |||||
{ | |||||
$image = $formTicket->get('image')->getData(); | |||||
if ($image) { | |||||
$originalFilename = pathinfo($image->getClientOriginalName(), PATHINFO_FILENAME); | |||||
$newFilename = uniqid().'.' . $image->guessExtension(); | |||||
try { | |||||
$image->move( | |||||
$this->parameterBag->get('app.ticket_images_directory'), | |||||
$newFilename | |||||
); | |||||
} | |||||
catch (FileException $e) { | |||||
throw new \ErrorException("Une erreur est survenue lors de l'upload du fichier."); | |||||
} | |||||
return $this->parameterBag->get('app.ticket_images_subdirectory').$newFilename ; | |||||
} | |||||
return false ; | |||||
} | |||||
public function createTicket($params): TicketInterface | public function createTicket($params): TicketInterface | ||||
{ | { | ||||
$classTicket = $this->em->getClassMetadata(TicketInterface::class)->getName() ; | $classTicket = $this->em->getClassMetadata(TicketInterface::class)->getName() ; | ||||
$ticketMessage->setStatus(1) ; | $ticketMessage->setStatus(1) ; | ||||
$ticketMessage->setTicket($ticket) ; | $ticketMessage->setTicket($ticket) ; | ||||
$ticketMessage->setMessage($params['message']) ; | $ticketMessage->setMessage($params['message']) ; | ||||
if(isset($params['createByAdmin']) && $params['createByAdmin'])$ticketMessage->setAnswerByAdmin(true); | |||||
if(isset($params['imageFilename']) && $params['imageFilename']) { | |||||
$ticketMessage->setImageFilename($params['imageFilename']); | |||||
} | |||||
if(isset($params['createByAdmin']) && $params['createByAdmin']) { | |||||
$ticketMessage->setAnswerByAdmin(true); | |||||
} | |||||
$this->em->persist($ticketMessage); | $this->em->persist($ticketMessage); | ||||
$this->em->flush() ; | $this->em->flush() ; |
return $phone ; | return $phone ; | ||||
} | } | ||||
public function getMetaTitle($entity) | |||||
{ | |||||
if($entity) { | |||||
if(method_exists($entity, 'getMetaTitle')) { | |||||
return $entity->getMetaTitle() ; | |||||
} | |||||
elseif(method_exists($entity, 'getTitle')) { | |||||
return $entity->getTitle() ; | |||||
} | |||||
} | |||||
return '' ; | |||||
} | |||||
public function getMetaDescription($entity) | |||||
{ | |||||
if($entity) { | |||||
if(method_exists($entity, 'getMetaDescription')) { | |||||
return $entity->getMetaDescription() ; | |||||
} | |||||
elseif(method_exists($entity, 'getDescription')) { | |||||
return $entity->getDescription() ; | |||||
} | |||||
} | |||||
return '' ; | |||||
} | |||||
public function getOpenGraphTitle($entity) | |||||
{ | |||||
if($entity) { | |||||
if(method_exists($entity, 'getOpenGraphTitle')) { | |||||
return $entity->getOpenGraphTitle() ; | |||||
} | |||||
elseif(method_exists($entity, 'getTitle')) { | |||||
return $entity->getTitle() ; | |||||
} | |||||
} | |||||
return '' ; | |||||
} | |||||
public function getOpenGraphDescription($entity) | |||||
{ | |||||
if($entity) { | |||||
if(method_exists($entity, 'getOpenGraphDescription')) { | |||||
return $entity->getOpenGraphDescription() ; | |||||
} | |||||
elseif(method_exists($entity, 'getDescription')) { | |||||
return $entity->getDescription() ; | |||||
} | |||||
} | |||||
return '' ; | |||||
} | |||||
public function getOpenGraphImage($entity) | |||||
{ | |||||
if($entity) { | |||||
if(method_exists($entity, 'getOpenGraphImage')) { | |||||
return $entity->getOpenGraphImage() ; | |||||
} | |||||
elseif(method_exists($entity, 'getImage')) { | |||||
return $entity->getImage() ; | |||||
} | |||||
} | |||||
return '' ; | |||||
} | |||||
} | } |
if ($entity->getImage() && file_exists($basePath . $entity->getImage())) { | if ($entity->getImage() && file_exists($basePath . $entity->getImage())) { | ||||
$extension = (pathinfo($basePath . $entity->getImage(), PATHINFO_EXTENSION)); | |||||
$extension = strtolower(pathinfo($basePath . $entity->getImage(), PATHINFO_EXTENSION)); | |||||
if ($extension == "jpg" || $extension == "png" || $extension == "gif") { | if ($extension == "jpg" || $extension == "png" || $extension == "gif") { | ||||
$newImage = md5(uniqid()) . '.' . $extension; | $newImage = md5(uniqid()) . '.' . $extension; | ||||
if ($folder) $newImage = $folder . '/' . $newImage; | if ($folder) $newImage = $folder . '/' . $newImage; | ||||
copy($basePath . $entity->getImage(), $basePath . $newImage); | copy($basePath . $entity->getImage(), $basePath . $newImage); | ||||
$entity->setImage($newImage); | $entity->setImage($newImage); | ||||
}else{ | |||||
$entity->setImage(null); | |||||
} | } | ||||
} else { | } else { | ||||
$entity->setImage(null); | $entity->setImage(null); |
<?php | |||||
namespace Lc\ShopBundle\Statistic; | |||||
use Lc\ShopBundle\Manager\EntityManager; | |||||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||||
class Statistic | |||||
{ | |||||
protected $properties = array(); | |||||
protected $averageProperties = array(); | |||||
protected $labels; | |||||
protected $dateStart; | |||||
protected $dateEnd; | |||||
protected $interval; | |||||
protected $em; | |||||
protected $resultsSort; | |||||
public function __construct(EntityManager $entityManager, ?\DateTime $dateStart = null, ?\DateTime $dateEnd = null, ?string $interval = null) | |||||
{ | |||||
$this->em = $entityManager; | |||||
$this->dateStart = $dateStart; | |||||
$this->dateEnd = $dateEnd; | |||||
$this->interval = $interval; | |||||
} | |||||
public function addProperty(string $propertyName, array $options) | |||||
{ | |||||
$resolver = new OptionsResolver(); | |||||
$this->configurePropertyOptions($resolver); | |||||
$this->properties[$propertyName] = $resolver->resolve($options); | |||||
$this->resultsSort[$propertyName] = $propertyName; | |||||
} | |||||
public function addAverageProperty(string $propertyName, array $options) | |||||
{ | |||||
$resolver = new OptionsResolver(); | |||||
$this->configurePropertyOptions($resolver); | |||||
$this->averageProperties[$propertyName] = $resolver->resolve($options); | |||||
$this->resultsSort[$propertyName] = $propertyName; | |||||
} | |||||
public function setAverageData(string $propertyName, string $key, $value) | |||||
{ | |||||
if (isset($this->averageProperties[$propertyName])) { | |||||
$this->averageProperties[$propertyName]['data'][$key] += number_format($value, 2); | |||||
} else { | |||||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||||
} | |||||
} | |||||
public function setData(string $propertyName, string $key, $value) | |||||
{ | |||||
if (isset($this->properties[$propertyName])) { | |||||
$this->properties[$propertyName]['data'][$key] += number_format($value, 2); | |||||
$this->properties[$propertyName]['total_period'] += number_format($value, 2); | |||||
} else { | |||||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||||
} | |||||
} | |||||
public function setAveragePropertiesData() | |||||
{ | |||||
foreach ($this->getLabels() as $key => $label) { | |||||
foreach ($this->getAverageProperties() as $averagePropertyName => $averageProperty) { | |||||
if ($this->getData($averageProperty['divider'], $key)) { | |||||
$this->setAverageData($averagePropertyName, $key, $this->getData($averageProperty['dividend'], $key) / $this->getData($averageProperty['divider'], $key)); | |||||
} | |||||
if ($this->getTotalPeriod($averageProperty['divider'])) { | |||||
$this->averageProperties[$averagePropertyName]['total_period'] = $this->getTotalPeriod($averageProperty['dividend']) / $this->getTotalPeriod($averageProperty['divider']); | |||||
} | |||||
} | |||||
} | |||||
foreach ($this->getProperties() as $propertyName => $property) { | |||||
$this->properties[$propertyName]['average_period'] = number_format($this->properties[$propertyName]['total_period'] / count($this->getLabels()),2); | |||||
} | |||||
foreach ($this->getAverageProperties() as $averagePropertyName => $averageProperty) { | |||||
$this->averageProperties[$averagePropertyName]['average_period'] = number_format($this->averageProperties[$averagePropertyName]['total_period'] / count($this->getLabels()), 2); | |||||
} | |||||
} | |||||
public function getLabels() | |||||
{ | |||||
return $this->labels; | |||||
} | |||||
public function getProperties() | |||||
{ | |||||
return $this->properties; | |||||
} | |||||
public function getData($propertyName, $key) | |||||
{ | |||||
if (!isset($this->properties[$propertyName])) { | |||||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||||
} | |||||
return $this->properties[$propertyName]['data'][$key]; | |||||
} | |||||
public function getTotalPeriod($propertyName) | |||||
{ | |||||
if (!isset($this->properties[$propertyName])) { | |||||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||||
} | |||||
return $this->properties[$propertyName]['total_period']; | |||||
} | |||||
public function getAverageProperties() | |||||
{ | |||||
return $this->averageProperties; | |||||
} | |||||
public function getResults() | |||||
{ | |||||
$results = array_replace($this->resultsSort, $this->properties, $this->averageProperties); | |||||
return $results; | |||||
} | |||||
public function getAsArray() | |||||
{ | |||||
return array( | |||||
'label' => $this->getLabels(), | |||||
'data' => $this->getResults(), | |||||
); | |||||
} | |||||
public function getDateRange() | |||||
{ | |||||
return new \DatePeriod($this->getDateStart(), new \DateInterval('P1' . $this->getInterval()), $this->getDateEnd()); | |||||
} | |||||
public function getDateStart() | |||||
{ | |||||
return $this->dateStart; | |||||
} | |||||
public function getDateEnd() | |||||
{ | |||||
return $this->dateEnd; | |||||
} | |||||
public function getInterval() | |||||
{ | |||||
return $this->interval; | |||||
} | |||||
public function configurePropertyOptions(OptionsResolver $resolver) | |||||
{ | |||||
$resolver->setDefaults([ | |||||
'unit' => '', | |||||
'label' => 'Chiffre affaire produit', | |||||
'label_short' => 'CA produit', | |||||
'data' => array(), | |||||
'total_period' => 0, | |||||
'average_period' => 0, | |||||
'dividend' => null, | |||||
'divider' => null, | |||||
]); | |||||
} | |||||
} |