Преглед на файлове

Merge branch 'develop'

master
Guillaume Bourgeois преди 10 месеца
родител
ревизия
58133f6ee5
променени са 34 файла, в които са добавени 534 реда и са изтрити 287 реда
  1. +4
    -5
      backend/controllers/StatsController.php
  2. +9
    -5
      backend/models/MailForm.php
  3. +1
    -1
      backend/views/dashboard/index.php
  4. +10
    -0
      backend/views/distribution/index.php
  5. +1
    -1
      backend/views/distribution/shopping-cart-labels.php
  6. +1
    -1
      backend/views/document/_download_product_line.php
  7. +4
    -3
      backend/views/layouts/header.php
  8. +1
    -2
      backend/views/layouts/left.php
  9. +3
    -2
      backend/views/point-sale/_form.php
  10. +1
    -24
      backend/views/producer/billing.php
  11. +1
    -1
      backend/views/producer/update.php
  12. +130
    -127
      backend/views/product/_form.php
  13. +14
    -1
      backend/views/stats/index.php
  14. +6
    -2
      backend/views/subscription/_form.php
  15. +3
    -2
      backend/views/user/_form.php
  16. +34
    -12
      backend/web/css/screen.css
  17. +7
    -0
      backend/web/js/vuejs/distribution-index.js
  18. +24
    -1
      backend/web/sass/_adminlte.scss
  19. +1
    -1
      common/config/params.php
  20. +12
    -3
      common/helpers/Image.php
  21. +1
    -1
      common/logic/Distribution/Distribution/Export/DistributionReportCsvGenerator.php
  22. +7
    -1
      common/logic/Distribution/Distribution/Export/DistributionReportPdfGenerator.php
  23. +36
    -1
      common/logic/Distribution/Distribution/Export/DistributionShoppingCartLabelsPdfGenerator.php
  24. +10
    -3
      common/logic/Order/Order/Service/TillerManager.php
  25. +18
    -3
      common/logic/Order/ProductOrder/Service/ProductOrderSolver.php
  26. +43
    -13
      common/logic/Producer/Producer/Repository/ProducerRepository.php
  27. +5
    -1
      common/logic/Product/Product/Service/ProductSolver.php
  28. +1
    -2
      common/logic/Subscription/Subscription/Repository/SubscriptionRepository.php
  29. +3
    -9
      common/logic/Subscription/Subscription/Repository/SubscriptionRepositoryQuery.php
  30. +4
    -1
      common/logic/User/User/Service/UserSolver.php
  31. +27
    -0
      common/versions/23.12.B.php
  32. +29
    -0
      common/versions/23.12.C.php
  33. +81
    -57
      frontend/views/site/_prices_producer.php
  34. +2
    -1
      producer/views/layouts/main.php

+ 4
- 5
backend/controllers/StatsController.php Целия файл

