Browse Source

[Administration] Tableau de bord administrateur

feature/souke
Guillaume Bourgeois 9 months ago
parent
commit
9fb5952ccf
10 changed files with 372 additions and 27 deletions
  1. +85
    -0
      backend/controllers/DashboardAdminController.php
  2. +166
    -0
      backend/views/dashboard-admin/index.php
  3. +6
    -0
      backend/views/layouts/left.php
  4. +37
    -22
      backend/web/css/screen.css
  5. +11
    -1
      backend/web/js/backend.js
  6. +18
    -0
      backend/web/sass/_adminlte.scss
  7. +4
    -0
      backend/web/sass/dashboard-admin/_index.scss
  8. +1
    -0
      backend/web/sass/screen.scss
  9. +39
    -4
      domain/Producer/Producer/DolibarrProducerUtils.php
  10. +5
    -0
      domain/User/User/UserRepository.php

+ 85
- 0
backend/controllers/DashboardAdminController.php View File

<?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.
*/

namespace backend\controllers;

use common\helpers\Price;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;

class DashboardAdminController extends BackendController
{
/**
* @inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return $this->getUserModule()
->getAuthorizationChecker()
->isGrantedAsAdministrator($this->getUserCurrent());
}
],
],
],
];
}


public function actionIndex()
{
return $this->render('index', [
'countUsersOnline' => $this->getUserModule()->getRepository()->countUsersOnline(),
'countTicketsAdminOpen' => $this->getTicketModule()->getRepository()->countTicketsAdminStatusOpen(),
'countTicketsAdminUnread' => $this->getTicketModule()->getRepository()->countTicketsAdminUnreadByUser($this->getUserCurrent()),
'amountProducerUnpaidInvoices' => '--',
]);
}

public function actionAjaxAmountProducerInvoicesUnpaid()
{
return Price::format($this->getProducerModule()->getDolibarrUtils()->getAmountProducerInvoicesUnpaid());
}
}

+ 166
- 0
backend/views/dashboard-admin/index.php View File

<?php

$this->setTitle('Tableau de bord');

?>

<div class="dashboard-admin-index">
<div class="row">
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-aqua">
<div class="inner">
<h3><?= $countUsersOnline ?></h3>
<p>En ligne</p>
</div>
<div class="icon">
<i class="fa fa-wifi"></i>
</div>
<a href="<?= Yii::$app->urlManager->createUrl('online-admin/index') ?>" class="small-box-footer">
Voir <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-green">
<div class="inner">
<h3><?= 'Oui' ?></h3>
<p>Support activé</p>
</div>
<div class="icon">
<i class="fa fa-phone"></i>
</div>
<a href="<?= Yii::$app->urlManager->createUrl('support-admin/index') ?>" class="small-box-footer">
Désactiver <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-<?= $countTicketsAdminUnread ? 'green' : 'blue' ?>">
<div class="inner">
<h3><?= $countTicketsAdminOpen ?></h3>
<p>Tickets</p>
</div>
<div class="icon">
<i class="fa fa-comments"></i>
</div>
<a href="<?= Yii::$app->urlManager->createUrl('support-admin/index') ?>" class="small-box-footer">
Voir <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-green">
<div class="inner">
<h3><?= '1230 €' ?></h3>
<p>Total factures producteurs mois en cours</p>
</div>
<div class="icon">
<i class="fa fa-euro"></i>
</div>
<a href="<?= Yii::$app->urlManager->createUrl('producer-admin/index') ?>" class="small-box-footer">
Voir <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-red">
<div class="inner">
<h3 id="amount-producer-invoices-unpaid"><?= $amountProducerUnpaidInvoices ?></h3>
<p>Montant factures impayées</p>
</div>
<div class="icon">
<i class="fa fa-euro"></i>
</div>
<a target="_blank" href="<?= Yii::$app->parameterBag->get('dolibarrUrl') ?>compta/facture/list.php?leftmenu=customers_bills_notpaid&search_status=1" class="small-box-footer">
Voir <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-yellow">
<div class="inner">
<h3><?= '127 000 €' ?></h3>
<p>CA producteurs 30 derniers jours</p>
</div>
<div class="icon">
<i class="fa fa-line-chart"></i>
</div>
<a href="<?= Yii::$app->urlManager->createUrl('stats-admin/turnover') ?>" class="small-box-footer">
Voir <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-yellow">
<div class="inner">
<h3><?= '141' ?></h3>
<p>Commandes clients / jour</p>
</div>
<div class="icon">
<i class="fa fa-line-chart"></i>
</div>
<a href="<?= Yii::$app->urlManager->createUrl('stats-admin/turnover') ?>" class="small-box-footer">
Voir <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-aqua">
<div class="inner">
<h3>43</h3>
<p>Producteurs actifs sur les 3 derniers mois</p>
</div>
<div class="icon">
<i class="fa fa-th-list"></i>
</div>
<div class="small-box-footer">&nbsp;</div>
</div>
</div>
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-aqua">
<div class="inner">
<h3>357</h3>
<p>Points de vente actifs sur les 3 derniers mois</p>
</div>
<div class="icon">
<i class="fa fa-map-marker"></i>
</div>
<div class="small-box-footer">&nbsp;</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-aqua">
<div class="inner">
<h3>3 865</h3>
<p>Clients actifs sur les 3 derniers mois</p>
</div>
<div class="icon">
<i class="fa fa-users"></i>
</div>
<div class="small-box-footer">&nbsp;</div>
</div>
</div>
<div class="col-lg-6 col-xs-6">
<div class="small-box bg-aqua">
<div class="inner">
<h3>32</h3>
<p>Inscriptions utilisateurs des 7 derniers jours</p>
</div>
<div class="icon">
<i class="fa fa-user-plus"></i>
</div>
<div class="small-box-footer">&nbsp;</div>
</div>
</div>
</div>
</div>

+ 6
- 0
backend/views/layouts/left.php View File



// Administration // Administration
['label' => 'Administration', 'options' => ['class' => 'header'], 'visible' => $isUserCurrentGrantedAsAdministrator], ['label' => 'Administration', 'options' => ['class' => 'header'], 'visible' => $isUserCurrentGrantedAsAdministrator],
[
'label' => 'Tableau de bord',
'icon' => 'dashboard',
'url' => ['dashboard-admin/index'],
'visible' => $isUserCurrentGrantedAsAdministrator,
],
[ [
'label' => 'En ligne', 'label' => 'En ligne',
'icon' => 'wifi', 'icon' => 'wifi',

+ 37
- 22
backend/web/css/screen.css View File

opacity: 1; opacity: 1;
} }
/* line 301, ../sass/_adminlte.scss */ /* line 301, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .small-box h3 {
font-size: 28px;
font-family: 'Source Sans Pro',sans-serif;
}
/* line 306, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .small-box .icon {
top: -2px;
}
/* line 310, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .small-box .small-box-footer {
color: white;
padding-top: 6px;
padding-bottom: 2px;
}
/* line 319, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout h4 .fa { body.skin-black .content-wrapper .callout h4 .fa {
margin-right: 7px; margin-right: 7px;
} }
/* line 304, ../sass/_adminlte.scss */
/* line 322, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout a { body.skin-black .content-wrapper .callout a {
color: white; color: white;
} }
/* line 307, ../sass/_adminlte.scss */
/* line 325, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout .btn { body.skin-black .content-wrapper .callout .btn {
color: #333; color: #333;
text-decoration: none; text-decoration: none;
} }
/* line 314, ../sass/_adminlte.scss */
/* line 332, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table th { body.skin-black .content-wrapper .table th {
font-size: 13px; font-size: 13px;
} }
/* line 317, ../sass/_adminlte.scss */
/* line 335, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table th.column-actions, body.skin-black .content-wrapper .table td.column-actions { body.skin-black .content-wrapper .table th.column-actions, body.skin-black .content-wrapper .table td.column-actions {
width: 172px; width: 172px;
text-align: right; text-align: right;
} }
/* line 321, ../sass/_adminlte.scss */
/* line 339, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table td.text-small, body.skin-black .content-wrapper .table th.text-small { body.skin-black .content-wrapper .table td.text-small, body.skin-black .content-wrapper .table th.text-small {
font-size: 12px; font-size: 12px;
} }
/* line 326, ../sass/_adminlte.scss */
/* line 344, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > .active > a, body.skin-black .content-wrapper .pagination > .active > span, body.skin-black .content-wrapper .pagination > .active > a:hover, body.skin-black .content-wrapper .pagination > .active > span:hover, body.skin-black .content-wrapper .pagination > .active > a:focus, body.skin-black .content-wrapper .pagination > .active > span:focus { body.skin-black .content-wrapper .pagination > .active > a, body.skin-black .content-wrapper .pagination > .active > span, body.skin-black .content-wrapper .pagination > .active > a:hover, body.skin-black .content-wrapper .pagination > .active > span:hover, body.skin-black .content-wrapper .pagination > .active > a:focus, body.skin-black .content-wrapper .pagination > .active > span:focus {
background-color: #F39C12; background-color: #F39C12;
border: solid 1px #F39C12; border: solid 1px #F39C12;
color: white; color: white;
} }
/* line 332, ../sass/_adminlte.scss */
/* line 350, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > li > a, body.skin-black .content-wrapper .pagination > li > span { body.skin-black .content-wrapper .pagination > li > a, body.skin-black .content-wrapper .pagination > li > span {
color: #F39C12; color: #F39C12;
} }
/* line 334, ../sass/_adminlte.scss */
/* line 352, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > li > a:hover, body.skin-black .content-wrapper .pagination > li > span:hover { body.skin-black .content-wrapper .pagination > li > a:hover, body.skin-black .content-wrapper .pagination > li > span:hover {
color: #c87f0a; color: #c87f0a;
} }
/* line 339, ../sass/_adminlte.scss */
/* line 357, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .submenu { body.skin-black .content-wrapper .submenu {
margin-bottom: 25px; margin-bottom: 25px;
} }
/* line 343, ../sass/_adminlte.scss */
/* line 361, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-actions { body.skin-black .content-wrapper .form-actions {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
z-index: 10; z-index: 10;
border-top: solid 1px #e0e0e0; border-top: solid 1px #e0e0e0;
} }
/* line 356, ../sass/_adminlte.scss */
/* line 374, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-actions a, body.skin-black .content-wrapper .form-actions button { body.skin-black .content-wrapper .form-actions a, body.skin-black .content-wrapper .form-actions button {
margin-left: 10px; margin-left: 10px;
} }
/* line 361, ../sass/_adminlte.scss */
/* line 379, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-buttons { body.skin-black .content-wrapper .form-buttons {
margin-top: 25px; margin-top: 25px;
text-align: right; text-align: right;
} }
/* line 368, ../sass/_adminlte.scss */
/* line 386, ../sass/_adminlte.scss */
body.skin-black .main-footer a { body.skin-black .main-footer a {
color: #F39C12; color: #F39C12;
} }
/* line 373, ../sass/_adminlte.scss */
/* line 391, ../sass/_adminlte.scss */
body.skin-black .gridview-pagesize { body.skin-black .gridview-pagesize {
float: right; float: right;
margin-bottom: 8px; margin-bottom: 8px;
} }
/* line 378, ../sass/_adminlte.scss */
/* line 396, ../sass/_adminlte.scss */
body.skin-black #yii-debug-toolbar { body.skin-black #yii-debug-toolbar {
bottom: 64px; bottom: 64px;
} }


