Quellcode durchsuchen

[Backend] Statisques produit et commandes

develop
Fab vor 3 Jahren
Ursprung
Commit
4e9d6824a0
11 geänderte Dateien mit 110 neuen und 367 gelöschten Zeilen
  1. +13
    -2
      ShopBundle/Controller/Backend/ProductFamilyController.php
  2. +19
    -0
      ShopBundle/Model/ProductFamily.php
  3. +23
    -11
      ShopBundle/Resources/public/js/backend/script/default/init-common.js
  4. +5
    -1
      ShopBundle/Resources/translations/lcshop.fr.yaml
  5. +2
    -0
      ShopBundle/Resources/views/backend/default/field/product_family_sales.html.twig
  6. +0
    -2
      ShopBundle/Resources/views/backend/default/field/product_family_total_product_ordered.html.twig
  7. +0
    -316
      ShopBundle/Resources/views/backend/productfamily/advanced_edition.html.twig
  8. +22
    -19
      ShopBundle/Resources/views/backend/productfamily/macros.html.twig
  9. +1
    -1
      ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig
  10. +3
    -1
      ShopBundle/Resources/views/backend/productfamily/panel_stock.html.twig
  11. +22
    -14
      ShopBundle/Statistic/Statistic.php

+ 13
- 2
ShopBundle/Controller/Backend/ProductFamilyController.php Datei anzeigen

@@ -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]);

+ 19
- 0
ShopBundle/Model/ProductFamily.php Datei anzeigen

@@ -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()) {

+ 23
- 11
ShopBundle/Resources/public/js/backend/script/default/init-common.js Datei anzeigen

@@ -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

+ 5
- 1
ShopBundle/Resources/translations/lcshop.fr.yaml Datei anzeigen

@@ -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

+ 2
- 0
ShopBundle/Resources/views/backend/default/field/product_family_sales.html.twig Datei anzeigen

@@ -0,0 +1,2 @@
{% import '@LcShop/backend/productfamily/macros.html.twig' as macros %}
{{ macros.product_family_sales_statistic(orderUtils.getProductsSalesStatistic(item, 2), item) }}

+ 0
- 2
ShopBundle/Resources/views/backend/default/field/product_family_total_product_ordered.html.twig Datei anzeigen

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

+ 0
- 316
ShopBundle/Resources/views/backend/productfamily/advanced_edition.html.twig Datei anzeigen

@@ -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 %}

+ 22
- 19
ShopBundle/Resources/views/backend/productfamily/macros.html.twig Datei anzeigen

@@ -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>


+ 1
- 1
ShopBundle/Resources/views/backend/productfamily/panel_products.html.twig Datei anzeigen

@@ -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 %}


+ 3
- 1
ShopBundle/Resources/views/backend/productfamily/panel_stock.html.twig Datei anzeigen

@@ -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>


+ 22
- 14
ShopBundle/Statistic/Statistic.php Datei anzeigen

@@ -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,
]);

Laden…
Abbrechen
Speichern