@@ -67,19 +67,18 @@ class StatsController extends BackendController
/**
* Affiche le CA réalisé par mois sur une année donnée
*/
public function actionIndex(int $year = null)
public function actionIndex(int $year = null, string $displayBy = 'month')
{
$producerModule = $this->getProducerModule();
$producerCurrent = $this->getProducerCurrent();

if(!$year) {
$year = date('Y');
}

$yearsWithTurnoverArray = $producerModule->getYearsWithTurnover($producerCurrent);
$dataChartTurnover = $producerModule->getDatasChartTurnoverStatistics($producerCurrent, $year);
$yearsWithTurnoverArray = $this->getProducerModule()->getRepository()->getYearsWithTurnover($producerCurrent);
$dataChartTurnover = $this->getProducerModule()->getRepository()->getDatasChartTurnoverStatistics($producerCurrent, $year, $displayBy);

return $this->render('index', [
'displayBy' => $displayBy,
'yearCurrent' => $year,
'dataLabels' => $dataChartTurnover['labels'],
'data' => $dataChartTurnover['data'],

+ 9
- 5
backend/models/MailForm.php Целия файл

@@ -174,15 +174,19 @@ Produits disponibles :
$fromEmail = $producerModule->getEmailOpendistrib($producer) ;
$fromName = $producer->name ;

$linkProducer = 'https://'.$producer->slug.'.opendistrib.net';
$linkUnsubscribe = Yii::$app->urlManagerProducer->createAbsoluteUrl(['newsletter/unsubscribe', 'slug_producer' => $producer->slug]);

// Message inscription newsletter
$messageAutoText .= "

--
Boutique : ".$linkProducer."
Me désinscrire : ".$linkUnsubscribe;

Me désinscrire de ce bulletin d'information :
".Yii::$app->urlManagerProducer->createAbsoluteUrl(['newsletter/index', 'slug_producer' => $producer->slug]);

$messageAutoHtml .= "<br /><br />--<br /><br /><a href=\"".Yii::$app->urlManagerProducer->createAbsoluteUrl(['newsletter/unsubscribe', 'slug_producer' => $producer->slug])."\">Me désinscrire</a> de ce bulletin d'information";
$messageAutoHtml .= "<br /><br />--<br>";
$messageAutoHtml .= "Boutique : <a href=\"".$linkProducer."\">".$linkProducer."</a><br>";
$messageAutoHtml .= "Me désinscrire : <a href=\"".$linkUnsubscribe."\">".$linkUnsubscribe."</a>";
}
else {
$fromEmail = 'contact@opendistrib.net' ;
@@ -191,7 +195,7 @@ Me désinscrire de ce bulletin d'information :

// Tests
/*$usersArray = [
['email' => '', 'name' => '', 'lastname' => '']
['email' => 'contact@guillaumebourgeois.fr', 'name' => '', 'lastname' => '']
];*/

foreach($usersArray as $user) {

+ 1
- 1
backend/views/dashboard/index.php Целия файл

@@ -147,7 +147,7 @@ $this->setTitle('Tableau de bord');
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Derniers abonnements créés
Derniers abonnements créés/modifiés
</h3>
</div>
<div class="panel-body">

+ 10
- 0
backend/views/distribution/index.php Целия файл

@@ -294,6 +294,11 @@ $this->setPageTitle('Distributions') ;
<button id="btn-add-subscriptions" @click="addSubscriptions" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span> Importer les abonnements</button>
<template v-if="producer && producer.tiller == true">
<button v-if="tillerIsSynchro" id="btn-tiller" class="btn btn-success btn-xs" disabled><span class="glyphicon glyphicon-refresh"></span> Synchronisé avec Tiller</button>
<template v-else-if="!isDistributionToday()">
<span data-toggle="tooltip" data-placement="top" data-original-title="Synchronisation possible uniquement le jour de la distribution">
<button id="btn-tiller" class="btn btn-xs btn-default" disabled><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button>
</span>
</template>
<button v-else id="btn-tiller" class="btn btn-xs btn-default" @click="synchroTiller"><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button>
</template>
<button v-if="producer && producer.credit" id="btn-pay-orders" class="btn btn-default btn-xs" @click="payOrders"><span class="glyphicon glyphicon-euro"></span> Débiter les commandes</button>
@@ -443,6 +448,11 @@ $this->setPageTitle('Distributions') ;
<span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par virement') }}
</a>
</li>
<li>
<a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="credit-card">
<span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par carte bancaire') }}
</a>
</li>
</template>
</template>
<li>

+ 1
- 1
backend/views/distribution/shopping-cart-labels.php Целия файл

@@ -8,7 +8,7 @@ $i = 0;
foreach($ordersArray as $key => $order) {
$index ++;

echo $distributionShoppingCartLabelsPdfGenerator->getShoppingCartLabelAsHtml($order, $index);
echo $distributionShoppingCartLabelsPdfGenerator->getShoppingCartLabelAsHtml($order, $index, $isSpecificFormat);

if($index == $shoppingCartLabelsPerColumn) {
$index = 0;

+ 1
- 1
backend/views/document/_download_product_line.php Целия файл

@@ -38,7 +38,7 @@ $unitModule = UnitModule::getInstance();
<?php if($displayPrices): ?>
<td class="align-center column-unit-price">
<?php $displayPriceUnitReference = $producerModule->getSolver()->getConfig('option_document_display_price_unit_reference'); ?>
<?php $priceUnitReference = $productOrderModule->getSolver()->getPriceUnitReference($productOrder); ?>
<?php $priceUnitReference = $productOrderModule->getSolver()->getPriceUnitReference($productOrder, true); ?>
<?php $priceUnitReferenceString = Price::format($priceUnitReference, $documentPriceDecimals).' / kg' ?>
<?php if($productOrder->unit == 'piece'): ?>
<?= Price::format($price, $documentPriceDecimals) ?>

+ 4
- 3
backend/views/layouts/header.php Целия файл

@@ -36,6 +36,7 @@
* termes.
*/

use common\helpers\Image;
use common\helpers\Price;
use common\logic\Producer\Producer\Module\ProducerModule;
use common\logic\User\User\Module\UserModule;
@@ -62,8 +63,8 @@ $userCurrent = GlobalParam::getCurrentUser();
<span class="sr-only">Toggle navigation</span>
</a>

<span class="producer-panel<?php if(!$producer->logo): ?> without-logo<?php endif; ?>">
<?php if($producer->logo): ?>
<span class="producer-panel<?php if(!$producer->logo || !Image::isPhotoExist($producer->logo)): ?> without-logo<?php endif; ?>">
<?php if($producer->logo && Image::isPhotoExist($producer->logo)): ?>
<span class="logo">
<img class="img-logo"
src="<?= Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl; ?>/uploads/<?= $producer->logo; ?>"
@@ -284,7 +285,7 @@ $userCurrent = GlobalParam::getCurrentUser();
</a>
<ul class="dropdown-menu">
<li><a href="<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/index']); ?>"><i
class="fa fa-chevron-left"></i> Retour à l'accueil</a></li>
class="fa fa-home"></i> Retour à l'accueil</a></li>
<li><a href="<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['user/update']); ?>"><i
class="fa fa-user"></i> Mon profil</a></li>
<li><a href="<?= Yii::$app->urlManagerBackend->createUrl(['site/logout']); ?>"><i

+ 1
- 2
backend/views/layouts/left.php Целия файл

@@ -159,6 +159,7 @@ $isUserCurrentGrantedAsProducer = $userModule->getAuthorizationChecker()->isGran
'visible' => $isUserCurrentGrantedAsProducer && Yii::$app->parameterBag->get('dolibarrApiKey'),
'active' => Yii::$app->controller->id == 'producer-invoice',
],
['label' => 'Tarifs & modules', 'icon' => 'euro', 'url' => ['/producer/billing'], 'visible' => $isUserCurrentGrantedAsProducer],
[
'label' => 'Développement',
'icon' => 'code',
@@ -167,8 +168,6 @@ $isUserCurrentGrantedAsProducer = $userModule->getAuthorizationChecker()->isGran
'active' => Yii::$app->controller->id == 'development',
'template' => '<a href="{url}">{icon} {label}' . $newVersionOpendistribLabel . '</a>'
],
['label' => 'Tarifs', 'icon' => 'euro', 'url' => ['/producer/billing'], 'visible' => $isUserCurrentGrantedAsProducer],

['label' => 'Administration', 'options' => ['class' => 'header'], 'visible' => $isUserCurrentGrantedAsAdministrator],
[
'label' => 'Tickets',

+ 3
- 2
backend/views/point-sale/_form.php Целия файл

@@ -173,8 +173,9 @@ $distributionModule = DistributionModule::getInstance();
</div>
<div class="clr"></div>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<div class="form-group form-actions">
<?= Html::a('Retour', ['point-sale/index'], ['class' => 'btn btn-default']) ?>
<?= Html::submitButton($model->isNewRecord ? 'Créer' : 'Modifier', ['class' => 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>

+ 1
- 24
backend/views/producer/billing.php Целия файл

@@ -41,34 +41,11 @@ use common\helpers\Price;
$producerModule = $this->getProducerModule();
$producerPriceRangeModule = $this->getProducerPriceRangeModule();

$this->setTitle('Tarifs') ;
$this->setTitle('Tarifs hébergement & modules') ;
$this->addBreadcrumb($this->getTitle()) ;

?>

<?php

if($producerModule->isBillingTypeFreePrice($producer)) {
echo '<div class="alert alert-info">';
echo "Vous bénéficiez actuellement d'un abonnement à prix libre dont voici le montant : <strong>".$producer->getFreePrice()."</strong>";
echo '</div>';
}
elseif($producerModule->isBillingTypeClassic($producer)) {
$month = date('Y-m', strtotime('-1 month'));
$turnover = $producerModule->getTurnover($producer, $month);
$amountBilledLastMonth = $producerPriceRangeModule->getAmountToBeBilledByTurnover($turnover);

if($amountBilledLastMonth) {
echo '<div class="alert alert-info">';
echo "À titre d'information, voici le tarif retenu pour le mois dernier (".strftime('%B', strtotime('-1 month')).") : <strong>".$producerModule->getAmountToBeBilledByMonth($producer, $month, true)."</strong>";
echo "<br />Le chiffre d'affaire pris en compte pour ce calcul est : <strong>".Price::format($turnover)." HT</strong>";
echo '<br /><a href="'.Yii::$app->urlManager->createUrl(['stats/index']).'">Voir l\'évolution de mon chiffre d\'affaire</a>';
echo '</div>';
}
}

?>

<?=

$this->render('@frontend/views/site/_prices_producer', [

+ 1
- 1
backend/views/producer/update.php Целия файл

@@ -488,7 +488,7 @@ $this->addBreadcrumb($this->getTitle());
</div>
</div>

<div class="form-group">
<div class="form-group form-actions">
<?= Html::submitButton('Mettre à jour', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</div>

+ 130
- 127
backend/views/product/_form.php Целия файл

@@ -9,55 +9,55 @@ use common\logic\Product\Product\Model\Product;
use common\logic\PointSale\PointSale\Model\PointSale;

$productCategoryModule = $this->getProductCategoryModule();
$taxRateModule = $this-> getTaxRateModule();
$taxRateModule = $this->getTaxRateModule();

?>

<div class="product-form">

<?php $form = ActiveForm::begin([
'enableClientValidation' => false,
'options' => ['enctype' => 'multipart/form-data']
]); ?>
<div>
<div class="col-md-8">
<?= $form->field($model, 'status')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'reference')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'id_product_category')->dropDownList($productCategoryModule->populateProductCategoriesDropdownList()); ?>
<?= $form->field($model, 'description')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'recipe')->textarea()->label('Description longue') ?>
<?= $form->field($model, 'unit')
->dropDownList(ArrayHelper::map(Product::$unitsArray, 'unit', 'wording'))
->label('Unité (pièce, poids ou volume)'); ?>
<?php
//Récupère la tva par défaut du producteur courant
$producer = \common\helpers\GlobalParam::getCurrentProducer();
$taxRateDefault = $producer->taxRate;
$taxRateNamesArray = array_merge(array(0 => 'Tva par défaut'), ArrayHelper::map($taxRateModule->findTaxRates(), 'id', function ($model) {
return $model->name;
}));
$taxRateValuesArray = array_merge(array(0 => $taxRateDefault->value), ArrayHelper::map($taxRateModule->findTaxRates(), 'id', function ($model) {
return $model->value;
}));
foreach ($taxRateValuesArray as $key => $taxRateValue) {
$taxRateValuesArrayFormatted[$key] = array('data-tax-rate-value' => $taxRateValue);
}
?>
<?php if($taxRateDefault->value != 0): ?>
<?= $form->field($model, 'id_tax_rate')->dropDownList($taxRateNamesArray, ['options' => $taxRateValuesArrayFormatted])->label('Taxe'); ?>
<?php endif; ?>
<?= $form->field($model, 'price', [
'template' => '
<?php $form = ActiveForm::begin([
'enableClientValidation' => false,
'options' => ['enctype' => 'multipart/form-data']
]); ?>
<div>
<div class="col-md-8">
<?= $form->field($model, 'status')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'reference')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'id_product_category')->dropDownList($productCategoryModule->populateProductCategoriesDropdownList()); ?>
<?= $form->field($model, 'description')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'recipe')->textarea()->label('Description longue') ?>
<?= $form->field($model, 'unit')
->dropDownList(ArrayHelper::map(Product::$unitsArray, 'unit', 'wording'))
->label('Unité (pièce, poids ou volume)'); ?>
<?php
//Récupère la tva par défaut du producteur courant
$producer = \common\helpers\GlobalParam::getCurrentProducer();
$taxRateDefault = $producer->taxRate;
$taxRateNamesArray = array_merge(array(0 => 'Tva par défaut'), ArrayHelper::map($taxRateModule->findTaxRates(), 'id', function ($model) {
return $model->name;
}));
$taxRateValuesArray = array_merge(array(0 => $taxRateDefault->value), ArrayHelper::map($taxRateModule->findTaxRates(), 'id', function ($model) {
return $model->value;
}));
foreach ($taxRateValuesArray as $key => $taxRateValue) {
$taxRateValuesArrayFormatted[$key] = array('data-tax-rate-value' => $taxRateValue);
}
?>
<?php if ($taxRateDefault->value != 0): ?>
<?= $form->field($model, 'id_tax_rate')->dropDownList($taxRateNamesArray, ['options' => $taxRateValuesArrayFormatted])->label('Taxe'); ?>
<?php endif; ?>
<?= $form->field($model, 'price', [
'template' => '
<div class="row">
<div class="col-xs-6">
<label for="product-price" class="control-label without-tax"></label>
@@ -75,92 +75,95 @@ $taxRateModule = $this-> getTaxRateModule();
</div>
',
]) ?>
<?= $form->field($model, 'step')->textInput()->hint('Définit ce qui est ajouté ou enlevé lors des changements de quantité.') ?>
<?= $form->field($model, 'weight')->textInput()->label('Poids (g)')->hint("Si unité au poids ou volume, utilisé pour déterminer le nombre de pièces dans les exports.") ?>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_monday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_tuesday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_wednesday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_thursday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_friday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_saturday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_sunday')->textInput() ?>
</div>
<div class="clr"></div>
<?php
if (!$model->isNewRecord) {
echo $form->field($model, 'apply_distributions')
->checkbox()
->hint('Sélectionnez cette option si vous souhaitez que ces modifications (actif / non actif, quantité max) soient répercutées dans les distributions à venir déjà initialisées.');
}
?>
</div>
<div class="col-md-4">
<?= $form->field($model, 'photoFile')->fileInput() ?>
<?php
if (strlen($model->photo)) {
echo '<img class="photo-product" src="' . Image::getThumbnailSmall($model->photo, true). '" width="200px" /><br />';
echo '<input type="checkbox" name="delete_photo" id="delete_photo" /> <label for="delete_photo">Supprimer la photo</label>';
}
?>
<div id="days-production">
<h2>Jours de distribution</h2>
<?= $form->field($model, 'monday')->checkbox() ?>
<?= $form->field($model, 'tuesday')->checkbox() ?>
<?= $form->field($model, 'wednesday')->checkbox() ?>
<?= $form->field($model, 'thursday')->checkbox() ?>
<?= $form->field($model, 'friday')->checkbox() ?>
<?= $form->field($model, 'saturday')->checkbox() ?>
<?= $form->field($model, 'sunday')->checkbox() ?>
</div>
<div class="clr"></div>
<div id="availability-points-sale">
<h2>Disponibilité points de vente</h2>
<?= $form->field($model, 'available_on_points_sale')->radioList([1 => 'Disponible', 0 => 'Indisponible']) ?>
<strong id="label-availability-points-sale">Et <span><?php if($model->available_on_points_sale): ?>indisponible<?php else: ?>disponible<?php endif; ?></span> sur les points de vente</strong>
<?php $pointSaleArray = PointSale::find()
->where([
'id_producer' => GlobalParam::getCurrentProducerId(),
'status' => 1
])
->orderBy('is_bread_box ASC, name ASC')
->all(); ?>
<?= Html::activeCheckboxList($model, 'pointsSale', ArrayHelper::map($pointSaleArray, 'id', function ($pointSale, $defaultValue) use ($model) {
return Html::encode($pointSale->name) ;
}), ['encode' => false, 'class' => '']) ?>
</div>
</div>
<div class="clr"></div>
]) ?>
<?= $form->field($model, 'step')->textInput()->hint('Définit ce qui est ajouté ou enlevé lors des changements de quantité.') ?>
<?= $form->field($model, 'weight')->textInput()->label('Poids (g)')->hint("Si unité au poids ou volume, utilisé pour déterminer le nombre de pièces dans les exports.") ?>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_monday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_tuesday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_wednesday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_thursday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_friday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_saturday')->textInput() ?>
</div>
<div class="col-md-3">
<?= $form->field($model, 'quantity_max_sunday')->textInput() ?>
</div>
<div class="clr"></div>
<?php
if (!$model->isNewRecord) {
echo $form->field($model, 'apply_distributions')
->checkbox()
->hint('Sélectionnez cette option si vous souhaitez que ces modifications (actif / non actif, quantité max) soient répercutées dans les distributions à venir déjà initialisées.');
}
?>
</div>
<div class="col-md-4">
<?= $form->field($model, 'photoFile')->fileInput() ?>
<?php
if (strlen($model->photo)) {
echo '<img class="photo-product" src="' . Image::getThumbnailSmall($model->photo, true) . '" width="200px" /><br />';
echo '<input type="checkbox" name="delete_photo" id="delete_photo" /> <label for="delete_photo">Supprimer la photo</label>';
}
?>
<div id="days-production">
<h2>Jours de distribution</h2>
<?= $form->field($model, 'monday')->checkbox() ?>
<?= $form->field($model, 'tuesday')->checkbox() ?>
<?= $form->field($model, 'wednesday')->checkbox() ?>
<?= $form->field($model, 'thursday')->checkbox() ?>
<?= $form->field($model, 'friday')->checkbox() ?>
<?= $form->field($model, 'saturday')->checkbox() ?>
<?= $form->field($model, 'sunday')->checkbox() ?>
</div>
<div class="clr"></div>
<div id="availability-points-sale">
<h2>Disponibilité points de vente</h2>
<?= $form->field($model, 'available_on_points_sale')->radioList([1 => 'Disponible', 0 => 'Indisponible']) ?>
<strong id="label-availability-points-sale">Et
<span><?php if ($model->available_on_points_sale): ?>indisponible<?php else: ?>disponible<?php endif; ?></span>
sur les points de vente</strong>
<?php $pointSaleArray = PointSale::find()
->where([
'id_producer' => GlobalParam::getCurrentProducerId(),
'status' => 1
])
->orderBy('is_bread_box ASC, name ASC')
->all(); ?>
<?= Html::activeCheckboxList($model, 'pointsSale', ArrayHelper::map($pointSaleArray, 'id', function ($pointSale, $defaultValue) use ($model) {
return Html::encode($pointSale->name);
}), ['encode' => false, 'class' => '']) ?>
</div>
</div>
<div class="clr"></div>
</div>

<?= $form->field($model, 'id_producer')->hiddenInput()->label('') ?>
<?= $form->field($model, 'id_producer')->hiddenInput()->label('') ?>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<div class="form-group form-actions">
<?= Html::a('Retour', ['product/index'], ['class' => 'btn btn-default']) ?>
<?= Html::submitButton($model->isNewRecord ? 'Créer' : 'Modifier', ['class' => 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>
<?php ActiveForm::end(); ?>

</div>

+ 14
- 1
backend/views/stats/index.php Целия файл

@@ -44,13 +44,26 @@ $this->addBreadcrumb('Statistiques (chiffre d\'affaire)') ;

?>

Affichage :
<?php
echo Html::a('Mois',
['stats/index', 'year' => $yearCurrent, 'displayBy' => 'month'],
['class' => 'btn btn-xs '.(($displayBy == 'month') ? 'btn-primary' : 'btn-default')]).' ';
echo Html::a('Semaine',
['stats/index', 'year' => $yearCurrent, 'displayBy' => 'week'],
['class' => 'btn btn-xs '.(($displayBy == 'week') ? 'btn-primary' : 'btn-default')]).' ';

?>

<br><br>

<?php
foreach($yearsWithTurnoverArray as $year) {
$classBtn = 'btn-default';
if($yearCurrent == $year) {
$classBtn = 'btn-primary';
}
echo Html::a($year, ['stats/index', 'year' => $year], ['class' => 'btn '.$classBtn]).' ';
echo Html::a($year, ['stats/index', 'year' => $year, 'displayBy' => $displayBy], ['class' => 'btn '.$classBtn]).' ';
}
?>


+ 6
- 2
backend/views/subscription/_form.php Целия файл

@@ -124,7 +124,11 @@ $pointSaleModule = $this->getPointSaleModule();
</div>
<?= $form->field($model, 'comment')->textarea(['rows' => 6]) ?>
<?= Html::submitButton('Enregistrer' , ['class' => 'btn btn-primary']) ?>

<div class="form-group form-actions">
<?= Html::a('Retour', ['subscription/index'], ['class' => 'btn btn-default']) ?>
<?= Html::submitButton($model->id ? 'Modifier' : 'Créer', ['class' => 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>

+ 3
- 2
backend/views/user/_form.php Целия файл

@@ -110,8 +110,9 @@ $distributionModule = DistributionModule::getInstance();
<?php /* $form->field($model, 'product_price_percent')
->dropDownList( ProductPrice::percentValues(), [])->hint('Pourcentage appliqué aux prix de chaque produit pour cet utilisateur.');*/ ?>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<div class="form-group form-actions">
<?= Html::a('Retour', ['user/index'], ['class' => 'btn btn-default']) ?>
<?= Html::submitButton($model->isNewRecord ? 'Créer' : 'Modifier', ['class' => 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>

+ 34
- 12
backend/web/css/screen.css Целия файл

@@ -1812,58 +1812,80 @@ body.skin-black .content-wrapper .pagination > .active > a, body.skin-black .con
border: solid 1px #F39C12;
color: white;
}
/* line 293, ../sass/_adminlte.scss */
/* line 294, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > li > a, body.skin-black .content-wrapper .pagination > li > span {
color: #F39C12;
}
/* line 295, ../sass/_adminlte.scss */
/* line 296, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > li > a:hover, body.skin-black .content-wrapper .pagination > li > span:hover {
color: #c87f0a;
}
/* line 300, ../sass/_adminlte.scss */
/* line 301, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .submenu {
margin-bottom: 25px;
}
/* line 306, ../sass/_adminlte.scss */
/* line 305, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
padding: 15px 30px 15px 30px;
margin: 0px;
background-color: white;
text-align: right;
z-index: 10;
border-top: solid 1px #e0e0e0;
}
/* line 318, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-actions a, body.skin-black .content-wrapper .form-actions button {
margin-left: 10px;
}
/* line 325, ../sass/_adminlte.scss */
body.skin-black .main-footer a {
color: #F39C12;
}
/* line 311, ../sass/_adminlte.scss */
/* line 330, ../sass/_adminlte.scss */
body.skin-black .gridview-pagesize {
float: right;
margin-bottom: 8px;
}
/* line 335, ../sass/_adminlte.scss */
body.skin-black #yii-debug-toolbar {
bottom: 64px;
}

/* line 317, ../sass/_adminlte.scss */
/* line 340, ../sass/_adminlte.scss */
body.login-page {
background: none;
background-color: white;
}
/* line 321, ../sass/_adminlte.scss */
/* line 344, ../sass/_adminlte.scss */
body.login-page .login-box .login-logo {
text-align: center;
font-family: 'highvoltageregular';
}
/* line 325, ../sass/_adminlte.scss */
/* line 348, ../sass/_adminlte.scss */
body.login-page .login-box .login-logo img {
width: 50px;
}
/* line 330, ../sass/_adminlte.scss */
/* line 353, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .btn-primary {
background-color: #F39C12;
border-color: #F39C12;
padding: 5px 10px;
}
/* line 335, ../sass/_adminlte.scss */
/* line 358, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .btn-primary:active {
background-color: #f4a62a;
border-color: #F39C12;
}
/* line 341, ../sass/_adminlte.scss */
/* line 364, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body a {
color: #F39C12;
}
/* line 343, ../sass/_adminlte.scss */
/* line 366, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body a:hover {
color: #f4a62a;
}

+ 7
- 0
backend/web/js/vuejs/distribution-index.js Целия файл

@@ -150,6 +150,13 @@ var app = new Vue({
}
return false;
},
isDistributionToday: function() {
var today = new Date();
return this.date
&& today.getFullYear() == this.date.getFullYear()
&& today.getMonth() == this.date.getMonth()
&& today.getDay() == this.date.getDay();
},
init: function (idActivePointSale) {
var app = this;
this.showLoading = true;

+ 24
- 1
backend/web/sass/_adminlte.scss Целия файл

@@ -290,16 +290,35 @@ body.skin-black {
border: solid 1px $color1 ;
color: white ;
}

.pagination > li > a, .pagination > li > span {
color: $color1 ;
&:hover {
color: darken($color1, 10) ;
}
}
.submenu {
margin-bottom: 25px ;
}

.form-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
padding: 15px 30px 15px 30px;
margin: 0px;
background-color: white;
text-align: right;
z-index: 10;
border-top: solid 1px #e0e0e0;

a, button {
margin-left: 10px;
}
}
}
.main-footer {
@@ -312,6 +331,10 @@ body.skin-black {
float: right;
margin-bottom: 8px;
}

#yii-debug-toolbar {
bottom: 64px;
}
}

body.login-page {

+ 1
- 1
common/config/params.php Целия файл

@@ -37,7 +37,7 @@
*/

return [
'version' => '23.12.A',
'version' => '23.12.C',
'maintenanceMode' => false,
'siteName' => 'Opendistrib',
'adminEmail' => 'contact@opendistrib.net',

+ 12
- 3
common/helpers/Image.php Целия файл

@@ -31,8 +31,17 @@ class Image
$thumbnailFilename = self::getThumbnailFilename($filenameOriginal, $thumbnail);
$thumbnailPath = $basePath . $thumbnailFilename;
$originalPath = $basePath . $filenameOriginal;
$defaultImagePath = $basePath . 'default.jpg';

return self::isThumbnailExist($thumbnailFilename) ? $thumbnailPath : $originalPath;
if(self::isPhotoExist($thumbnailFilename)) {
return $thumbnailPath;
}

if(self::isPhotoExist($filenameOriginal)) {
return $originalPath;
}

return $defaultImagePath;
}

public static function getBasePath(bool $absoluteUrl = false): string
@@ -51,8 +60,8 @@ class Image
return $filenameArray[0].'-'.$thumbnail.'.'.$filenameArray[1];
}

public static function isThumbnailExist(string $thumbnailFilename): bool
public static function isPhotoExist(string $filename): bool
{
return file_exists(\Yii::getAlias('@producer').'/web/'.self::DIR_UPLOADS.'/'.$thumbnailFilename);
return file_exists(\Yii::getAlias('@producer').'/web/'.self::DIR_UPLOADS.'/'.$filename);
}
}

+ 1
- 1
common/logic/Distribution/Distribution/Export/DistributionReportCsvGenerator.php Целия файл

@@ -185,7 +185,7 @@ class DistributionReportCsvGenerator extends AbstractGenerator implements Distri
$totalsPointSaleArray[$index] .= $quantity;

if ($product->unit != $unit) {
$totalsPointSaleArray[$index] .= '' . $this->productSolver->strUnit($unit, 'wording_short', true);
$totalsPointSaleArray[$index] .= '' . $this->unitSolver->strUnit($unit, 'wording_short', true);
}
}
}

+ 7
- 1
common/logic/Distribution/Distribution/Export/DistributionReportPdfGenerator.php Целия файл

@@ -119,6 +119,10 @@ class DistributionReportPdfGenerator extends AbstractGenerator implements Distri
.payment-detail-remaining-surplus {
font-size: 10px;
}
.td-order-amount.is-order-paid {
background-color: #f1f1f1;
}
',
'methods' => [
'SetHeader' => ['Commandes du ' . date('d/m/Y', strtotime($distribution->date))],
@@ -293,7 +297,9 @@ class DistributionReportPdfGenerator extends AbstractGenerator implements Distri

public function columnOrderAmount(Order $order): string
{
$html = '<td class="td-order-amount"><strong>'.number_format($order->amount_with_tax, 2) . ' €</strong>';
$isOrderPaid = $this->orderRepository->isOrderPaid($order);

$html = '<td class="td-order-amount'.(($isOrderPaid) ? ' is-order-paid' : '').'"><strong>'.number_format($order->amount_with_tax, 2) . ' €</strong>';

$paymentLabelPaid = $this->orderRepository->getPaymentLabelPaid($order);
if($paymentLabelPaid && strlen($paymentLabelPaid)) {

+ 36
- 1
common/logic/Distribution/Distribution/Export/DistributionShoppingCartLabelsPdfGenerator.php Целия файл

@@ -9,6 +9,7 @@ use common\logic\Feature\Feature\FeatureChecker;
use common\logic\Feature\Feature\FeatureManager;
use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Repository\OrderRepository;
use common\logic\Order\Order\Service\OrderBuilder;
use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Producer\Producer\Service\ProducerSolver;
use kartik\mpdf\Pdf;
@@ -24,6 +25,7 @@ class DistributionShoppingCartLabelsPdfGenerator extends AbstractGenerator imple
protected OrderRepository $orderRepository;
protected OrderSolver $orderSolver;
protected FeatureChecker $featureChecker;
protected OrderBuilder $orderBuilder;

public function loadDependencies(): void
{
@@ -31,6 +33,7 @@ class DistributionShoppingCartLabelsPdfGenerator extends AbstractGenerator imple
$this->orderRepository = $this->loadService(OrderRepository::class);
$this->orderSolver = $this->loadService(OrderSolver::class);
$this->featureChecker = $this->loadService(FeatureChecker::class);
$this->orderBuilder = $this->loadService(OrderBuilder::class);
}

public function getSpecificFormatDetailsArray(): array
@@ -57,6 +60,10 @@ class DistributionShoppingCartLabelsPdfGenerator extends AbstractGenerator imple
$ordersArray = $this->orderRepository->findOrdersByDistribution($distribution);
$ordersArray = $this->filterOrdersExcludedUsersAndPointSales($ordersArray);

foreach($ordersArray as $order) {
$this->orderBuilder->initOrder($order);
}

$content = \Yii::$app->getView()->render('@backend/views/distribution/shopping-cart-labels.php', [
'distribution' => $distribution,
'ordersArray' => $ordersArray,
@@ -161,6 +168,21 @@ class DistributionShoppingCartLabelsPdfGenerator extends AbstractGenerator imple
height: '.$specificFormatHeight.'mm;
display: block;
float: left;
}
.shopping-cart-label .amount-and-payment {
margin-top: 8px;
font-size: 10px;
/*border-top: dotted 1px gray;*/
}
.shopping-cart-label .amount-and-payment .amount {
display: inline-block;
background-color: #e0e0e0;
color: #333;
font-weight: bold;
padding: 3px 8px;
border-radius: 8px;
}';
}
else {
@@ -181,8 +203,20 @@ class DistributionShoppingCartLabelsPdfGenerator extends AbstractGenerator imple
return $css;
}

public function getShoppingCartLabelAsHtml(Order $order, int $index): string
public function getShoppingCartLabelAsHtml(Order $order, int $index, bool $isSpecificFormat): string
{
$amountAndPayment = '';
if($isSpecificFormat) {
$amountAndPayment = '<div class="amount-and-payment">';
$amountAndPayment .= '<span class="amount">'.$this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_TOTAL, true).'</span>';

$paymentLabelPaid = $this->orderRepository->getPaymentLabelPaid($order);
if($paymentLabelPaid && strlen($paymentLabelPaid)) {
$amountAndPayment .= ' / '.$paymentLabelPaid;
}
$amountAndPayment .= '</div>';
}

return '<div class="shopping-cart-label shopping-cart-label-'.$index.'">
<div class="inner">
<div class="username">
@@ -195,6 +229,7 @@ class DistributionShoppingCartLabelsPdfGenerator extends AbstractGenerator imple
<div class="products">
'.$this->orderRepository->getCartSummary($order).'
</div>
'.$amountAndPayment.'
</div>
</div>';
}

+ 10
- 3
common/logic/Order/Order/Service/TillerManager.php Целия файл

@@ -138,8 +138,15 @@ class TillerManager extends AbstractManager
if ($ordersOpendistrib) {
foreach ($ordersOpendistrib as $orderOpendistrib) {
$this->orderBuilder->initOrder($orderOpendistrib);
$ordersOpendistribSynchro[$orderOpendistrib->id] = false;
if (isset($ordersTiller->orders)) {

if($orderOpendistrib->tiller_external_id) {
$ordersOpendistribSynchro[$orderOpendistrib->id] = true;
}
else {
$ordersOpendistribSynchro[$orderOpendistrib->id] = false;
}

/*if (isset($ordersTiller->orders)) {
foreach ($ordersTiller->orders as $orderTiller) {
if ($orderOpendistrib->tiller_external_id == $orderTiller->id) {
$amountTotalPaidOrderOpendistrib = (int)round(
@@ -151,7 +158,7 @@ class TillerManager extends AbstractManager
}
}
}
}
}*/
}
}


+ 18
- 3
common/logic/Order/ProductOrder/Service/ProductOrderSolver.php Целия файл

@@ -70,20 +70,35 @@ class ProductOrderSolver extends AbstractService implements SolverInterface
return $productOrder->price;
}

public function getPriceUnitReference(ProductOrder $productOrder): ?float
public function getPriceUnitReference(ProductOrder $productOrder, bool $isInvoicePrice = false): ?float
{
$productOrderPrice = $productOrder->price;
if($isInvoicePrice) {
$productOrderPrice = $this->getInvoicePrice($productOrder);
}

if($productOrder->unit == 'piece') {
if($productOrder->product->weight) {
$price = (1000 * $productOrder->price) / $productOrder->product->weight;
$price = (1000 * $productOrderPrice) / $productOrder->product->weight;
}
else {
return null;
}
}
else {
$price = $productOrder->price;
$price = $productOrderPrice;
}

return $price;
}

public function getInvoicePrice(ProductOrder $productOrder)
{
if($productOrder->invoice_price) {
return $productOrder->invoice_price;
}
else {
return $productOrder->price;
}
}
}

+ 43
- 13
common/logic/Producer/Producer/Repository/ProducerRepository.php Целия файл

@@ -152,6 +152,25 @@ class ProducerRepository extends AbstractRepository
$period = date('Y-m');
}

$dateStart = date('Y-m-31', strtotime("-1 month", strtotime($period)));
$dateEnd = date('Y-m-01', strtotime("+1 month", strtotime($period)));

return $this->getTurnoverByDateStartEnd($producer, $dateStart, $dateEnd, $format);
}

public function getTurnoverByWeek(Producer $producer, int $year, int $week, bool $format = false)
{
$date = new \DateTime();
$date->setISODate($year, $week);
$dateStart = $date->format('Y-m-d');
$date->modify('+6 days');
$dateEnd = $date->format('Y-m-d');

return $this->getTurnoverByDateStartEnd($producer, $dateStart, $dateEnd, $format);
}

public function getTurnoverByDateStartEnd(Producer $producer, string $dateStart, string $dateEnd, bool $format = false)
{
$connection = \Yii::$app->getDb();
$command = $connection->createCommand(
'
@@ -160,11 +179,11 @@ class ProducerRepository extends AbstractRepository
WHERE `order`.id = product_order.id_order
AND distribution.id_producer = :id_producer
AND `order`.id_distribution = distribution.id
AND distribution.date > :date_begin
AND distribution.date > :date_start
AND distribution.date < :date_end',
[
':date_begin' => date('Y-m-31', strtotime("-1 month", strtotime($period))),
':date_end' => date('Y-m-01', strtotime("+1 month", strtotime($period))),
':date_start' => $dateStart,
':date_end' => $dateEnd,
':id_producer' => $producer->id
]
);
@@ -198,9 +217,11 @@ class ProducerRepository extends AbstractRepository
return $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, $format);
}

public function getDatasChartTurnoverStatistics(Producer $producer, int $year)
public function getDatasChartTurnoverStatistics(Producer $producer, int $year, string $displayBy = 'month')
{
$interval = new \DateInterval('P1M');
$data = [];
$dataLabels = [];

$start = new \DateTime($year.'-01-01');
if($year == date('Y')) {
$end = new \DateTime('last day of this month');
@@ -208,16 +229,25 @@ class ProducerRepository extends AbstractRepository
else {
$end = new \DateTime($year.'-12-31');
}
$period = new \DatePeriod($start, $interval, $end);

$data = [];
$dataLabels = [];
$interval = new \DateInterval(($displayBy == 'week') ? 'P1W' : 'P1M');
$period = new \DatePeriod($start, $interval, $end);

foreach ($period as $date) {
$month = $date->format('m/Y');
$dataLabels[] = $month;
$turnover = $this->getTurnover($producer, $date->format('Y-m'));
$data[$month] = $turnover;
if($displayBy == 'week') {
foreach ($period as $date) {
$week = $date->format('W');
$dataLabels[] = $week;
$turnover = $this->getTurnoverByWeek($producer, $year, $date->format('W'));
$data[$week] = $turnover;
}
}
else {
foreach ($period as $date) {
$month = $date->format('m/Y');
$dataLabels[] = $month;
$turnover = $this->getTurnover($producer, $date->format('Y-m'));
$data[$month] = $turnover;
}
}

// création d'un tableau sans index car chart.js n'accepte pas les index

+ 5
- 1
common/logic/Product/Product/Service/ProductSolver.php Целия файл

@@ -188,7 +188,11 @@ class ProductSolver extends AbstractService implements SolverInterface
return $product->reference;
}

return $product->name;
$productName = $product->name;
// le caractère "<" crée un problème dans le récapitulatif PDF des commandes
$productName = str_replace('<', '', $productName);

return $productName;
}

public function isProductActiveByDay(Product $product, string $day): bool

+ 1
- 2
common/logic/Subscription/Subscription/Repository/SubscriptionRepository.php Целия файл

@@ -71,8 +71,7 @@ class SubscriptionRepository extends AbstractRepository
public function findSubscriptionsLatestAdded()
{
return $this->createDefaultQuery()
->filterByCreatedDuringPastWeek()
->filterByCreatedByUser()
->filterByCreatedOrUpdatedByUserDuringPastWeek()
->find();
}
}

+ 3
- 9
common/logic/Subscription/Subscription/Repository/SubscriptionRepositoryQuery.php Целия файл

@@ -21,17 +21,11 @@ class SubscriptionRepositoryQuery extends AbstractRepositoryQuery
return $this;
}

public function filterByCreatedDuringPastWeek(): self
public function filterByCreatedOrUpdatedByUserDuringPastWeek(): self
{
$datePastWeek = new \DateTime('-7 days');
$this->andWhere('subscription.created_at >= :created_at')
->addParams(['created_at' => $datePastWeek->format('Y-m-d H:i:s')]);
return $this;
}

public function filterByCreatedByUser(): self
{
$this->andWhere('subscription.id_user = subscription.id_created_by');
$this->andWhere('(subscription.id_user = subscription.id_created_by AND subscription.created_at >= :date_past_week) OR (subscription.id_user = subscription.id_updated_by AND subscription.updated_at >= :date_past_week)')
->addParams(['date_past_week' => $datePastWeek->format('Y-m-d H:i:s')]);
return $this;
}
}

+ 4
- 1
common/logic/User/User/Service/UserSolver.php Целия файл

@@ -98,7 +98,10 @@ class UserSolver extends AbstractService implements SolverInterface

public function getUsername(User $user, $withType = false): string
{
if (isset($user->name_legal_person) && strlen($user->name_legal_person)) {
if ($this->isTypeLegalPerson($user)
&& isset($user->name_legal_person)
&& strlen($user->name_legal_person)) {

$username = $user->name_legal_person;
} else {
$username = $user->lastname . ' ' . $user->name;

+ 27
- 0
common/versions/23.12.B.php Целия файл

@@ -0,0 +1,27 @@
<?php

require_once dirname(__FILE__).'/_macros.php';

version(
'11/12/2023',
[
[
"[Administration] Distributions > paiement : ajout 'Carte bancaire' en moyen de paiement",
"[Administration] Communiquer > envoyer un email : ajout du lien vers la boutique du producteur dans le footer",
"[Administration] Formulaires : boutons d'actions en position fixe",
],
[
"[Administration] Tiller : correctif problème synchronisation"
]
],
[
[
],
[
"[Technique] Images : gestion image par défaut"
]
],
$userCurrent
);

?>

+ 29
- 0
common/versions/23.12.C.php Целия файл

@@ -0,0 +1,29 @@
<?php

require_once dirname(__FILE__).'/_macros.php';

version(
'18/12/2023',
[
[
"[Administration] Tableau de bord : affichage des abonnements modifiés récemment",
"[Administration] Export étiquettes PDF : ajout de l'information du paiement de la commande",
"[Administration] Export commandes PDF : cellule du montant grisée quand la commande est payée",
"[Administration] Statistiques > Chiffre d'affaires : vue semaine par semaine",
],
[
"[Administration] Utilisateur : correctif affichage nom personne légale",
"[Administration] Distributions > Synchronisation Tiller : activation uniquement le jour des distribution",
"[Administration] Export commandes PDF : correctif problème caractère "<" dans le nom des produits",
]
],
[
[
],
[
]
],
$userCurrent
);

?>

+ 81
- 57
frontend/views/site/_prices_producer.php Целия файл

@@ -42,64 +42,88 @@ use yii\helpers\Html;

?>

<div class="alert alert-warning" role="alert">
Découvrez ci-dessous la <strong>grille tarifaire</strong> pour l'hébergement de votre circuit court sur Opendistrib.
Le montant qui vous est facturé mensuellement dépend de votre chiffre d’affaire hors taxe réalisé sur le logiciel.
Il est donc adapté chaque mois en fonction de l’évolution de votre activité.<br>
Le service est <strong>sans engagement</strong>, vous arrêtez quand vous voulez sur simple désactivation de votre compte.
</div>

<?=
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<div class="glyphicon glyphicon-hdd"></div>
Hébergement
</h3>
</div>
<div class="panel-body">
<div class="alert alert-warning" role="alert">
Découvrez ci-dessous la <strong>grille tarifaire</strong> pour l'hébergement de votre circuit court sur Opendistrib.
Le montant qui vous est facturé mensuellement dépend de votre chiffre d’affaire hors taxe réalisé sur le logiciel.
Il est donc adapté chaque mois en fonction de l’évolution de votre activité. Le service est
<strong>sans engagement</strong>, vous arrêtez quand vous voulez sur simple désactivation de votre compte.
</div>
<?=
GridView::widget([
'dataProvider' => $dataProviderPrices,
'summary' => '',
'columns' => [
[
'label' => 'Tranches (CA HT / mois)',
'format' => 'raw',
'value' => function ($model) {
if ($model->range_begin == 0) {
$html = 'Moins de ' . $model->range_end . ' &euro;';
} elseif ($model->range_end == null) {
$html = 'Plus de ' . $model->range_begin . ' &euro;';
} else {
$html = 'Entre ' . $model->range_begin . ' &euro;';
$html .= ' et ' . $model->range_end . ' &euro;';
}
return $html;
}
],
[
'label' => 'Tarif (HT)',
'format' => 'raw',
'value' => function ($model) {
$html = $model->price . ' &euro;';

GridView::widget([
'dataProvider' => $dataProviderPrices,
'summary' => '',
'columns' => [
[
'label' => 'Tranches (CA HT / mois)',
'format' => 'raw',
'value' => function ($model) {
if ($model->range_begin == 0) {
$html = 'Moins de ' . $model->range_end . ' &euro;';
} elseif ($model->range_end == null) {
$html = 'Plus de ' . $model->range_begin . ' &euro;';
} else {
$html = 'Entre ' . $model->range_begin . ' &euro;';
$html .= ' et ' . $model->range_end . ' &euro;';
}
return $html;
}
],
[
'label' => 'Tarifs (HT)',
'format' => 'raw',
'value' => function ($model) {
$html = $model->price . ' &euro;';
return $html;
}
],
]
]);
?>
</div>
</div>

return $html;
}
],
]
]);
?>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<span class="glyphicon glyphicon-th-large"></span>
Modules
</h3>
</div>
<div class="panel-body">
<div class="alert alert-warning" role="alert">
Retrouvez ici les modules payants d'Opendistrib correspondant aux développements qui n'ont pas encore
été totalement financés et aux fonctionnalités nécessitant une configuration spécifique. Contactez-moi
pour demander l'activation d'un module.
</div>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Module</th>
<th>Tarif (HT)</th>
</tr>
</thead>
<tbody>
<?php foreach($paidFeaturesArray as $paidFeature): ?>
<tr>
<td>
<div><strong><?= Html::encode($paidFeature->name) ?></strong></div>
<div><?= $paidFeature->description ?></div>
</td>
<td><?= Price::format($paidFeature->price, 0) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>

<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Module</th>
<th>Activation du module (HT)</th>
</tr>
</thead>
<tbody>
<?php foreach($paidFeaturesArray as $paidFeature): ?>
<tr>
<td>
<div><strong><?= Html::encode($paidFeature->name) ?></strong></div>
<div><?= $paidFeature->description ?></div>
</td>
<td><?= Price::format($paidFeature->price, 0) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>


+ 2
- 1
producer/views/layouts/main.php Целия файл

@@ -36,6 +36,7 @@
* termes.
*/

use common\helpers\Image;
use common\logic\Feature\Feature\Feature;
use common\logic\Feature\Feature\FeatureModule;
use common\logic\Order\Order\Model\Order;
@@ -88,7 +89,7 @@ if (!Yii::$app->user->isGuest) {
<div class="container">
<div id="left" class="col-md-3">
<div class="fixed">
<?php if (strlen($producer->logo)): ?>
<?php if (strlen($producer->logo) && Image::isPhotoExist($producer->logo)): ?>
<div id="logo"<?php if (!is_null($producer->background_color_logo) && strlen($producer->background_color_logo)): ?> style="background-color:<?= Html::encode($producer->background_color_logo); ?>"<?php endif; ?>>
<a href="<?= \Yii::$app->urlManager->createUrl(['site/index']) ?>">
<img class="img-logo"

Loading…
Отказ
Запис