$searchModel = new ProductPriceSearch(); | $searchModel = new ProductPriceSearch(); | ||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); | ||||
$userProducerWithProductPercent = UserProducer::searchAll([], [ | |||||
'join_with' => ['user'], | |||||
'conditions' => 'user_producer.product_price_percent != 0', | |||||
]) ; | |||||
$pointSaleWithProductPercent = PointSale::searchAll([], [ | |||||
'conditions' => 'point_sale.product_price_percent != 0' | |||||
]) ; | |||||
return $this->render('update/prices/list', [ | return $this->render('update/prices/list', [ | ||||
'model' => $model, | 'model' => $model, | ||||
'action' => 'prices-list', | 'action' => 'prices-list', | ||||
'searchModel' => $searchModel, | 'searchModel' => $searchModel, | ||||
'dataProvider' => $dataProvider, | 'dataProvider' => $dataProvider, | ||||
'userProducerWithProductPercent' => $userProducerWithProductPercent, | |||||
'pointSaleWithProductPercent' => $pointSaleWithProductPercent, | |||||
]); | ]); | ||||
} | } | ||||
<div class="alert alert-info"> | |||||
<div class="alert alert-warning"> | |||||
Prix de base : <strong><?= Price::format($model->getPrice()); ?> HT</strong> / <strong><?= Price::format($model->getPriceWithTax()); ?> TTC</strong><br /> | Prix de base : <strong><?= Price::format($model->getPrice()); ?> HT</strong> / <strong><?= Price::format($model->getPriceWithTax()); ?> TTC</strong><br /> | ||||
</div> | </div> |
$this->addBreadcrumb(['label' => 'Produits', 'url' => ['index']]); | $this->addBreadcrumb(['label' => 'Produits', 'url' => ['index']]); | ||||
$this->addBreadcrumb(['label' => $model->name, 'url' => ['update', 'id' => $model->id]]); | $this->addBreadcrumb(['label' => $model->name, 'url' => ['update', 'id' => $model->id]]); | ||||
$this->addBreadcrumb('Modifier'); | $this->addBreadcrumb('Modifier'); | ||||
$this->addButton(['label' => 'Nouveau prix <span class="glyphicon glyphicon-plus"></span>', 'url' => ['product/prices-create', 'idProduct' => $model->id ], 'class' => 'btn btn-primary']); | |||||
//$this->addButton(['label' => 'Nouveau prix <span class="glyphicon glyphicon-plus"></span>', 'url' => ['product/prices-create', 'idProduct' => $model->id ], 'class' => 'btn btn-primary']); | |||||
?> | ?> | ||||
]) ; | ]) ; | ||||
?> | ?> | ||||
<?= | |||||
$this->render('_base_price', [ | |||||
'model' => $model, | |||||
]) ; | |||||
?> | |||||
<div class="col-md-8"> | |||||
<?php | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title"> | |||||
Prix spécifiques à ce produit | |||||
<a href="<?= Yii::$app->urlManager->createUrl(['product/prices-create', 'idProduct' => $model->id ]) ?>" class="btn btn-default btn-xs"> | |||||
Nouveau prix | |||||
<span class="glyphicon glyphicon-plus"></span> | |||||
</a> | |||||
</h3> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<?php | |||||
echo GridView::widget([ | |||||
//'filterModel' => $searchModel, | |||||
'dataProvider' => $dataProvider, | |||||
'columns' => [ | |||||
[ | |||||
'attribute' => 'id_point_sale', | |||||
'format' => 'raw', | |||||
'value' => function ($model) { | |||||
if($model->pointSale) { | |||||
return $model->pointSale->name ; | |||||
} | |||||
return '<span class="label label-success">Tous</span>' ; | |||||
} | |||||
], | |||||
[ | |||||
'attribute' => 'id_user', | |||||
'format' => 'raw', | |||||
'value' => function ($model) { | |||||
if($model->user) { | |||||
return $model->user->getUsername() ; | |||||
} | |||||
return '<span class="label label-success">Tous</span>' ; | |||||
} | |||||
], | |||||
[ | |||||
'attribute' => 'price', | |||||
'value' => function ($productPrice) { | |||||
return Price::numberTwoDecimals($productPrice->price).' €' ; | |||||
} | |||||
], | |||||
[ | |||||
'attribute' => 'price', | |||||
'header' => 'Prix (TTC)', | |||||
'value' => function ($productPrice) use ($model) { | |||||
return Price::numberTwoDecimals(Price::getPriceWithTax($productPrice->price, $model->taxRate->value)).' €' ; | |||||
} | |||||
], | |||||
[ | |||||
'class' => 'yii\grid\ActionColumn', | |||||
'template' => '{update} {delete}', | |||||
'headerOptions' => ['class' => 'column-actions'], | |||||
'contentOptions' => ['class' => 'column-actions'], | |||||
'buttons' => [ | |||||
'update' => function ($url, $model) { | |||||
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', ['product/prices-update', 'id' => $model->id], [ | |||||
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default' | |||||
]); | |||||
}, | |||||
'delete' => function ($url, $model) { | |||||
return Html::a('<span class="glyphicon glyphicon-trash"></span>', ['product/prices-delete', 'id' => $model->id], [ | |||||
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default' | |||||
]); | |||||
} | |||||
], | |||||
], | |||||
], | |||||
]); | |||||
?> | |||||
</div> | |||||
</div> | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title">Pourcentage global / Utilisateurs</h3> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<table class="table table-bordered"> | |||||
<thead> | |||||
<tr> | |||||
<th>Utilisateur</th> | |||||
<th>Pourcentage</th> | |||||
<th>Prix (HT)</th> | |||||
<th>Prix (TTC)</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<?php if($userProducerWithProductPercent && count($userProducerWithProductPercent) > 0): ?> | |||||
<?php foreach($userProducerWithProductPercent as $userProducer): ?> | |||||
<?php if($userProducer->user): ?> | |||||
<tr> | |||||
<td><?= $userProducer->user->getUsername() ?></td> | |||||
<td><?= $userProducer->product_price_percent ?> %</td> | |||||
<td><?= Price::format($model->getPrice(['user_producer' => $userProducer])) ?></td> | |||||
<td><?= Price::format($model->getPriceWithTax(['user_producer' => $userProducer])) ?></td> | |||||
</tr> | |||||
<?php endif; ?> | |||||
<?php endforeach; ?> | |||||
<?php else: ?> | |||||
<tr><td colspan="4">Aucun résultat</td></tr> | |||||
<?php endif; ?> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title">Pourcentage global / Points de vente</h3> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<table class="table table-bordered"> | |||||
<thead> | |||||
<tr> | |||||
<th>Point de vente</th> | |||||
<th>Pourcentage</th> | |||||
<th>Prix (HT)</th> | |||||
<th>Prix (TTC)</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<?php if($pointSaleWithProductPercent && count($pointSaleWithProductPercent) > 0): ?> | |||||
<?php foreach($pointSaleWithProductPercent as $pointSale): ?> | |||||
<tr> | |||||
<td><?= Html::encode($pointSale->name) ?></td> | |||||
<td><?= $pointSale->product_price_percent ?> %</td> | |||||
<td><?= Price::format($model->getPrice(['point_sale' => $pointSale])) ?></td> | |||||
<td><?= Price::format($model->getPriceWithTax(['point_sale' => $pointSale])) ?></td> | |||||
</tr> | |||||
<?php endforeach; ?> | |||||
<?php else: ?> | |||||
<tr><td colspan="4">Aucun résultat</td></tr> | |||||
<?php endif; ?> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title">Prix de base</h3> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<p>Prix de base : <strong><?= Price::format($model->getPrice()); ?> HT</strong> / <strong><?= Price::format($model->getPriceWithTax()); ?> TTC</strong><br /></p> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
echo GridView::widget([ | |||||
//'filterModel' => $searchModel, | |||||
'dataProvider' => $dataProvider, | |||||
'columns' => [ | |||||
[ | |||||
'attribute' => 'id_point_sale', | |||||
'value' => function ($model) { | |||||
if($model->pointSale) { | |||||
return $model->pointSale->name ; | |||||
} | |||||
return '' ; | |||||
} | |||||
], | |||||
[ | |||||
'attribute' => 'id_user', | |||||
'value' => function ($model) { | |||||
if($model->user) { | |||||
return $model->user->getUsername() ; | |||||
} | |||||
return '' ; | |||||
} | |||||
], | |||||
[ | |||||
'attribute' => 'price', | |||||
'value' => function ($productPrice) { | |||||
return Price::numberTwoDecimals($productPrice->price).' €' ; | |||||
} | |||||
], | |||||
[ | |||||
'attribute' => 'price', | |||||
'header' => 'Prix (TTC)', | |||||
'value' => function ($productPrice) use ($model) { | |||||
return Price::numberTwoDecimals(Price::getPriceWithTax($productPrice->price, $model->taxRate->value)).' €' ; | |||||
} | |||||
], | |||||
[ | |||||
'class' => 'yii\grid\ActionColumn', | |||||
'template' => '{update} {delete}', | |||||
'headerOptions' => ['class' => 'column-actions'], | |||||
'contentOptions' => ['class' => 'column-actions'], | |||||
'buttons' => [ | |||||
'update' => function ($url, $model) { | |||||
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', ['product/prices-update', 'id' => $model->id], [ | |||||
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default' | |||||
]); | |||||
}, | |||||
'delete' => function ($url, $model) { | |||||
return Html::a('<span class="glyphicon glyphicon-trash"></span>', ['product/prices-delete', 'id' => $model->id], [ | |||||
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default' | |||||
]); | |||||
} | |||||
], | |||||
], | |||||
], | |||||
]); | |||||
<div class="col-md-4"> | |||||
<div class="panel panel-default"> | |||||
<div class="panel-heading"> | |||||
<h3 class="panel-title">Priorités de résolution</h3> | |||||
</div> | |||||
<div class="panel-body"> | |||||
<p>Le prix d'un produit se déduit dans un ordre précis de résolution, le voici : </p> | |||||
<ul> | |||||
<li>Les prix spécifiques définis au niveau du produit</li> | |||||
<li>Les pourcentages globaux définis au niveau des utilisateurs et points de vente</li> | |||||
<li>Le prix de base défini au niveau du produit</li> | |||||
</ul> | |||||
<p>À chaque étape de résolution, on vérifie si le contexte courant (utilisateur / point de vente) correspond à un prix. | |||||
Si c'est le cas, on l'utilise, sinon on passe à l'étape suivante jusqu'à arriver au prix de base | |||||
défini dans "Général". | |||||
</p> | |||||
</div> | |||||
</div> | |||||
</div> |
} | } | ||||
} | } | ||||
.panel { | |||||
.panel-heading { | |||||
.panel-title { | |||||
.btn { | |||||
float: right ; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
/* modals */ | /* modals */ | ||||
.modal-mask { | .modal-mask { |
<?php | <?php | ||||
/** | |||||
Copyright distrib (2018) | |||||
contact@opendistrib.net | |||||
Ce logiciel est un programme informatique servant à aider les producteurs | |||||
à distribuer leur production en circuits courts. | |||||
Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||||
respectant les principes de diffusion des logiciels libres. Vous pouvez | |||||
utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||||
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||||
sur le site "http://www.cecill.info". | |||||
En contrepartie de l'accessibilité au code source et des droits de copie, | |||||
de modification et de redistribution accordés par cette licence, il n'est | |||||
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||||
seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||||
titulaire des droits patrimoniaux et les concédants successifs. | |||||
A cet égard l'attention de l'utilisateur est attirée sur les risques | |||||
associés au chargement, à l'utilisation, à la modification et/ou au | |||||
développement et à la reproduction du logiciel par l'utilisateur étant | |||||
donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||||
manipuler et qui le réserve donc à des développeurs et des professionnels | |||||
avertis possédant des connaissances informatiques approfondies. Les | |||||
utilisateurs sont donc invités à charger et tester l'adéquation du | |||||
logiciel à leurs besoins dans des conditions permettant d'assurer la | |||||
sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||||
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||||
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||||
pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||||
termes. | |||||
*/ | |||||
/** | |||||
* Copyright distrib (2018) | |||||
* | |||||
* contact@opendistrib.net | |||||
* | |||||
* Ce logiciel est un programme informatique servant à aider les producteurs | |||||
* à distribuer leur production en circuits courts. | |||||
* | |||||
* Ce logiciel est régi par la licence CeCILL soumise au droit français et | |||||
* respectant les principes de diffusion des logiciels libres. Vous pouvez | |||||
* utiliser, modifier et/ou redistribuer ce programme sous les conditions | |||||
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA | |||||
* sur le site "http://www.cecill.info". | |||||
* | |||||
* En contrepartie de l'accessibilité au code source et des droits de copie, | |||||
* de modification et de redistribution accordés par cette licence, il n'est | |||||
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons, | |||||
* seule une responsabilité restreinte pèse sur l'auteur du programme, le | |||||
* titulaire des droits patrimoniaux et les concédants successifs. | |||||
* | |||||
* A cet égard l'attention de l'utilisateur est attirée sur les risques | |||||
* associés au chargement, à l'utilisation, à la modification et/ou au | |||||
* développement et à la reproduction du logiciel par l'utilisateur étant | |||||
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à | |||||
* manipuler et qui le réserve donc à des développeurs et des professionnels | |||||
* avertis possédant des connaissances informatiques approfondies. Les | |||||
* utilisateurs sont donc invités à charger et tester l'adéquation du | |||||
* logiciel à leurs besoins dans des conditions permettant d'assurer la | |||||
* sécurité de leurs systèmes et ou de leurs données et, plus généralement, | |||||
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. | |||||
* | |||||
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez | |||||
* pris connaissance de la licence CeCILL, et que vous en avez accepté les | |||||
* termes. | |||||
*/ | |||||
namespace common\models; | namespace common\models; | ||||
use Yii; | use Yii; | ||||
use common\components\ActiveRecordCommon ; | |||||
use common\components\ActiveRecordCommon; | |||||
/** | /** | ||||
* This is the model class for table "user_etablissement". | * This is the model class for table "user_etablissement". | ||||
* @property boolean $actif | * @property boolean $actif | ||||
* @property boolean $favoris | * @property boolean $favoris | ||||
*/ | */ | ||||
class UserProducer extends ActiveRecordCommon | |||||
class UserProducer extends ActiveRecordCommon | |||||
{ | { | ||||
/** | |||||
* @inheritdoc | |||||
*/ | |||||
public static function tableName() | |||||
{ | |||||
return 'user_producer'; | |||||
} | |||||
/** | |||||
* @inheritdoc | |||||
*/ | |||||
public static function tableName() | |||||
{ | |||||
return 'user_producer'; | |||||
} | |||||
/** | |||||
* @inheritdoc | |||||
*/ | |||||
public function rules() | |||||
{ | |||||
return [ | |||||
[['id_user', 'id_producer'], 'required'], | |||||
[['id_user', 'id_producer', 'product_price_percent'], 'integer'], | |||||
[['active', 'bookmark', 'credit_active'], 'boolean'], | |||||
[['credit', 'product_price_percent'], 'double'], | |||||
]; | |||||
} | |||||
/** | |||||
* @inheritdoc | |||||
*/ | |||||
public function attributeLabels() | |||||
{ | |||||
return [ | |||||
'id_user' => 'Utilisateur', | |||||
'id_producer' => 'Producteur', | |||||
'active' => 'Actif', | |||||
'bookmark' => 'Favoris', | |||||
'credit_active' => 'Crédit', | |||||
'product_price_percent' => 'Prix produits : pourcentage' | |||||
]; | |||||
} | |||||
public function getProducer() | |||||
{ | |||||
return $this->hasOne(Producer::className(), ['id' => 'id_producer']); | |||||
} | |||||
/** | |||||
* @inheritdoc | |||||
*/ | |||||
public function rules() | |||||
{ | |||||
return [ | |||||
[['id_user', 'id_producer'], 'required'], | |||||
[['id_user', 'id_producer', 'product_price_percent'], 'integer'], | |||||
[['active','bookmark','credit_active'], 'boolean'], | |||||
[['credit', 'product_price_percent'], 'double'], | |||||
]; | |||||
} | |||||
public function getUser() | |||||
{ | |||||
return $this->hasOne(User::className(), ['id' => 'id_user']); | |||||
} | |||||
/** | |||||
* @inheritdoc | |||||
*/ | |||||
public function attributeLabels() | |||||
{ | |||||
return [ | |||||
'id_user' => 'Utilisateur', | |||||
'id_producer' => 'Producteur', | |||||
'active' => 'Actif', | |||||
'bookmark' => 'Favoris', | |||||
'credit_active' => 'Crédit', | |||||
'product_price_percent' => 'Prix produits : pourcentage' | |||||
]; | |||||
} | |||||
public function getProducer() | |||||
{ | |||||
return $this->hasOne(Producer::className(), ['id' => 'id_producer']); | |||||
} | |||||
/** | |||||
* Retourne les options de base nécessaires à la fonction de recherche. | |||||
* | |||||
* @return array | |||||
*/ | |||||
public static function defaultOptionsSearch() { | |||||
return [ | |||||
'with' => [], | |||||
'join_with' => [], | |||||
'orderby' => '', | |||||
'attribute_id_producer' => 'user_producer.id_producer' | |||||
] ; | |||||
} | |||||
/** | |||||
* Retourne les options de base nécessaires à la fonction de recherche. | |||||
* | |||||
* @return array | |||||
*/ | |||||
public static function defaultOptionsSearch() | |||||
{ | |||||
return [ | |||||
'with' => [], | |||||
'join_with' => [], | |||||
'orderby' => '', | |||||
'attribute_id_producer' => 'user_producer.id_producer' | |||||
]; | |||||
} | |||||
} | } |