@@ -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'], |
@@ -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) { |
@@ -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"> |
@@ -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> |
@@ -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; |
@@ -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) ?> |
@@ -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 |
@@ -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', |
@@ -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(); ?> |
@@ -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', [ |
@@ -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> |
@@ -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> |
@@ -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]).' '; | |||
} | |||
?> | |||
@@ -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> |
@@ -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(); ?> |
@@ -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; | |||
} |
@@ -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; |
@@ -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 { |
@@ -37,7 +37,7 @@ | |||
*/ | |||
return [ | |||
'version' => '23.12.A', | |||
'version' => '23.12.C', | |||
'maintenanceMode' => false, | |||
'siteName' => 'Opendistrib', | |||
'adminEmail' => 'contact@opendistrib.net', |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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)) { |
@@ -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>'; | |||
} |
@@ -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 | |||
} | |||
} | |||
} | |||
} | |||
}*/ | |||
} | |||
} | |||
@@ -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; | |||
} | |||
} | |||
} |
@@ -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 |
@@ -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 |
@@ -71,8 +71,7 @@ class SubscriptionRepository extends AbstractRepository | |||
public function findSubscriptionsLatestAdded() | |||
{ | |||
return $this->createDefaultQuery() | |||
->filterByCreatedDuringPastWeek() | |||
->filterByCreatedByUser() | |||
->filterByCreatedOrUpdatedByUserDuringPastWeek() | |||
->find(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; |
@@ -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 | |||
); | |||
?> |
@@ -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 | |||
); | |||
?> |
@@ -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 . ' €'; | |||
} elseif ($model->range_end == null) { | |||
$html = 'Plus de ' . $model->range_begin . ' €'; | |||
} else { | |||
$html = 'Entre ' . $model->range_begin . ' €'; | |||
$html .= ' et ' . $model->range_end . ' €'; | |||
} | |||
return $html; | |||
} | |||
], | |||
[ | |||
'label' => 'Tarif (HT)', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
$html = $model->price . ' €'; | |||
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 . ' €'; | |||
} elseif ($model->range_end == null) { | |||
$html = 'Plus de ' . $model->range_begin . ' €'; | |||
} else { | |||
$html = 'Entre ' . $model->range_begin . ' €'; | |||
$html .= ' et ' . $model->range_end . ' €'; | |||
} | |||
return $html; | |||
} | |||
], | |||
[ | |||
'label' => 'Tarifs (HT)', | |||
'format' => 'raw', | |||
'value' => function ($model) { | |||
$html = $model->price . ' €'; | |||
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> | |||
@@ -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" |