@@ -97,6 +97,17 @@ class ProductFamilyController extends AdminController | |||
'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( | |||
'data' => $entity->getBehaviorAddToCart() ? $entity->getBehaviorAddToCart() : 'simple', | |||
'choices' => array( | |||
@@ -279,7 +290,7 @@ class ProductFamilyController extends AdminController | |||
'entity' => $entity, | |||
'delete_form' => $deleteForm->createView(), | |||
'sortableProductsField' => $sortableProductsField, | |||
'totalProductOrdered' => $this->orderUtils->getTotalProductOrderedLastWeeks($entity) | |||
'productsSalesStatistic' => $this->orderUtils->getProductsSalesStatistic($entity) | |||
]; | |||
return $this->executeDynamicMethod('render<EntityName>Template', ['edit', $this->entity['templates']['edit'], $parameters]); | |||
@@ -335,7 +346,7 @@ class ProductFamilyController extends AdminController | |||
'entity' => $entity, | |||
'categories' => $categories, | |||
'sortableProductsField' => array(), | |||
'totalProductOrdered' => array('total'=>0) | |||
'productsSalesStatistic' => null | |||
]; | |||
return $this->executeDynamicMethod('render<EntityName>Template', ['new', $this->entity['templates']['new'], $parameters]); |
@@ -26,6 +26,9 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
const BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY = 'by-product-family' ; | |||
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_VALIDATION = 'renewable-with-validation'; | |||
const BEHAVIOR_STOCK_WEEK_NON_RENEWABLE = 'non-renewable'; | |||
@@ -141,6 +144,11 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
*/ | |||
protected $behaviorCountStock; | |||
/** | |||
* @ORM\Column(type="string", length=255) | |||
*/ | |||
protected $behaviorDisplaySale; | |||
/** | |||
* @ORM\Column(type="date", nullable=true) | |||
*/ | |||
@@ -541,6 +549,17 @@ abstract class ProductFamily extends AbstractDocumentEntity implements ProductPr | |||
return $this; | |||
} | |||
public function getBehaviorDisplaySale(): ?string | |||
{ | |||
return $this->behaviorDisplaySale; | |||
} | |||
public function setBehaviorDisplaySale(string $behaviorDisplaySale): self | |||
{ | |||
$this->behaviorDisplaySale = $behaviorDisplaySale; | |||
return $this; | |||
} | |||
public function isPropertyNoveltyOnline(): ?bool | |||
{ | |||
if ($this->getPropertyNoveltyExpirationDate()) { |
@@ -362,30 +362,42 @@ function resetNumItemsCollectionField($collectionWidget){ | |||
function initBtnShowTotalOrderProduct(){ | |||
log( $('.lc-show-total-order-product')); | |||
$('.lc-show-total-order-product').on('click', function (){ | |||
log( $('.lc-show-products-sales-statistic')); | |||
$('.lc-show-products-sales-statistic').on('click', function (){ | |||
$btn = $(this); | |||
var url = $(this).data('url'); | |||
$('#modal-total-order').remove(); | |||
$('#modal-products-sales-statistic').remove(); | |||
$.ajax({ | |||
url: url, | |||
method: "POST", | |||
dataType: "json", | |||
success: function (response) { | |||
$('body').append(response.data); | |||
$('#modal-total-order').modal('show'); | |||
initModalTotalOrderProduct(response.statistics); | |||
$('#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 initModalTotalOrderProduct(statistics) { | |||
chart = drawTotalOrderProduct(statistics) | |||
} | |||
function drawTotalOrderProduct(statictics) { | |||
log(statictics); | |||
function drawProductsSalesStatistic(statictics, propertyName) { | |||
var options = { | |||
bezierCurve : false, | |||
tooltips: { | |||
@@ -400,8 +412,8 @@ log(statictics); | |||
"data": { | |||
"labels": Object.values(statictics.label), | |||
"datasets": [{ | |||
"label": "Total commandés/semaines ( En moyenne :"+statictics.total_average+')', | |||
"data": Object.values(statictics.total), | |||
"label": "Vente de produits / semaine", | |||
"data": Object.values(statictics.data[propertyName].data), | |||
"fill": false, | |||
"borderColor": "rgb(75, 192, 192)", | |||
"lineTension": 0.1 |
@@ -338,6 +338,7 @@ field: | |||
availableQuantityDefault: Quantité par défaut | |||
quantity: Quantité | |||
behaviorCountStock: Gestion du stock | |||
behaviorDisplaySale: Affichage du total des ventes | |||
differentSupplierTaxRate: TVA différente pour le producteur | |||
supplierTaxRate: TVA du producteur | |||
propertyNoveltyExpirationDateActive: Marquer le produit comme "nouveauté" jusqu'au | |||
@@ -362,6 +363,9 @@ field: | |||
by-product-family: Gérer le stock par produit (à l'unité) | |||
by-product: Gérer le stock par déclainaison | |||
unlimited: Illimité | |||
behaviorDisplaySaleOptions: | |||
by-measure: Par unité de référence | |||
by-quantity: Par quantité | |||
behaviorStockWeek: Renouvelement du stock chaque semaine | |||
behaviorStockWeekOptions: | |||
renewable: Renouvelable | |||
@@ -546,7 +550,7 @@ action: | |||
product: | |||
editStock: Gérer les stocks | |||
editProductFamily: Éditer le produit | |||
totalOrder: Afficher plus de semaines | |||
statSales: Afficher plus de semaines | |||
user: | |||
account: Mon compte | |||
logout: Me déconnecter |
@@ -0,0 +1,2 @@ | |||
{% import '@LcShop/backend/productfamily/macros.html.twig' as macros %} | |||
{{ macros.product_family_sales_statistic(orderUtils.getProductsSalesStatistic(item, 2), item) }} |
@@ -1,2 +0,0 @@ | |||
{% import '@LcShop/backend/productfamily/macros.html.twig' as macros %} | |||
{{ macros.total_order_product_family(orderUtils.getTotalProductOrderedLastWeeks(item, 2, true)['total'], item, true) }} |
@@ -1,316 +0,0 @@ | |||
{% 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 %} |
@@ -1,7 +1,7 @@ | |||
{% 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-info"><i class="fa fa-shopping-basket"></i> | |||
<strong> | |||
@@ -10,28 +10,31 @@ | |||
</span> | |||
<br/> | |||
{% endfor %} | |||
{% endmacro total_order_product %} | |||
{% macro total_order_product_family(totalProductOrdered, productFamily,forceByMeasure = false) %} | |||
<button type="button" data-product-family="{{ productFamily.id }}" class="lc-show-total-order-product btn btn-sm" | |||
data-toggle="tooltip" title="{{ 'action.product.totalOrder'|trans }}" | |||
data-url="{{ path('easyadmin', { action: 'showTotalOrder', entity: 'ProductFamily', id: productFamily.id }) }}"> | |||
{% 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> | |||
{{ weekNumberQuantity is null ? 0 : weekNumberQuantity }} | |||
{% if productFamily and (productFamily.behaviorCountStock== constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE') or forceByMeasure) %} | |||
{% if productFamily and (productFamily.behaviorDisplaySale== constant('Lc\\ShopBundle\\Model\\ProductFamily::BEHAVIOR_DISPLAY_SALE_BY_MEASURE')) %} | |||
{{ productFamily.unit.unitReference }} | |||
{% endif %} | |||
</strong> | |||
</span> | |||
<br/> | |||
{% endfor %} | |||
</button> | |||
<br/> | |||
{% endfor %} | |||
</button> | |||
{% endif %} | |||
{% endmacro total_order_product_family %} | |||
{% endmacro product_family_sales_statistic %} | |||
@@ -69,7 +72,7 @@ | |||
</td> | |||
{% endmacro %} | |||
{% macro product_row(product, totalProductOrdered) %} | |||
{% macro product_row(product, productsSalesStatistic) %} | |||
<tr class="lc-draggable" v-show="originProduct != true && status >= 0 "> | |||
<td> | |||
@@ -130,7 +133,7 @@ | |||
<td colspan="2"> | |||
{{ _self.total_order_product(totalProductOrdered) }} | |||
{{ _self.product_sales_statistic(productsSalesStatistic) }} | |||
</td> | |||
@@ -264,7 +264,7 @@ | |||
{# {% if product.vars.value.giftVoucherReductionCart %}giftVoucherReductionCart: {{ product.vars.value.giftVoucherReductionCart.id }},{% endif %} #} | |||
{# {% if product.vars.value.expirationDate %}expirationDate: "{{ product.vars.value.expirationDate|date('d/m/Y') }}"{% endif %} #} | |||
}; | |||
window.formProductTemplate[{{ keyForm }}] = '{{ product_family_macros.product_row(product, totalProductOrdered[product.vars.value.id])|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; | |||
window.formProductTemplate[{{ keyForm }}] = '{{ product_family_macros.product_row(product, productsSalesStatistic['data'][product.vars.value.id]['data'])|replace({"\n":' ', "\r":' ', "'" : "\\'"})|raw }}'; | |||
{# {% endif %} #} | |||
{% endfor %} | |||
@@ -33,6 +33,8 @@ | |||
{% endif %} | |||
{% endfor %} | |||
{{ form_row(form.behaviorDisplaySale) }} | |||
</div> | |||
<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') }}'" | |||
@@ -62,7 +64,7 @@ | |||
</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') }}' "> | |||
{{ product_family_macros.total_order_product_family(totalProductOrdered['total'], entity) }} | |||
{{ product_family_macros.product_family_sales_statistic(productsSalesStatistic, entity) }} | |||
</p> | |||
</div> | |||
@@ -4,14 +4,13 @@ | |||
namespace Lc\ShopBundle\Statistic; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\ShopBundle\Manager\EntityManager; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
class Statistic | |||
{ | |||
protected $properties; | |||
protected $averageProperties; | |||
protected $properties = array(); | |||
protected $averageProperties = array(); | |||
protected $labels; | |||
protected $dateStart; | |||
protected $dateEnd; | |||
@@ -19,7 +18,7 @@ class Statistic | |||
protected $em; | |||
protected $resultsSort; | |||
public function __construct(EntityManagerInterface $entityManager, ?\DateTime $dateStart, ? \DateTime $dateEnd, ? string $interval) | |||
public function __construct(EntityManager $entityManager, ?\DateTime $dateStart = null, ?\DateTime $dateEnd = null, ?string $interval = null) | |||
{ | |||
$this->em = $entityManager; | |||
$this->dateStart = $dateStart; | |||
@@ -32,7 +31,7 @@ class Statistic | |||
$resolver = new OptionsResolver(); | |||
$this->configurePropertyOptions($resolver); | |||
$this->properties[$propertyName] = $resolver->resolve($options); | |||
$this->resultsSort[$propertyName] =$propertyName; | |||
$this->resultsSort[$propertyName] = $propertyName; | |||
} | |||
public function addAverageProperty(string $propertyName, array $options) | |||
@@ -40,25 +39,27 @@ class Statistic | |||
$resolver = new OptionsResolver(); | |||
$this->configurePropertyOptions($resolver); | |||
$this->averageProperties[$propertyName] = $resolver->resolve($options); | |||
$this->resultsSort[$propertyName] =$propertyName; | |||
$this->resultsSort[$propertyName] = $propertyName; | |||
} | |||
public function setAverageData(string $propertyName, string $key, $value){ | |||
if (isset($this->averageProperties[$propertyName]) ) { | |||
public function setAverageData(string $propertyName, string $key, $value) | |||
{ | |||
if (isset($this->averageProperties[$propertyName])) { | |||
$this->averageProperties[$propertyName]['data'][$key] += number_format($value, 2); | |||
}else{ | |||
} else { | |||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||
} | |||
} | |||
public function setData(string $propertyName, string $key, $value) | |||
{ | |||
if (isset($this->properties[$propertyName])){ | |||
if (isset($this->properties[$propertyName])) { | |||
$this->properties[$propertyName]['data'][$key] += number_format($value, 2); | |||
$this->properties[$propertyName]['total_period'] += number_format($value, 2); | |||
}else{ | |||
} else { | |||
throw new \Exception('La proprieté "' . $propertyName . '" n\'existe pas '); | |||
} | |||
@@ -78,7 +79,12 @@ class Statistic | |||
} | |||
} | |||
} | |||
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); | |||
} | |||
} | |||
@@ -118,11 +124,12 @@ class Statistic | |||
public function getResults() | |||
{ | |||
$results = array_merge($this->resultsSort, $this->properties, $this->averageProperties); | |||
$results = array_replace($this->resultsSort, $this->properties, $this->averageProperties); | |||
return $results; | |||
} | |||
public function getAsArray(){ | |||
public function getAsArray() | |||
{ | |||
return array( | |||
'label' => $this->getLabels(), | |||
'data' => $this->getResults(), | |||
@@ -157,6 +164,7 @@ class Statistic | |||
'label_short' => 'CA produit', | |||
'data' => array(), | |||
'total_period' => 0, | |||
'average_period' => 0, | |||
'dividend' => null, | |||
'divider' => null, | |||
]); |