Переглянути джерело

[backend] Rapports : génération du rapport

refactoring
Guillaume Bourgeois 5 роки тому
джерело
коміт
8553f472cd
7 змінених файлів з 466 додано та 336 видалено
  1. +59
    -0
      backend/controllers/ReportController.php
  2. +28
    -5
      backend/views/report/index.php
  3. +258
    -255
      backend/web/css/screen.css
  4. +46
    -2
      backend/web/js/vuejs/report-index.js
  5. +0
    -73
      backend/web/sass/distribution/_index.scss
  6. +1
    -1
      backend/web/sass/report/_index.scss
  7. +74
    -0
      backend/web/sass/screen.scss

+ 59
- 0
backend/controllers/ReportController.php Переглянути файл

@@ -45,6 +45,7 @@ use common\models\Distribution ;

class ReportController extends BackendController
{
var $enableCsrfValidation = false;

public function behaviors()
{
@@ -120,4 +121,62 @@ class ReportController extends BackendController
] ;
}
public function actionAjaxReport()
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$posts = Yii::$app->request->post();
$resArray = [] ;

$conditionUsers = $this->_generateConditionSqlReport($posts, 'users', 'id_user') ;
$conditionPointsSale = $this->_generateConditionSqlReport($posts, 'pointsSale', 'id_point_sale') ;
$conditionDistributions = $this->_generateConditionSqlReport($posts, 'distributions', 'id_distribution') ;
$res = Yii::$app->db->createCommand("SELECT product.name, SUM(product_order.quantity) AS quantity, SUM(product_order.price * product_order.quantity) AS total
FROM `order`, product_order, product
WHERE `order`.id = product_order.id_order
AND product_order.id_product = product.id
".$conditionUsers."
".$conditionPointsSale."
".$conditionDistributions."
GROUP BY product.id
ORDER BY product.name ASC
")
->queryAll();

$totalGlobal = 0 ;
foreach($res as $line) {
$total = Price::format(round($line['total'], 2)) ;
if($line['quantity'] > 0) {
$resArray[] = [
'name' => $line['name'],
'quantity' => $line['quantity'],
'total' => $total,
] ;
$totalGlobal += $total ;
}
}
$resArray[] = [
'name' => '',
'quantity' => '',
'total' => '<strong>'.Price::format(round($totalGlobal, 2)).'</strong>',
] ;
return $resArray ;
}
public function _generateConditionSqlReport($posts, $name, $fieldOrder)
{
$condition = '' ;
if(isset($posts[$name]) && strlen($posts[$name])) {
$idsArray = explode(',', $posts[$name]) ;
for($i = 0; $i < count($idsArray); $i++) {
$idsArray[$i] = (int) $idsArray[$i] ;
}
$condition = 'AND `order`.'.$fieldOrder.' IN ('.implode(',',$idsArray).') ' ;
}
return $condition ;
}
}

+ 28
- 5
backend/views/report/index.php Переглянути файл

@@ -46,7 +46,7 @@ $this->addBreadcrumb('Rapports') ;
<div id="loading" v-if="showLoading">
<img src="<?= Yii::$app->urlManagerBackend->getBaseUrl(); ?>/img/loader.gif" alt="Chargement ..." />
</div>
<div id="wrapper-app-report-index" :class="'wrapper-app-vuejs '+(showLoading ? '' : 'loaded')">
<div id="wrapper-app-report-index" :class="'wrapper-app-vuejs '+(loading ? '' : 'loaded')">
<div id="parameters" class="col-md-6">
<div id="nav-sections-report">
<a v-for="section in sections" :class="'btn-section btn '+(currentSection == section.id ? 'btn-primary' : 'btn-default')" @click="changeSection(section)"><span :class="'fa '+section.icon"></span> {{ section.name }}<span v-if="currentSection == section.id"> <span class="glyphicon glyphicon-triangle-bottom"></span></span></a>
@@ -60,7 +60,7 @@ $this->addBreadcrumb('Rapports') ;
<div class="content-max-height">
<ul id="list-users">
<li v-for="user in usersArray" v-if="!termSearchUser.length || (termSearchUser.length && (user.lastname.toLowerCase().indexOf(termSearchUser.toLowerCase()) != -1 || user.name.toLowerCase().indexOf(termSearchUser.toLowerCase()) != -1 ))">
<input type="checkbox" :id="'user_'+user.user_id" v-model="user.checked" />
<input type="checkbox" :id="'user_'+user.user_id" v-model="user.checked" @change="reportChange" />
<label :for="'user_'+user.user_id" v-html="user.lastname+' '+user.name"></label>
</li>
</ul>
@@ -72,7 +72,7 @@ $this->addBreadcrumb('Rapports') ;
<div class="content-max-height">
<ul class="list" id="list-points-sale">
<li v-for="pointSale in pointsSaleArray">
<input type="checkbox" :id="'pointsale_'+pointSale.id" v-model="pointSale.checked" />
<input type="checkbox" :id="'pointsale_'+pointSale.id" v-model="pointSale.checked" @change="reportChange" />
<label :for="'pointsale_'+pointSale.id" v-html="pointSale.name"></label>
</li>
</ul>
@@ -91,7 +91,7 @@ $this->addBreadcrumb('Rapports') ;
<a class="btn btn-default link-month-distribution" @click="distributionsMonth.display = !distributionsMonth.display">{{ distributionsMonth.month }} <span class="glyphicon glyphicon-menu-down"></span></a>
<ul v-if="distributionsMonth.display">
<li v-for="distribution in distributionsMonth.distributions">
<input type="checkbox" :id="'distribution_'+distribution.id" v-model="distribution.checked" />
<input type="checkbox" :id="'distribution_'+distribution.id" v-model="distribution.checked" @change="reportChange" />
<label :for="'distribution_'+distribution.id">{{ distribution.date }}</label>
</li>
</ul>
@@ -133,10 +133,33 @@ $this->addBreadcrumb('Rapports') ;
</div>
</div>
<div id="report" v-if="countUsers() || countPointsSale() || countDistributions()">
<a href="#" class="btn btn-primary">Générer</a>
<div class="content-report section" v-if="showReport">
<h3><span class="fa fa-pencil-square-o"></span> Rapport</h3>
<table class="table table-bordered" v-if="tableReport.length > 1">
<thead>
<tr>
<th>Produit</th>
<th>Quantité</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr v-for="line in tableReport">
<td>{{ line.name }}</td>
<td>{{ line.quantity }}</td>
<td v-html="line.total"></td>
</tr>
</tbody>
</table>
<div class="alert alert-warning" v-else>
Aucune donnée disponible pour ces critères.
</div>
</div>
<a class="btn btn-primary" @click="generateReport()" v-else="!showReport"><span class="fa fa-pencil-square-o"></span> Générer</a>
</div>
</div>
</div>
</div>
</div>
</div>