/* line 383, ../sass/_adminlte.scss */
/* line 401, ../sass/_adminlte.scss */
body.login-page { body.login-page {
background: none; background: none;
background-color: white; background-color: white;
} }
/* line 387, ../sass/_adminlte.scss */
/* line 405, ../sass/_adminlte.scss */
body.login-page .login-box .login-logo { body.login-page .login-box .login-logo {
text-align: center; text-align: center;
font-family: 'highvoltageregular'; font-family: 'highvoltageregular';
} }
/* line 391, ../sass/_adminlte.scss */
/* line 409, ../sass/_adminlte.scss */
body.login-page .login-box .login-logo img { body.login-page .login-box .login-logo img {
width: 50px; width: 50px;
} }
/* line 396, ../sass/_adminlte.scss */
/* line 414, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .btn-primary { body.login-page .login-box .login-box-body .btn-primary {
background-color: #F39C12; background-color: #F39C12;
border-color: #F39C12; border-color: #F39C12;
padding: 5px 10px; padding: 5px 10px;
} }
/* line 401, ../sass/_adminlte.scss */
/* line 419, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .btn-primary:active { body.login-page .login-box .login-box-body .btn-primary:active {
background-color: #f4a62a; background-color: #f4a62a;
border-color: #F39C12; border-color: #F39C12;
} }
/* line 407, ../sass/_adminlte.scss */
/* line 425, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body a { body.login-page .login-box .login-box-body a {
color: #F39C12; color: #F39C12;
} }
/* line 409, ../sass/_adminlte.scss */
/* line 427, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body a:hover { body.login-page .login-box .login-box-body a:hover {
color: #f4a62a; color: #f4a62a;
} }

+ 11
- 1
backend/web/js/backend.js View File

opendistrib_features_index(); opendistrib_features_index();
opendistrib_point_sale_form(); opendistrib_point_sale_form();
opendistrib_check_all_checkboxes(); opendistrib_check_all_checkboxes();
opendistrib_dashboard_admin_invoices_unpaid();
}); });


var UrlManager = { var UrlManager = {
getBaseUrl: function () { getBaseUrl: function () {
return $('meta[name=baseurl]').attr('content') + '/'; return $('meta[name=baseurl]').attr('content') + '/';

}, },
getBaseUrlAbsolute: function () { getBaseUrlAbsolute: function () {
return $('meta[name=baseurl-absolute]').attr('content') + '/'; return $('meta[name=baseurl-absolute]').attr('content') + '/';
} }
}; };


function opendistrib_dashboard_admin_invoices_unpaid() {
var selector = '#amount-producer-invoices-unpaid';
$(selector).click(function() {
$(this).html('<i class="fa fa-spinner"></i>');
$.get(UrlManager.getBaseUrl() + 'dashboard-admin/ajax-amount-producer-invoices-unpaid', {}, function(result) {
$(selector).html(result);
});
});
}

function opendistrib_check_all_checkboxes() { function opendistrib_check_all_checkboxes() {
$('.check-all-checkboxes').change(function() { $('.check-all-checkboxes').change(function() {
var selector = $(this).data('selector'); var selector = $(this).data('selector');

+ 18
- 0
backend/web/sass/_adminlte.scss View File

} }
} }
} }

.small-box {
h3 {
font-size: 28px;
font-family: 'Source Sans Pro',sans-serif;
}

.icon {
top: -2px;
}

.small-box-footer {
color: white;
padding-top: 6px;
padding-bottom: 2px;

}
}
.callout { .callout {
h4 .fa { h4 .fa {

+ 4
- 0
backend/web/sass/dashboard-admin/_index.scss View File


.dashboard-admin-index {

}

+ 1
- 0
backend/web/sass/screen.scss View File

@import "online-admin/_index.scss"; @import "online-admin/_index.scss";
@import "feature-admin/_index.scss"; @import "feature-admin/_index.scss";
@import "setting/_form.scss"; @import "setting/_form.scss";
@import "dashboard-admin/_index.scss" ;
@import "_responsive.scss" ; @import "_responsive.scss" ;

+ 39
- 4
domain/Producer/Producer/DolibarrProducerUtils.php View File

return $invoicesArray; return $invoicesArray;
} }


public function countDolibarrProducerInvoicesUnpaid(Producer $producer): int
public function getDolibarrProducerInvoicesUnpaid(Producer $producer): array
{ {
$count = 0;
$unpaidInvoicesArray = [];
$invoicesArray = $this->getDolibarrProducerInvoices($producer); $invoicesArray = $this->getDolibarrProducerInvoices($producer);

foreach($invoicesArray as $invoice) { foreach($invoicesArray as $invoice) {
if($invoice['remaintopay'] > 0) { if($invoice['remaintopay'] > 0) {
$count ++;
$unpaidInvoicesArray[] = $invoice;
} }
} }


return $count;
return $unpaidInvoicesArray;
}

public function countDolibarrProducerInvoicesUnpaid(Producer $producer): int
{
return count($this->getDolibarrProducerInvoicesUnpaid($producer));
}

public function getDolibarrInvoicesUnpaid()
{
$unpaidInvoicesArray = [];
$producersArray = $this->producerRepository->findProducersActive();

foreach($producersArray as $producer) {
$unpaidInvoicesArray = array_merge(
$unpaidInvoicesArray,
$this->getDolibarrProducerInvoicesUnpaid($producer)
);
}

//die('test : '.count($unpaidInvoicesArray));

return $unpaidInvoicesArray;
}

public function getAmountProducerInvoicesUnpaid()
{
$amount = 0;
$unpaidInvoicesArray = $this->getDolibarrInvoicesUnpaid();

foreach($unpaidInvoicesArray as $unpaidInvoice) {
$amount += $unpaidInvoice['remaintopay'];
}

return $amount;
} }


public function generateDolibarrProducerInvoice(Producer $producer) public function generateDolibarrProducerInvoice(Producer $producer)

+ 5
- 0
domain/User/User/UserRepository.php View File

{ {
return count($this->findUsersWithStatusUserAndOnline()); return count($this->findUsersWithStatusUserAndOnline());
} }

public function countUsersOnline(): int
{
return $this->countUsersStatusUserOnline() + $this->countUsersStatusProducerOnline();
}
} }

Loading…
Cancel
Save