*/ | */ | ||||
public function actionIndex() | public function actionIndex() | ||||
{ | { | ||||
$dataProvider = new ActiveDataProvider([ | |||||
'query' => Product::find() | |||||
->where(['id_producer' => Producer::getId()]) | |||||
->orderBy('order ASC'), | |||||
'pagination' => [ | |||||
'pageSize' => 1000, | |||||
], | |||||
]); | |||||
$searchModel = new ProductSearch() ; | |||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); | |||||
return $this->render('index', [ | return $this->render('index', [ | ||||
'searchModel' => $searchModel, | |||||
'dataProvider' => $dataProvider, | 'dataProvider' => $dataProvider, | ||||
]); | ]); | ||||
} | } | ||||
$productDistribution->active = 0; | $productDistribution->active = 0; | ||||
$productDistribution->save(); | $productDistribution->save(); | ||||
} | } | ||||
Yii::$app->getSession()->setFlash('success', 'Produit <strong>'.Html::encode($model->name).'</strong> ajouté'); | |||||
return $this->redirect(['index']); | return $this->redirect(['index']); | ||||
} else { | } else { | ||||
$model->save(); | $model->save(); | ||||
} | } | ||||
Yii::$app->getSession()->setFlash('success', 'Produit <strong>'.Html::encode($model->name).'</strong> modifié'); | |||||
return $this->redirect(['index']); | return $this->redirect(['index']); | ||||
} else { | } else { | ||||
return $this->render('update', [ | return $this->render('update', [ | ||||
*/ | */ | ||||
public function actionDelete($id) | public function actionDelete($id) | ||||
{ | { | ||||
$this->findModel($id)->delete(); | |||||
$model = $this->findModel($id) ; | |||||
$model->delete(); | |||||
ProductDistribution::deleteAll(['id_product' => $id]) ; | ProductDistribution::deleteAll(['id_product' => $id]) ; | ||||
Yii::$app->getSession()->setFlash('success', 'Produit <strong>'.Html::encode($model->name).'</strong> supprimé'); | |||||
return $this->redirect(['index']); | return $this->redirect(['index']); | ||||
} | } | ||||
if (!Product::searchCount() || !PointSale::searchCount()) { | if (!Product::searchCount() || !PointSale::searchCount()) { | ||||
$this->redirect(['site/index', 'error_products_points_sale' => 1]); | $this->redirect(['site/index', 'error_products_points_sale' => 1]); | ||||
} | } | ||||
/*$dataProvider = new ActiveDataProvider([ | |||||
'query' => Subscription::find() | |||||
->with(['user', 'producer', 'pointSale', 'productSubscription', 'productSubscription.product']) | |||||
->joinWith(['user']) | |||||
->where(['subscription.id_producer' => Producer::getId()]) | |||||
->orderBy('subscription.id_point_sale ASC, CASE `subscription`.`username` WHEN "" THEN `user`.`name` ELSE `subscription`.`username` END ASC'), | |||||
'pagination' => [ | |||||
'pageSize' => 1000, | |||||
], | |||||
]);*/ | |||||
$searchModel = new SubscriptionSearch ; | $searchModel = new SubscriptionSearch ; | ||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); | ||||
return $this->render('index', [ | return $this->render('index', [ |
<div class="product-index"> | <div class="product-index"> | ||||
<?= GridView::widget([ | <?= GridView::widget([ | ||||
'filterModel' => $searchModel, | |||||
'dataProvider' => $dataProvider, | 'dataProvider' => $dataProvider, | ||||
'columns' => [ | 'columns' => [ | ||||
[ | [ | ||||
'attribute' => 'order', | 'attribute' => 'order', | ||||
'headerOptions' => ['class' => 'order'], | 'headerOptions' => ['class' => 'order'], | ||||
'format' => 'raw', | 'format' => 'raw', | ||||
'filter' => '', | |||||
'value' => function($model) { | 'value' => function($model) { | ||||
return '<a class="btn-order btn btn-default" href="javascript:void(0);"><span class="glyphicon glyphicon-resize-vertical"></span></a>' ; | return '<a class="btn-order btn btn-default" href="javascript:void(0);"><span class="glyphicon glyphicon-resize-vertical"></span></a>' ; | ||||
} | } | ||||
'attribute' => 'photo', | 'attribute' => 'photo', | ||||
'format' => 'raw', | 'format' => 'raw', | ||||
'headerOptions' => ['class' => 'td-photo'], | 'headerOptions' => ['class' => 'td-photo'], | ||||
'filter' => '', | |||||
'value' => function($model) { | 'value' => function($model) { | ||||
if(strlen($model->photo)) { | if(strlen($model->photo)) { | ||||
$url = Yii::$app->urlManagerProducer->getBaseUrl() ; | $url = Yii::$app->urlManagerProducer->getBaseUrl() ; | ||||
'headerOptions' => ['class' => 'active'], | 'headerOptions' => ['class' => 'active'], | ||||
'contentOptions' => ['class' => 'center'], | 'contentOptions' => ['class' => 'center'], | ||||
'format' => 'raw', | 'format' => 'raw', | ||||
'filter' => [0 => 'Non', 1 => 'Oui'], | |||||
'value' => function($model) { | 'value' => function($model) { | ||||
if($model->active) | if($model->active) | ||||
{ | { | ||||
[ | [ | ||||
'class' => 'yii\grid\ActionColumn', | 'class' => 'yii\grid\ActionColumn', | ||||
'template' => '{update} {delete}', | 'template' => '{update} {delete}', | ||||
'headerOptions' => ['class' => 'actions'], | |||||
'headerOptions' => ['class' => 'column-actions'], | |||||
'contentOptions' => ['class' => 'column-actions'], | |||||
'buttons' => [ | 'buttons' => [ | ||||
'update' => function ($url, $model) { | 'update' => function ($url, $model) { | ||||
return Html::a('<span class="glyphicon glyphicon-pencil"></span> Modifier', $url, [ | |||||
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [ | |||||
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default' | 'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default' | ||||
]); | ]); | ||||
}, | }, | ||||
'delete' => function ($url, $model) { | 'delete' => function ($url, $model) { | ||||
return Html::a('<span class="glyphicon glyphicon-trash"></span> Suprimer', $url, [ | |||||
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [ | |||||
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default' | 'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default' | ||||
]); | ]); | ||||
} | } |
[ | [ | ||||
'class' => 'yii\grid\ActionColumn', | 'class' => 'yii\grid\ActionColumn', | ||||
'template' => '{update} {delete}', | 'template' => '{update} {delete}', | ||||
'headerOptions' => ['class' => 'actions'], | |||||
'headerOptions' => ['class' => 'column-actions'], | |||||
'contentOptions' => ['class' => 'column-actions'], | |||||
'buttons' => [ | 'buttons' => [ | ||||
'update' => function ($url, $model) { | 'update' => function ($url, $model) { | ||||
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [ | return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [ |
return ui; | return ui; | ||||
}; | }; | ||||
$(".produit-index table tbody").sortable({ | |||||
$(".product-index table tbody").sortable({ | |||||
items: "> tr", | items: "> tr", | ||||
appendTo: "parent", | appendTo: "parent", | ||||
cursor: "move", | cursor: "move", | ||||
var tab_ordre = {} ; | var tab_ordre = {} ; | ||||
var ordre = 1 ; | var ordre = 1 ; | ||||
$(".produit-index table tbody tr").each(function() { | |||||
$(".product-index table tbody tr").each(function() { | |||||
tab_ordre[$(this).attr('data-key')] = ordre ; | tab_ordre[$(this).attr('data-key')] = ordre ; | ||||
ordre++ ; | ordre++ ; | ||||
}) ; | }) ; | ||||
console.log(tab_ordre) ; | console.log(tab_ordre) ; | ||||
$.get(UrlManager.getBaseUrl()+'produit/ordre',{ | |||||
tab: JSON.stringify(tab_ordre) | |||||
$.get(UrlManager.getBaseUrl()+'product/order',{ | |||||
array: JSON.stringify(tab_ordre) | |||||
}) ; | }) ; | ||||
} | } | ||||
}).disableSelection(); | }).disableSelection(); |
th { | th { | ||||
font-size: 13px ; | font-size: 13px ; | ||||
} | } | ||||
th.column-actions, td.column-actions { | |||||
width: 130px ; | |||||
text-align: right ; | |||||
} | |||||
td.text-small, th.text-small { | td.text-small, th.text-small { | ||||
font-size: 12px ; | font-size: 12px ; | ||||
} | } | ||||
} | } | ||||
.pagination > .active > a, .pagination > .active > span, .pagination > .active > a:hover, .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { | |||||
background-color: $color1 ; | |||||
border: solid 1px $color1 ; | |||||
color: white ; | |||||
} | |||||
.pagination > li > a, .pagination > li > span { | |||||
color: $color1 ; | |||||
&:hover { | |||||
color: darken($color1, 10) ; | |||||
} | |||||
} | |||||
} | } | ||||
.main-footer { | .main-footer { |
.product-index { | |||||
.td-photo { | |||||
max-width: 100px ; | |||||
width: 100px ; | |||||
} | |||||
.photo-product { | |||||
max-width: 100px ; | |||||
} | |||||
.ui-state-highlight { | |||||
height: 75px; | |||||
background-color: $color2 ; | |||||
} | |||||
} |
z-index: 1031 ; | z-index: 1031 ; | ||||
} | } | ||||
.pagination > .active > a, .pagination > .active > span, .pagination > .active > a:hover, .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { | |||||
background-color: $color1 ; | |||||
border: solid 1px $color1 ; | |||||
} | |||||
.pagination > li > a, .pagination > li > span { | |||||
color: $color1 ; | |||||
&:hover { | |||||
color: darken($color1, 10) ; | |||||
} | |||||
} | |||||
.wrap { | .wrap { | ||||
.btn-primary, | .btn-primary, | ||||
.btn-success { | .btn-success { | ||||
background-color: white ; | background-color: white ; | ||||
} | } | ||||
.wrap .product-index { | |||||
.td-photo { | |||||
max-width: 100px ; | |||||
width: 100px ; | |||||
} | |||||
.photo-product { | |||||
max-width: 100px ; | |||||
} | |||||
.ui-state-highlight { | |||||
height: 75px; | |||||
background-color: $color2 ; | |||||
} | |||||
} | |||||
/* communiquer */ | /* communiquer */ | ||||
@import "_adminlte.scss" ; | @import "_adminlte.scss" ; | ||||
@import "site/_index.scss" ; | @import "site/_index.scss" ; | ||||
@import "subscription/_index.scss" ; | |||||
@import "subscription/_index.scss" ; | |||||
@import "product/_index.scss" ; |
<?php | |||||
/** | |||||
Copyright La boîte à pain (2018) | |||||
contact@laboiteapain.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 ; | |||||
use common\models\Product ; | |||||
class ProductSearch extends Product | |||||
{ | |||||
public function rules() | |||||
{ | |||||
return [ | |||||
[['active', 'order', 'quantity_max', 'id_producer'], 'integer'], | |||||
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable'], 'boolean'], | |||||
[['price', 'weight'], 'number'], | |||||
[[ 'photo'], 'file'], | |||||
[['name', 'description', 'photo'], 'string', 'max' => 255], | |||||
[['recipe'], 'string', 'max' => 1000], | |||||
]; | |||||
} | |||||
public function search($params) | |||||
{ | |||||
$optionsSearch = self::defaultOptionsSearch() ; | |||||
$query = Product::find() | |||||
->with($optionsSearch['with']) | |||||
->innerJoinWith($optionsSearch['join_with'], true) | |||||
->where(['product.id_producer' => Producer::getId()]) | |||||
; | |||||
$dataProvider = new ActiveDataProvider([ | |||||
'query' => $query, | |||||
'sort' => ['attributes' => ['order', 'photo', 'name', 'description','active']], | |||||
'pagination' => [ | |||||
'pageSize' => 20, | |||||
], | |||||
]); | |||||
$this->load($params); | |||||
if (!$this->validate()) { | |||||
return $dataProvider; | |||||
} | |||||
$query->andFilterWhere(['like', 'product.name', $this->name]) ; | |||||
$query->andFilterWhere(['like', 'product.description', $this->description]) ; | |||||
if(isset($this->active) && is_numeric($this->active)) { | |||||
$query->andWhere([ | |||||
'product.active' => $this->active | |||||
]) ; | |||||
} | |||||
return $dataProvider; | |||||
} | |||||
} |