+ 258
- 255
backend/web/css/screen.css
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 46
- 2
backend/web/js/vuejs/report-index.js Переглянути файл

@@ -2,7 +2,10 @@
var app = new Vue({
el: '#app-report-index',
data: {
loading: true,
showLoading: true,
showReport: false,
tableReport: [],
currentSection: 'users',
sections: [
{
@@ -42,6 +45,7 @@ var app = new Vue({
app.distributionYear = app.distributionYearsArray[app.distributionYearsArray.length - 1] ;
app.distributionsByMonthArray = response.data.distributionsByMonthArray ;
app.loading = false ;
app.showLoading = false ;
});
},
@@ -77,7 +81,47 @@ var app = new Vue({
}
return count ;
},
generateReport: function() {
var app = this ;
app.showLoading = true ;
var data = new FormData();
var idsUsersArray = [] ;
for(var i = 0; i < app.usersArray.length; i++) {
if(app.usersArray[i].checked) {
idsUsersArray.push(app.usersArray[i].user_id) ;
}
}
var idsPointsSaleArray = [] ;
for(var i = 0; i < app.pointsSaleArray.length; i++) {
if(app.pointsSaleArray[i].checked) {
idsPointsSaleArray.push(app.pointsSaleArray[i].id) ;
}
}
var idsDistributionsArray = [] ;
for(var i in this.distributionsByMonthArray) {
for(var j = 0; j < this.distributionsByMonthArray[i].distributions.length; j++) {
if(this.distributionsByMonthArray[i].distributions[j].checked) {
idsDistributionsArray.push(app.distributionsByMonthArray[i].distributions[j].id) ;
}
}
}

data.append('users', idsUsersArray);
data.append('pointsSale', idsPointsSaleArray);
data.append('distributions', idsDistributionsArray);
axios.post("ajax-report",data)
.then(function(response) {
app.tableReport = response.data ;
app.showLoading = false ;
app.showReport = true ;
});
},
reportChange: function() {
this.showReport = false;
}
}
});



+ 0
- 73
backend/web/sass/distribution/_index.scss Переглянути файл

@@ -299,78 +299,5 @@ termes.
}
}
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
display: table;
transition: opacity .3s ease;
}

.modal-wrapper {
display: table-cell;
vertical-align: middle;
}

.modal-container {
width: 70%;
margin: 0px auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
transition: all .3s ease;
font-family: Helvetica, Arial, sans-serif;
}
.modal-header {
padding-bottom: 0px ;
h3 {
margin-top: 0;
color: #333;
text-transform: uppercase ;
margin-bottom: 0px ;
}
}

.modal-body {
margin: 20px 0;
max-height: 300px ;
height: 300px ;
overflow-y: scroll ;
}

.modal-default-button {
float: right;
}

/*
* The following styles are auto-applied to elements with
* transition="modal" when their visibility is toggled
* by Vue.js.
*
* You can easily play with the modal transition by editing
* these styles.
*/

.modal-enter {
opacity: 0;
}

.modal-leave-active {
opacity: 0;
}

.modal-enter .modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}

}


+ 1
- 1
backend/web/sass/report/_index.scss Переглянути файл

@@ -110,7 +110,7 @@ termes.
}
#report {
margin-top: 43px ;
.section {
margin-bottom: 15px ;

+ 74
- 0
backend/web/sass/screen.scss Переглянути файл

@@ -314,6 +314,80 @@ a.btn, button.btn {
}
}

/* modals */

.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
display: table;
transition: opacity .3s ease;
}

.modal-wrapper {
display: table-cell;
vertical-align: middle;
}

.modal-container {
width: 70%;
margin: 0px auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
transition: all .3s ease;
font-family: Helvetica, Arial, sans-serif;
}

.modal-header {
padding-bottom: 0px ;
h3 {
margin-top: 0;
color: #333;
text-transform: uppercase ;
margin-bottom: 0px ;
}
}

.modal-body {
margin: 20px 0;
max-height: 300px ;
height: 300px ;
overflow-y: scroll ;
}

.modal-default-button {
float: right;
}

/*
* The following styles are auto-applied to elements with
* transition="modal" when their visibility is toggled
* by Vue.js.
*
* You can easily play with the modal transition by editing
* these styles.
*/

.modal-enter {
opacity: 0;
}

.modal-leave-active {
opacity: 0;
}

.modal-enter .modal-container,
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}

// liste de commandes
.site-index, .user-commandes {
#last-orders, #history-orders {

Завантаження…
Відмінити
Зберегти