Parcourir la source

Merge branch 'develop'

master
Guillaume Bourgeois il y a 1 an
Parent
révision
58133f6ee5
34 fichiers modifiés avec 534 ajouts et 287 suppressions
  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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

@@ -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 Voir le fichier

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

Chargement…
Annuler
Enregistrer