Sfoglia il codice sorgente

[Backend] Page de support : infos de contact + affichage des tickets

feature/souke
Guillaume Bourgeois 1 anno fa
parent
commit
c6abef807c
37 ha cambiato i file con 1471 aggiunte e 92 eliminazioni
  1. +136
    -0
      backend/controllers/SupportController.php
  2. +44
    -39
      backend/views/layouts/left.php
  3. +56
    -0
      backend/views/support/create.php
  4. +141
    -0
      backend/views/support/index.php
  5. +10
    -0
      backend/views/support/view.php
  6. +60
    -44
      backend/web/css/screen.css
  7. +17
    -0
      backend/web/sass/_adminlte.scss
  8. +3
    -0
      common/components/BusinessLogic.php
  9. +36
    -0
      common/components/BusinessLogicTrait.php
  10. +8
    -0
      common/logic/AbstractSolver.php
  11. +0
    -1
      common/logic/Subscription/ProductSubscription/Repository/ProductSubscriptionRepository.php
  12. +0
    -1
      common/logic/Subscription/ProductSubscription/Repository/ProductSubscriptionRepositoryQuery.php
  13. +7
    -7
      common/logic/Subscription/ProductSubscription/Wrapper/ProductSubscriptionManager.php
  14. +117
    -0
      common/logic/Ticket/Ticket/Model/Ticket.php
  15. +89
    -0
      common/logic/Ticket/Ticket/Model/TicketSearch.php
  16. +35
    -0
      common/logic/Ticket/Ticket/Repository/TicketRepository.php
  17. +16
    -0
      common/logic/Ticket/Ticket/Repository/TicketRepositoryQuery.php
  18. +46
    -0
      common/logic/Ticket/Ticket/Service/TicketBuilder.php
  19. +14
    -0
      common/logic/Ticket/Ticket/Service/TicketDefinition.php
  20. +34
    -0
      common/logic/Ticket/Ticket/Service/TicketSolver.php
  21. +42
    -0
      common/logic/Ticket/Ticket/Wrapper/TicketContainer.php
  22. +23
    -0
      common/logic/Ticket/Ticket/Wrapper/TicketManager.php
  23. +105
    -0
      common/logic/Ticket/TicketMessage/Model/TicketMessage.php
  24. +28
    -0
      common/logic/Ticket/TicketMessage/Repository/TicketMessageRepository.php
  25. +16
    -0
      common/logic/Ticket/TicketMessage/Repository/TicketMessageRepositoryQuery.php
  26. +24
    -0
      common/logic/Ticket/TicketMessage/Service/TicketMessageBuilder.php
  27. +14
    -0
      common/logic/Ticket/TicketMessage/Service/TicketMessageDefinition.php
  28. +35
    -0
      common/logic/Ticket/TicketMessage/Wrapper/TicketMessageContainer.php
  29. +21
    -0
      common/logic/Ticket/TicketMessage/Wrapper/TicketMessageManager.php
  30. +103
    -0
      common/logic/Ticket/TicketUser/Model/TicketUser.php
  31. +28
    -0
      common/logic/Ticket/TicketUser/Repository/TicketUserRepository.php
  32. +16
    -0
      common/logic/Ticket/TicketUser/Repository/TicketUserRepositoryQuery.php
  33. +25
    -0
      common/logic/Ticket/TicketUser/Service/TicketUserBuilder.php
  34. +14
    -0
      common/logic/Ticket/TicketUser/Service/TicketUserDefinition.php
  35. +35
    -0
      common/logic/Ticket/TicketUser/Wrapper/TicketUserContainer.php
  36. +21
    -0
      common/logic/Ticket/TicketUser/Wrapper/TicketUserManager.php
  37. +52
    -0
      console/migrations/m230717_120138_module_ticket.php

+ 136
- 0
backend/controllers/SupportController.php Vedi File

@@ -0,0 +1,136 @@
<?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\logic\Ticket\Ticket\Model\TicketSearch;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\web\NotFoundHttpException;

class SupportController extends BackendController
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::class,
'actions' => [
],
],
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return $this->getUserManager()->hasAccessBackend();
}
]
],
],
];
}

public function actionIndex()
{
$searchTicket = new TicketSearch();
$dataProviderTicket = $searchTicket->search(\Yii::$app->request->queryParams);

return $this->render('index', [
'searchTicket' => $searchTicket,
'dataProviderTicket' => $dataProviderTicket
]);
}

public function actionCreate()
{
$ticketManager = $this->getTicketManager();
$ticket = $ticketManager->instanciateTicket($this->getProducerCurrent(), $this->getUserCurrent());

if ($ticket->load(\Yii::$app->request->post()) && $ticketManager->saveCreate($ticket)) {
$this->setFlash('success', 'Le ticket a bien été créé.');
return $this->redirect(['index']);
} else {
return $this->render('create', [
'ticket' => $ticket,
]);
}
}

public function actionView(int $id)
{
$ticketManager = $this->getTicketManager();
$ticket = $this->findTicket($id);
return $this->render('view', [
'ticket' => $ticket
]);
}

public function actionClose(int $id)
{
$ticketManager = $this->getTicketManager();
$ticket = $this->findTicket($id);
$ticketManager->closeTicket($ticket);
$this->addFlash('success', "Le ticket a bien été fermé.");
return $this->redirect(['index']);
}

public function actionOpen(int $id)
{
$ticketManager = $this->getTicketManager();
$ticket = $this->findTicket($id);
$ticketManager->openTicket($ticket);
$this->addFlash('success', "Le ticket a bien été ouvert.");
return $this->redirect(['index']);
}

public function findTicket(int $id)
{
$ticketManager = $this->getTicketManager();
$ticket = $ticketManager->findOneTicketById($id);

if($ticket && $ticketManager->hasTicketAccess($ticket, $this->getUserCurrent())) {
return $ticket;
}
else {
throw new NotFoundHttpException("Le ticket est introuvable.");
}
}
}

+ 44
- 39
backend/views/layouts/left.php Vedi File

@@ -37,6 +37,7 @@
*/

use common\helpers\GlobalParam;
use yii\helpers\Html;

$producerManager = $this->getProducerManager();
$userManager = $this->getUserManager();
@@ -48,51 +49,54 @@ $userManager = $this->getUserManager();
<section class="sidebar">

<?php
$producer = GlobalParam::getCurrentProducer();
$newVersionOpendistribTemplate = '';
if($producer && !$producerManager->isUpToDateWithOpendistribVersion($producer)) {
$newVersionOpendistribTemplate = '<span class="pull-right-container"><small class="label pull-right bg-orange">&nbsp;</small></span>';
}
$producer = GlobalParam::getCurrentProducer();
$newVersionOpendistribTemplate = '';
if ($producer && !$producerManager->isUpToDateWithOpendistribVersion($producer)) {
$newVersionOpendistribTemplate = '<span class="pull-right-container"><small class="label pull-right bg-orange">&nbsp;</small></span>';
}
?>

<?= dmstr\widgets\Menu::widget(
[
'options' => ['class' => 'sidebar-menu tree', 'data-widget' => 'tree'],
'items' => [
['label' => 'Tableau de bord', 'icon' => 'dashboard', 'url' => ['/site/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Distributions', 'icon' => 'calendar', 'url' => ['/distribution/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => "Besoin d'aide ?", 'options' => ['class' => 'header'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Support', 'icon' => 'comments', 'url' => ['support/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => $producer->name, 'options' => ['class' => 'header'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Tableau de bord', 'icon' => 'dashboard', 'url' => ['/site/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Distributions', 'icon' => 'calendar', 'url' => ['/distribution/index'], 'visible' => $userManager->isCurrentProducer()],
[
'label' => 'Produits',
'icon' => 'clone',
'url' => ['/product/index'],
'visible' => $userManager->isCurrentProducer(),
'visible' => $userManager->isCurrentProducer(),
'active' => Yii::$app->controller->id == 'product',
'items' => [
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/product/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Catégories', 'icon' => 'book', 'url' => ['/product-category/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Import prix', 'icon' => 'upload', 'url' => ['/product/price-import'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/product/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Catégories', 'icon' => 'book', 'url' => ['/product-category/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Import prix', 'icon' => 'upload', 'url' => ['/product/price-import'], 'visible' => $userManager->isCurrentProducer()],
]
],
['label' => 'Points de vente', 'icon' => 'map-marker', 'url' => ['/point-sale/index'], 'visible' => $userManager->isCurrentProducer(), 'active' => Yii::$app->controller->id == 'point-sale'],
['label' => 'Points de vente', 'icon' => 'map-marker', 'url' => ['/point-sale/index'], 'visible' => $userManager->isCurrentProducer(), 'active' => Yii::$app->controller->id == 'point-sale'],
[
'label' => 'Utilisateurs',
'icon' => 'users',
'url' => ['/user/index'],
'items' => [
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/user/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Groupes', 'icon' => 'users', 'url' => ['/user-group/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/user/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Groupes', 'icon' => 'users', 'url' => ['/user-group/index'], 'visible' => $userManager->isCurrentProducer()],
],
],
['label' => 'Abonnements', 'icon' => 'repeat', 'url' => ['/subscription/index'], 'visible' => $userManager->isCurrentProducer(), 'active' => Yii::$app->controller->id == 'subscription'],
['label' => 'Communiquer', 'icon' => 'bullhorn', 'url' => ['/communicate/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Abonnements', 'icon' => 'repeat', 'url' => ['/subscription/index'], 'visible' => $userManager->isCurrentProducer(), 'active' => Yii::$app->controller->id == 'subscription'],
['label' => 'Communiquer', 'icon' => 'bullhorn', 'url' => ['/communicate/index'], 'visible' => $userManager->isCurrentProducer()],
[
'label' => 'Documents',
'icon' => 'clone',
'url' => ['/delivery-note/index'],
'items' => [
['label' => 'Bons de livraison', 'icon' => 'sticky-note-o', 'url' => ['/delivery-note/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Factures', 'icon' => 'sticky-note-o', 'url' => ['/invoice/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Devis', 'icon' => 'sticky-note-o', 'url' => ['/quotation/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Bons de livraison', 'icon' => 'sticky-note-o', 'url' => ['/delivery-note/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Factures', 'icon' => 'sticky-note-o', 'url' => ['/invoice/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Devis', 'icon' => 'sticky-note-o', 'url' => ['/quotation/index'], 'visible' => $userManager->isCurrentProducer()],
],
],
[
@@ -100,43 +104,44 @@ $userManager = $this->getUserManager();
'icon' => 'line-chart',
'url' => ['/stats/index'],
'items' => [
['label' => 'Chiffre d\'affaire', 'icon' => 'line-chart', 'url' => ['/stats/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Rapports', 'icon' => 'pencil-square-o', 'url' => ['/report/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Produits', 'icon' => 'table', 'url' => ['/stats/products'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Chiffre d\'affaire', 'icon' => 'line-chart', 'url' => ['/stats/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Rapports', 'icon' => 'pencil-square-o', 'url' => ['/report/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Produits', 'icon' => 'table', 'url' => ['/stats/products'], 'visible' => $userManager->isCurrentProducer()],
],
],
['label' => 'Paramètres', 'icon' => 'cog', 'url' => ['/producer/update'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Accès', 'icon' => 'lock', 'url' => ['/access/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Paramètres', 'icon' => 'cog', 'url' => ['/producer/update'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Accès', 'icon' => 'lock', 'url' => ['/access/index'], 'visible' => $userManager->isCurrentProducer()],
['label' => "Opendistrib", 'options' => ['class' => 'header'], 'visible' => $userManager->isCurrentProducer()],
[
'label' => 'Développement',
'icon' => 'code',
'url' => ['/development/index'],
'visible' => $userManager->isCurrentProducer(),
'active' => Yii::$app->controller->id == 'development',
'template'=>'<a href="{url}">{icon} {label}'.$newVersionOpendistribTemplate.'</a>'
'label' => 'Développement',
'icon' => 'code',
'url' => ['/development/index'],
'visible' => $userManager->isCurrentProducer(),
'active' => Yii::$app->controller->id == 'development',
'template' => '<a href="{url}">{icon} {label}' . $newVersionOpendistribTemplate . '</a>'
],
['label' => 'Tarifs', 'icon' => 'euro', 'url' => ['/producer/billing'], 'visible' => $userManager->isCurrentProducer()],
['label' => 'Tarifs', 'icon' => 'euro', 'url' => ['/producer/billing'], 'visible' => $userManager->isCurrentProducer()],

['label' => 'Administration', 'options' => ['class' => 'header'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Producteurs', 'icon' => 'th-list', 'url' => ['/producer-admin/index'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Administration', 'options' => ['class' => 'header'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Producteurs', 'icon' => 'th-list', 'url' => ['/producer-admin/index'], 'visible' => $userManager->isCurrentAdmin()],
[
'label' => 'Statistiques',
'icon' => 'line-chart',
'url' => ['/stats-admin/turnover'],
'items' => [
['label' => 'Chiffre d\'affaire', 'icon' => 'line-chart', 'url' => ['/stats-admin/turnover'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Commandes clients', 'icon' => 'calendar', 'url' => ['/stats-admin/customer-orders'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Chiffre d\'affaire', 'icon' => 'line-chart', 'url' => ['/stats-admin/turnover'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Commandes clients', 'icon' => 'calendar', 'url' => ['/stats-admin/customer-orders'], 'visible' => $userManager->isCurrentAdmin()],
],
],

['label' => 'Tranches de prix', 'icon' => 'eur', 'url' => ['/producer-price-range-admin/index'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Taxes', 'icon' => 'eur', 'url' => ['/tax-rate-admin/index'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Communiquer', 'icon' => 'bullhorn', 'url' => ['/communicate-admin/index'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Tranches de prix', 'icon' => 'eur', 'url' => ['/producer-price-range-admin/index'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Taxes', 'icon' => 'eur', 'url' => ['/tax-rate-admin/index'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Communiquer', 'icon' => 'bullhorn', 'url' => ['/communicate-admin/index'], 'visible' => $userManager->isCurrentAdmin()],

//['label' => 'Outils', 'options' => ['class' => 'header'], 'visible' => $userManager->isCurrentAdmin()],
//['label' => 'Gii', 'icon' => 'file-code-o', 'url' => ['/gii'], 'visible' => $userManager->isCurrentAdmin()],
//['label' => 'Debug', 'icon' => 'dashboard', 'url' => ['/debug'], 'visible' => $userManager->isCurrentAdmin()],
['label' => 'Login', 'url' => ['site/login'], 'visible' => ! $userManager->isCurrentConnected()],
['label' => 'Login', 'url' => ['site/login'], 'visible' => !$userManager->isCurrentConnected()],
],
]
) ?>

+ 56
- 0
backend/views/support/create.php Vedi File

@@ -0,0 +1,56 @@
<?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.
*/

use yii\helpers\Html;
use yii\widgets\ActiveForm;

$this->setTitle('Créer un ticket') ;
$this->addBreadcrumb(['label' => 'ticket', 'url' => ['index']]) ;
$this->addBreadcrumb('Créer') ;

?>

<div class="ticket-create">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($ticket, 'subject'); ?>
<?= $form->field($ticket, 'message')->textarea(['rows' => 6]); ?>
<div class="form-group">
<?= Html::submitButton('Créer', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>

+ 141
- 0
backend/views/support/index.php Vedi File

@@ -0,0 +1,141 @@
<?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.
*/

use common\logic\Ticket\Ticket\Model\Ticket;
use common\logic\Ticket\Ticket\Wrapper\TicketManager;
use yii\helpers\Html;
use yii\grid\GridView;
use common\logic\Subscription\Subscription\Model\Subscription;

$ticketManager = TicketManager::getInstance();
$this->setTitle('Support');
$this->addBreadcrumb($this->getTitle());
//$this->addButton(['label' => 'Créer un ticket <span class="glyphicon glyphicon-plus"></span>', 'url' => 'support/create', 'class' => 'btn btn-primary']) ;

?>
<div class="support-index">

<div>
<div class="col-md-4">
<div class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-phone"></i></span>
<div class="info-box-content">
<span class="info-box-text">Me contacter directement</span>
<span class="info-box-text">
<br/>
<strong><?= Yii::$app->params['phoneNumber'] ?></strong>
</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-calendar"></i></span>
<div class="info-box-content">
<span class="info-box-text"><br/>
<?= Html::a('Prendre rendez-vous', Yii::$app->params['appointmentUrl'], ['class' => 'btn btn-sm btn-default', 'target' => '_blank']); ?>
</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-comments"></i></span>
<div class="info-box-content">
<span class="info-box-text"><br/><?= Html::a('Ouvrir un ticket', ['support/create'], ['class' => 'btn btn-sm btn-default']); ?></span>
</div>
</div>
</div>
</div>

<div class="clr"></div>

<div class="box">
<div class="box-header with-border">
<h3 class="box-title">Tickets</h3>
</div>

<div class="box-body">
<?= GridView::widget([
'filterModel' => $searchTicket,
'dataProvider' => $dataProviderTicket,
'columns' => [
[
'attribute' => 'subject',
'format' => 'raw',
'value' => function($ticket) {
return Html::a($ticket->subject, ['support/view', 'id' => $ticket->id]);
}
],
[
'attribute' => 'status',
'filter' => [Ticket::STATUS_OPEN => 'Ouvert', Ticket::STATUS_CLOSED => 'Fermé'],
'value' => function($ticket) {
$label = $ticket->status == Ticket::STATUS_OPEN ? 'Ouvert' : 'Fermé';
return $label;
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{close-open}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'close-open' => function ($url, $ticket) use ($ticketManager) {
if($ticketManager->isTicketOpen($ticket)) {
$title = 'Fermer';
$url = ['support/close', 'id' => $ticket->id];
$glyphicon = 'glyphicon-folder-close';
}
else {
$title = 'Ré-ouvrir';
$url = ['support/open', 'id' => $ticket->id];
$glyphicon = 'glyphicon-folder-open';
}
return Html::a('<span class="glyphicon '.$glyphicon.'"></span>', $url, [
'title' => $title, 'class' => 'btn btn-default'
]);
}
],
],
],
]); ?>
</div>
</div>

</div>

+ 10
- 0
backend/views/support/view.php Vedi File

@@ -0,0 +1,10 @@
<?php

use common\logic\Ticket\Ticket\Wrapper\TicketManager;

$ticketManager = TicketManager::getInstance();
$this->setTitle('Support');
$this->addBreadcrumb($this->getTitle());
$this->addBreadcrumb('Voir un ticket');



+ 60
- 44
backend/web/css/screen.css Vedi File

@@ -1546,122 +1546,138 @@ body.skin-black .main-header .navbar {
body.skin-black .main-header .navbar .sidebar-toggle {
color: #333;
}
/* line 28, ../sass/_adminlte.scss */
/* line 27, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .link-support {
float: left;
padding: 15px 15px;
border-right: solid 1px #e0e0e0;
color: #333;
}
/* line 33, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .link-support:hover {
text-decoration: none;
color: #FF7F00;
}
/* line 39, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
body.skin-black .main-header .navbar .navbar-right > li > a {
border-left: solid 1px #e0e0e0;
color: #333;
}
/* line 34, ../sass/_adminlte.scss */
/* line 45, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav > li > a:hover, body.skin-black .main-header .navbar .nav > li > a:active, body.skin-black .main-header .navbar .nav > li > a:focus,
body.skin-black .main-header .navbar .nav .open > a, body.skin-black .main-header .navbar .nav .open > a:hover, body.skin-black .main-header .navbar .nav .open > a:focus,
body.skin-black .main-header .navbar .nav > .active > a {
color: #FF7F00;
}
/* line 40, ../sass/_adminlte.scss */
/* line 51, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .dropdown-menu {
-moz-box-shadow: 0px 0px 4px gray;
-webkit-box-shadow: 0px 0px 4px gray;
box-shadow: 0px 0px 4px gray;
}
/* line 45, ../sass/_adminlte.scss */
/* line 56, ../sass/_adminlte.scss */
body.skin-black .main-header .logo, body.skin-black .main-header .navbar .sidebar-toggle {
border-right: solid 1px #e0e0e0;
}
/* line 49, ../sass/_adminlte.scss */
/* line 60, ../sass/_adminlte.scss */
body.skin-black .main-header .link-control-sidebar {
display: none;
}
/* line 54, ../sass/_adminlte.scss */
/* line 65, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu {
max-height: 300px;
}
/* line 57, ../sass/_adminlte.scss */
/* line 68, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a {
padding-top: 4px;
padding-bottom: 4px;
}
/* line 61, ../sass/_adminlte.scss */
/* line 72, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a h5 {
margin-bottom: 2px;
}
/* line 64, ../sass/_adminlte.scss */
/* line 75, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a h5 small {
float: right;
}
/* line 69, ../sass/_adminlte.scss */
/* line 80, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a p {
margin-left: 10px;
}
/* line 79, ../sass/_adminlte.scss */
/* line 90, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .label {
position: relative;
top: -2px;
left: 0px;
}
/* line 85, ../sass/_adminlte.scss */
/* line 96, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu #link-display-producers-offline {
color: #FF7F00;
}
/* line 89, ../sass/_adminlte.scss */
/* line 100, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .offline {
display: none;
}
/* line 95, ../sass/_adminlte.scss */
/* line 107, ../sass/_adminlte.scss */
body.skin-black .sidebar .sidebar-menu > li.header {
color: #899397;
}
/* line 112, ../sass/_adminlte.scss */
body.skin-black .sidebar-menu > li.active > a {
border-color: #FF7F00;
}
/* line 99, ../sass/_adminlte.scss */
/* line 116, ../sass/_adminlte.scss */
body.skin-black .content-wrapper {
background-color: #f5f5f5;
}
/* line 102, ../sass/_adminlte.scss */
/* line 119, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header {
background-color: #F5F5F5;
padding-bottom: 15px;
border-bottom: solid 1px #e0e0e0;
border-top: solid 1px #e0e0e0;
}
/* line 108, ../sass/_adminlte.scss */
/* line 125, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header .btn {
padding: 3px 6px;
font-size: 10px;
font-family: Arial;
text-transform: uppercase;
}
/* line 115, ../sass/_adminlte.scss */
/* line 132, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header h1 {
font-family: "highvoltageregular";
}
/* line 122, ../sass/_adminlte.scss */
/* line 139, ../sass/_adminlte.scss */
body.skin-black .content-wrapper a {
color: #FF7F00;
}
/* line 126, ../sass/_adminlte.scss */
/* line 143, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn {
color: white;
}
/* line 130, ../sass/_adminlte.scss */
/* line 147, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn-default {
color: #333;
background-color: white;
}
/* line 135, ../sass/_adminlte.scss */
/* line 152, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn-primary {
background-color: #FF7F00;
color: white;
border-color: #FF7F00;
}
/* line 142, ../sass/_adminlte.scss */
/* line 159, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert a {
color: white;
}
/* line 145, ../sass/_adminlte.scss */
/* line 162, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert a.btn {
color: #333;
text-decoration: none;
}
/* line 150, ../sass/_adminlte.scss */
/* line 167, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert .close {
font-size: 30px;
position: relative;
@@ -1670,89 +1686,89 @@ body.skin-black .content-wrapper .alert .close {
color: white;
opacity: 0.6;
}
/* line 158, ../sass/_adminlte.scss */
/* line 175, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert .close:hover {
opacity: 1;
}
/* line 165, ../sass/_adminlte.scss */
/* line 182, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout h4 .fa {
margin-right: 7px;
}
/* line 168, ../sass/_adminlte.scss */
/* line 185, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout a {
color: white;
}
/* line 171, ../sass/_adminlte.scss */
/* line 188, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout .btn {
color: #333;
text-decoration: none;
}
/* line 178, ../sass/_adminlte.scss */
/* line 195, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table th {
font-size: 13px;
}
/* line 181, ../sass/_adminlte.scss */
/* line 198, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table th.column-actions, body.skin-black .content-wrapper .table td.column-actions {
width: 150px;
text-align: right;
}
/* line 185, ../sass/_adminlte.scss */
/* line 202, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table td.text-small, body.skin-black .content-wrapper .table th.text-small {
font-size: 12px;
}
/* line 190, ../sass/_adminlte.scss */
/* line 207, ../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 {
background-color: #FF7F00;
border: solid 1px #FF7F00;
color: white;
}
/* line 195, ../sass/_adminlte.scss */
/* line 212, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > li > a, body.skin-black .content-wrapper .pagination > li > span {
color: #FF7F00;
}
/* line 197, ../sass/_adminlte.scss */
/* line 214, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > li > a:hover, body.skin-black .content-wrapper .pagination > li > span:hover {
color: #cc6600;
}
/* line 202, ../sass/_adminlte.scss */
/* line 219, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .submenu {
margin-bottom: 25px;
}
/* line 208, ../sass/_adminlte.scss */
/* line 225, ../sass/_adminlte.scss */
body.skin-black .main-footer a {
color: #FF7F00;
}

/* line 214, ../sass/_adminlte.scss */
/* line 231, ../sass/_adminlte.scss */
body.login-page {
background: none;
background-color: white;
}
/* line 218, ../sass/_adminlte.scss */
/* line 235, ../sass/_adminlte.scss */
body.login-page .login-box .login-logo {
text-align: center;
font-family: "comfortaalight";
}
/* line 221, ../sass/_adminlte.scss */
/* line 238, ../sass/_adminlte.scss */
body.login-page .login-box .login-logo img {
width: 50px;
}
/* line 226, ../sass/_adminlte.scss */
/* line 243, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .btn-primary {
background-color: #FF7F00;
border-color: #FF7F00;
padding: 5px 10px;
}
/* line 231, ../sass/_adminlte.scss */
/* line 248, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .btn-primary:active {
background-color: #ff8c1a;
border-color: #FF7F00;
}
/* line 237, ../sass/_adminlte.scss */
/* line 254, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body a {
color: #FF7F00;
}
/* line 239, ../sass/_adminlte.scss */
/* line 256, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body a:hover {
color: #ff8c1a;
}

+ 17
- 0
backend/web/sass/_adminlte.scss Vedi File

@@ -24,6 +24,17 @@ body.skin-black {
.sidebar-toggle {
color: #333 ;
}
.link-support {
float: left;
padding: 15px 15px;
border-right: solid 1px #e0e0e0;
color: #333;

&:hover {
text-decoration: none;
color: $color1;
}
}
.navbar-custom-menu .navbar-nav > li > a,
.navbar-right > li > a {
@@ -92,6 +103,12 @@ body.skin-black {
}
}

.sidebar {
.sidebar-menu > li.header {
color: #899397;
}
}

.sidebar-menu > li.active > a {
border-color: $color1 ;
}

+ 3
- 0
common/components/BusinessLogic.php Vedi File

@@ -28,6 +28,9 @@ class BusinessLogic
$this->getProductOrderContainer(),
$this->getProductPriceContainer(),
$this->getProductSubscriptionContainer(),
$this->getTicketUserContainer(),
$this->getTicketMessageContainer(),
$this->getTicketContainer(),
$this->getQuotationContainer(),
$this->getInvoiceContainer(),
$this->getDeliveryNoteContainer(),

+ 36
- 0
common/components/BusinessLogicTrait.php Vedi File

@@ -44,6 +44,12 @@ use common\logic\Subscription\ProductSubscription\Wrapper\ProductSubscriptionCon
use common\logic\Subscription\ProductSubscription\Wrapper\ProductSubscriptionManager;
use common\logic\Subscription\Subscription\Wrapper\SubscriptionContainer;
use common\logic\Subscription\Subscription\Wrapper\SubscriptionManager;
use common\logic\Ticket\Ticket\Wrapper\TicketContainer;
use common\logic\Ticket\Ticket\Wrapper\TicketManager;
use common\logic\Ticket\TicketMessage\Wrapper\TicketMessageContainer;
use common\logic\Ticket\TicketMessage\Wrapper\TicketMessageManager;
use common\logic\Ticket\TicketUser\Wrapper\TicketUserContainer;
use common\logic\Ticket\TicketUser\Wrapper\TicketUserManager;
use common\logic\User\CreditHistory\Wrapper\CreditHistoryContainer;
use common\logic\User\CreditHistory\Wrapper\CreditHistoryManager;
use common\logic\User\User\Wrapper\UserContainer;
@@ -187,6 +193,21 @@ trait BusinessLogicTrait
return UserUserGroupManager::getInstance();
}

public function getTicketManager(): TicketManager
{
return TicketManager::getInstance();
}

public function getTicketMessageManager(): TicketMessageManager
{
return TicketMessageManager::getInstance();
}

public function getTicketUserManager(): TicketUserManager
{
return TicketUserManager::getInstance();
}

public function getUserContainer(): UserContainer
{
return UserContainer::getInstance();
@@ -316,4 +337,19 @@ trait BusinessLogicTrait
{
return ProductDistributionContainer::getInstance();
}

public function getTicketContainer(): TicketContainer
{
return TicketContainer::getInstance();
}

public function getTicketMessageContainer(): TicketMessageContainer
{
return TicketMessageContainer::getInstance();
}

public function getTicketUserContainer(): TicketUserContainer
{
return TicketUserContainer::getInstance();
}
}

+ 8
- 0
common/logic/AbstractSolver.php Vedi File

@@ -0,0 +1,8 @@
<?php

namespace common\logic;

abstract class AbstractSolver extends AbstractService implements SolverInterface
{

}

+ 0
- 1
common/logic/Subscription/ProductSubscription/Repository/ProductSubscriptionRepository.php Vedi File

@@ -3,7 +3,6 @@
namespace common\logic\Subscription\ProductSubscription\Repository;

use common\logic\AbstractRepository;
use common\logic\Subscription\ProductSubscription\Model\ProductSubscription;
use common\logic\Subscription\Subscription\Model\Subscription;

class ProductSubscriptionRepository extends AbstractRepository

+ 0
- 1
common/logic/Subscription/ProductSubscription/Repository/ProductSubscriptionRepositoryQuery.php Vedi File

@@ -3,7 +3,6 @@
namespace common\logic\Subscription\ProductSubscription\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Subscription\ProductSubscription\Model\ProductSubscription;
use common\logic\Subscription\ProductSubscription\Service\ProductSubscriptionDefinition;
use common\logic\Subscription\Subscription\Model\Subscription;
use yii\db\ActiveQuery;

+ 7
- 7
common/logic/Subscription/ProductSubscription/Wrapper/ProductSubscriptionManager.php Vedi File

@@ -3,19 +3,19 @@
namespace common\logic\Subscription\ProductSubscription\Wrapper;

use common\logic\AbstractManager;
use common\logic\Subscription\ProductSubscription\Repository\ProductSubscriptionRepository;
use common\logic\Subscription\ProductSubscription\Service\ProductSubscriptionBuilder;
use common\logic\Subscription\ProductSubscription\Service\ProductSubscriptionDefinition;
use common\logic\Subscription\ProductSubscription\Repository\TicketRepository;
use common\logic\Subscription\ProductSubscription\Service\TicketBuilder;
use common\logic\Subscription\ProductSubscription\Service\TicketDefinition;

/**
* @mixin ProductSubscriptionDefinition
* @mixin ProductSubscriptionRepository
* @mixin ProductSubscriptionBuilder
* @mixin TicketDefinition
* @mixin TicketRepository
* @mixin TicketBuilder
*/
class ProductSubscriptionManager extends AbstractManager
{
public function getContainerFqcn(): string
{
return ProductSubscriptionContainer::class;
return TicketContainer::class;
}
}

+ 117
- 0
common/logic/Ticket/Ticket/Model/Ticket.php Vedi File

@@ -0,0 +1,117 @@
<?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 common\logic\Ticket\Ticket\Model;

use common\components\ActiveRecordCommon;
use common\logic\Producer\Producer\Model\Producer;
use common\logic\Ticket\TicketMessage\Model\TicketMessage;
use common\logic\User\User\Model\User;

class Ticket extends ActiveRecordCommon
{
const STATUS_OPEN = 'open';
const STATUS_CLOSED = 'closed';

public $message;

/**
* @inheritdoc
*/
public static function tableName()
{
return 'ticket';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_producer', 'id_user', 'subject', 'status'], 'required'],
[['id_producer', 'id_user'], 'integer'],
[['subject', 'status'], 'string'],
[['created_at', 'message'], 'safe'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_producer' => 'Producteur',
'id_user' => 'Utilisateur',
'subject' => 'Sujet',
'status' => 'Statut',
'created_at' => 'Date de création',
];
}

/*
* Relations
*/

public function getProducer()
{
return $this->hasOne(Producer::class, ['id' => 'id_producer']);
}

public function getUser()
{
return $this->hasOne(User::class, ['id' => 'id_user']);
}

public function getTicketMessages()
{
return $this->hasMany(TicketMessage::class, ['id_ticket' => 'id']);
}

public function populateProducer(Producer $producer): void
{
$this->populateFieldObject('id_producer', 'producer', $producer);
}

public function populateUser(User $user): void
{
$this->populateFieldObject('id_user', 'user', $user);
}
}

+ 89
- 0
common/logic/Ticket/Ticket/Model/TicketSearch.php Vedi File

@@ -0,0 +1,89 @@
<?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 common\logic\Ticket\Ticket\Model;

use common\helpers\GlobalParam;
use common\logic\Ticket\Ticket\Repository\TicketRepository;
use yii\data\ActiveDataProvider;

class TicketSearch extends Ticket
{
public function rules()
{
return [
[['subject', 'status'], 'string'],
[['subject', 'status'], 'string', 'max' => 255],
[['id_producer', 'id_user'], 'integer'],
];
}

public function search($params)
{
$ticketRepository = TicketRepository::getInstance();
$optionsSearch = $ticketRepository->getDefaultOptionsSearch();

$query = Ticket::find()
->with($optionsSearch['with'])
->innerJoinWith($optionsSearch['join_with'], true)
->where(['ticket.id_producer' => GlobalParam::getCurrentProducerId()]);

$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => ['attributes' => ['updated_at']],
'pagination' => [
'pageSize' => 20,
],
]);

$this->load($params);

if(!$this->status) {
$this->status = Ticket::STATUS_OPEN;
}

if (!$this->validate()) {
return $dataProvider;
}

$query->andFilterWhere(['like', 'ticket.subject', $this->subject]);
$query->andFilterWhere(['like', 'ticket.status', $this->status]);

return $dataProvider;
}
}

+ 35
- 0
common/logic/Ticket/Ticket/Repository/TicketRepository.php Vedi File

@@ -0,0 +1,35 @@
<?php

namespace common\logic\Ticket\Ticket\Repository;

use common\logic\AbstractRepository;

class TicketRepository extends AbstractRepository
{
protected TicketRepositoryQuery $query;

public function loadDependencies(): void
{
$this->loadQuery(TicketRepositoryQuery::class);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*/
public function getDefaultOptionsSearch(): array
{
return [
self::WITH => ['user', 'producer', 'ticketMessages'],
self::JOIN_WITH => [],
self::ORDER_BY => '',
self::ATTRIBUTE_ID_PRODUCER => ''
];
}

public function findOneTicketById(int $id)
{
return $this->createQuery()
->filterById($id)
->findOne();
}
}

+ 16
- 0
common/logic/Ticket/Ticket/Repository/TicketRepositoryQuery.php Vedi File

@@ -0,0 +1,16 @@
<?php

namespace common\logic\Ticket\Ticket\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Ticket\Ticket\Service\TicketDefinition;

class TicketRepositoryQuery extends AbstractRepositoryQuery
{
protected TicketDefinition $definition;

public function loadDependencies(): void
{
$this->loadDefinition(TicketDefinition::class);
}
}

+ 46
- 0
common/logic/Ticket/Ticket/Service/TicketBuilder.php Vedi File

@@ -0,0 +1,46 @@
<?php

namespace common\logic\Ticket\Ticket\Service;

use common\logic\AbstractBuilder;
use common\logic\Producer\Producer\Model\Producer;
use common\logic\Ticket\Ticket\Model\Ticket;
use common\logic\User\User\Model\User;

class TicketBuilder extends AbstractBuilder
{
public function instanciateTicket(Producer $producer, User $user): Ticket
{
$ticket = new Ticket();

$ticket->status = Ticket::STATUS_OPEN;
$ticket->populateProducer($producer);
$ticket->populateUser($user);

return $ticket;
}

public function createTicket(Producer $producer, User $user): Ticket
{
$ticket = $this->instanciateTicket($producer, $user);
$this->saveCreate($ticket);

return $ticket;
}

public function updateTicketStatus(Ticket $ticket, string $status)
{
$ticket->status = $status;
$this->saveUpdate($ticket);
}

public function closeTicket(Ticket $ticket)
{
$this->updateTicketStatus($ticket, Ticket::STATUS_CLOSED);
}

public function openTicket(Ticket $ticket)
{
$this->updateTicketStatus($ticket, Ticket::STATUS_OPEN);
}
}

+ 14
- 0
common/logic/Ticket/Ticket/Service/TicketDefinition.php Vedi File

@@ -0,0 +1,14 @@
<?php

namespace common\logic\Ticket\Ticket\Service;

use common\logic\AbstractDefinition;
use common\logic\Ticket\Ticket\Model\Ticket;

class TicketDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return Ticket::class;
}
}

+ 34
- 0
common/logic/Ticket/Ticket/Service/TicketSolver.php Vedi File

@@ -0,0 +1,34 @@
<?php

namespace common\logic\Ticket\Ticket\Service;

use common\logic\AbstractSolver;
use common\logic\Ticket\Ticket\Model\Ticket;
use common\logic\User\User\Model\User;
use common\logic\User\User\Service\UserSolver;

class TicketSolver extends AbstractSolver
{
protected UserSolver $userSolver;

public function loadDependencies(): void
{
$this->userSolver = $this->loadService(UserSolver::class);
}

public function hasTicketAccess(Ticket $ticket, User $user): string
{
return $user->id_producer == $ticket->id_producer
|| $this->userSolver->isAdmin($user);
}

public function isTicketOpen(Ticket $ticket)
{
return $ticket->status == Ticket::STATUS_OPEN;
}

public function isTicketClosed(Ticket $ticket)
{
return $ticket->status == Ticket::STATUS_CLOSED;
}
}

+ 42
- 0
common/logic/Ticket/Ticket/Wrapper/TicketContainer.php Vedi File

@@ -0,0 +1,42 @@
<?php

namespace common\logic\Ticket\Ticket\Wrapper;

use common\logic\AbstractContainer;
use common\logic\Ticket\Ticket\Repository\TicketRepository;
use common\logic\Ticket\Ticket\Service\TicketBuilder;
use common\logic\Ticket\Ticket\Service\TicketDefinition;
use common\logic\Ticket\Ticket\Service\TicketSolver;

class TicketContainer extends AbstractContainer
{
public function getServices(): array
{
return [
TicketDefinition::class,
TicketRepository::class,
TicketBuilder::class,
TicketSolver::class,
];
}

public function getDefinition(): TicketDefinition
{
return TicketDefinition::getInstance();
}

public function getRepository(): TicketRepository
{
return TicketRepository::getInstance();
}

public function getBuilder(): TicketBuilder
{
return TicketBuilder::getInstance();
}

public function getSolver(): TicketSolver
{
return TicketSolver::getInstance();
}
}

+ 23
- 0
common/logic/Ticket/Ticket/Wrapper/TicketManager.php Vedi File

@@ -0,0 +1,23 @@
<?php

namespace common\logic\Ticket\Ticket\Wrapper;

use common\logic\AbstractManager;
use common\logic\Ticket\Ticket\Repository\TicketRepository;
use common\logic\Ticket\Ticket\Service\TicketBuilder;
use common\logic\Ticket\Ticket\Service\TicketDefinition;
use common\logic\Ticket\Ticket\Service\TicketSolver;

/**
* @mixin TicketDefinition
* @mixin TicketRepository
* @mixin TicketBuilder
* @mixin TicketSolver
*/
class TicketManager extends AbstractManager
{
public function getContainerFqcn(): string
{
return TicketContainer::class;
}
}

+ 105
- 0
common/logic/Ticket/TicketMessage/Model/TicketMessage.php Vedi File

@@ -0,0 +1,105 @@
<?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 common\logic\Ticket\TicketMessage\Model;

use common\components\ActiveRecordCommon;
use common\logic\Ticket\Ticket\Model\Ticket;
use common\logic\User\User\Model\User;

class TicketMessage extends ActiveRecordCommon
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'ticket_message';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_ticket', 'id_user', 'message'], 'required'],
[['id_ticket', 'id_user'], 'integer'],
[['message'], 'string'],
[['created_at'], 'safe'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_ticket' => 'Ticket',
'id_user' => 'Utilisateur',
'message' => 'Message',
'created_at' => 'Date de création',
];
}

/*
* Relations
*/

public function getUser()
{
return $this->hasOne(User::class, ['id' => 'id_user']);
}

public function getTicket()
{
return $this->hasOne(Ticket::class, ['id' => 'id_ticket']);
}

public function populateUser(User $user): void
{
$this->populateFieldObject('id_user', 'user', $user);
}

public function populateTicket(Ticket $ticket): void
{
$this->populateFieldObject('id_ticket', 'ticket', $ticket);
}
}

+ 28
- 0
common/logic/Ticket/TicketMessage/Repository/TicketMessageRepository.php Vedi File

@@ -0,0 +1,28 @@
<?php

namespace common\logic\Ticket\TicketMessage\Repository;

use common\logic\AbstractRepository;

class TicketMessageRepository extends AbstractRepository
{
protected TicketMessageRepositoryQuery $query;

public function loadDependencies(): void
{
$this->loadQuery(TicketMessageRepositoryQuery::class);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*/
public function getDefaultOptionsSearch(): array
{
return [
self::WITH => ['user', 'producer', 'ticketMessages'],
self::JOIN_WITH => [],
self::ORDER_BY => '',
self::ATTRIBUTE_ID_PRODUCER => ''
];
}
}

+ 16
- 0
common/logic/Ticket/TicketMessage/Repository/TicketMessageRepositoryQuery.php Vedi File

@@ -0,0 +1,16 @@
<?php

namespace common\logic\Ticket\TicketMessage\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Ticket\TicketMessage\Service\TicketMessageDefinition;

class TicketMessageRepositoryQuery extends AbstractRepositoryQuery
{
protected TicketMessageDefinition $definition;

public function loadDependencies(): void
{
$this->loadDefinition(TicketMessageDefinition::class);
}
}

+ 24
- 0
common/logic/Ticket/TicketMessage/Service/TicketMessageBuilder.php Vedi File

@@ -0,0 +1,24 @@
<?php

namespace common\logic\Ticket\TicketMessage\Service;

use common\logic\AbstractBuilder;
use common\logic\Ticket\TicketMessage\Model\TicketMessage;

class TicketMessageBuilder extends AbstractBuilder
{
public function instanciateTicketMessage(): TicketMessage
{
$ticket = new TicketMessage();

return $ticket;
}

public function createTicketMessage(): TicketMessage
{
$ticketMessage = $this->instanciateTicketMessage();
$this->saveCreate($ticketMessage);

return $ticketMessage;
}
}

+ 14
- 0
common/logic/Ticket/TicketMessage/Service/TicketMessageDefinition.php Vedi File

@@ -0,0 +1,14 @@
<?php

namespace common\logic\Ticket\TicketMessage\Service;

use common\logic\AbstractDefinition;
use common\logic\Ticket\TicketMessage\Model\TicketMessage;

class TicketMessageDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return TicketMessage::class;
}
}

+ 35
- 0
common/logic/Ticket/TicketMessage/Wrapper/TicketMessageContainer.php Vedi File

@@ -0,0 +1,35 @@
<?php

namespace common\logic\Ticket\TicketMessage\Wrapper;

use common\logic\AbstractContainer;
use common\logic\Ticket\TicketMessage\Repository\TicketMessageRepository;
use common\logic\Ticket\TicketMessage\Service\TicketMessageBuilder;
use common\logic\Ticket\TicketMessage\Service\TicketMessageDefinition;

class TicketMessageContainer extends AbstractContainer
{
public function getServices(): array
{
return [
TicketMessageDefinition::class,
TicketMessageRepository::class,
TicketMessageBuilder::class
];
}

public function getDefinition(): TicketMessageDefinition
{
return TicketMessageDefinition::getInstance();
}

public function getRepository(): TicketMessageRepository
{
return TicketMessageRepository::getInstance();
}

public function getFactory(): TicketMessageBuilder
{
return TicketMessageBuilder::getInstance();
}
}

+ 21
- 0
common/logic/Ticket/TicketMessage/Wrapper/TicketMessageManager.php Vedi File

@@ -0,0 +1,21 @@
<?php

namespace common\logic\Ticket\TicketMessage\Wrapper;

use common\logic\AbstractManager;
use common\logic\Ticket\TicketMessage\Repository\TicketMessageRepository;
use common\logic\Ticket\TicketMessage\Service\TicketMessageBuilder;
use common\logic\Ticket\TicketMessage\Service\TicketMessageDefinition;

/**
* @mixin TicketMessageDefinition
* @mixin TicketMessageRepository
* @mixin TicketMessageBuilder
*/
class TicketMessageManager extends AbstractManager
{
public function getContainerFqcn(): string
{
return TicketMessageContainer::class;
}
}

+ 103
- 0
common/logic/Ticket/TicketUser/Model/TicketUser.php Vedi File

@@ -0,0 +1,103 @@
<?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 common\logic\Ticket\TicketUser\Model;

use common\components\ActiveRecordCommon;
use common\logic\Ticket\Ticket\Model\Ticket;
use common\logic\User\User\Model\User;

class TicketUser extends ActiveRecordCommon
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'ticket_user';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_ticket', 'id_user'], 'required'],
[['id_ticket', 'id_user'], 'integer'],
[['read_at'], 'safe'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_ticket' => 'Ticket',
'id_user' => 'Utilisateur',
'read_at' => 'Date de lecture',
];
}

/*
* Relations
*/

public function getUser()
{
return $this->hasOne(User::class, ['id' => 'id_user']);
}

public function getTicket()
{
return $this->hasOne(Ticket::class, ['id' => 'id_ticket']);
}

public function populateUser(User $user): void
{
$this->populateFieldObject('id_user', 'user', $user);
}

public function populateTicket(Ticket $ticket): void
{
$this->populateFieldObject('id_ticket', 'ticket', $ticket);
}
}

+ 28
- 0
common/logic/Ticket/TicketUser/Repository/TicketUserRepository.php Vedi File

@@ -0,0 +1,28 @@
<?php

namespace common\logic\Ticket\TicketUser\Repository;

use common\logic\AbstractRepository;

class TicketUserRepository extends AbstractRepository
{
protected TicketUserRepositoryQuery $query;

public function loadDependencies(): void
{
$this->loadQuery(TicketUserRepositoryQuery::class);
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*/
public function getDefaultOptionsSearch(): array
{
return [
self::WITH => ['user', 'producer', 'ticketMessages'],
self::JOIN_WITH => [],
self::ORDER_BY => '',
self::ATTRIBUTE_ID_PRODUCER => ''
];
}
}

+ 16
- 0
common/logic/Ticket/TicketUser/Repository/TicketUserRepositoryQuery.php Vedi File

@@ -0,0 +1,16 @@
<?php

namespace common\logic\Ticket\TicketUser\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Ticket\TicketUser\Service\TicketUserDefinition;

class TicketUserRepositoryQuery extends AbstractRepositoryQuery
{
protected TicketUserDefinition $definition;

public function loadDependencies(): void
{
$this->loadDefinition(TicketUserDefinition::class);
}
}

+ 25
- 0
common/logic/Ticket/TicketUser/Service/TicketUserBuilder.php Vedi File

@@ -0,0 +1,25 @@
<?php

namespace common\logic\Ticket\TicketUser\Service;

use common\logic\AbstractBuilder;
use common\logic\Ticket\Ticket\Model\Ticket;
use common\logic\Ticket\TicketUser\Model\TicketUser;

class TicketUserBuilder extends AbstractBuilder
{
public function instanciateTicketUser(): TicketUser
{
$ticketUser = new TicketUser();

return $ticketUser;
}

public function createTicketUser(): Ticket
{
$ticketUser = $this->instanciateTicketUser();
$this->saveCreate($ticketUser);

return $ticketUser;
}
}

+ 14
- 0
common/logic/Ticket/TicketUser/Service/TicketUserDefinition.php Vedi File

@@ -0,0 +1,14 @@
<?php

namespace common\logic\Ticket\TicketUser\Service;

use common\logic\AbstractDefinition;
use common\logic\Ticket\TicketUser\Model\TicketUser;

class TicketUserDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return TicketUser::class;
}
}

+ 35
- 0
common/logic/Ticket/TicketUser/Wrapper/TicketUserContainer.php Vedi File

@@ -0,0 +1,35 @@
<?php

namespace common\logic\Ticket\TicketUser\Wrapper;

use common\logic\AbstractContainer;
use common\logic\Ticket\TicketUser\Repository\TicketUserRepository;
use common\logic\Ticket\TicketUser\Service\TicketUserBuilder;
use common\logic\Ticket\TicketUser\Service\TicketUserDefinition;

class TicketUserContainer extends AbstractContainer
{
public function getServices(): array
{
return [
TicketUserDefinition::class,
TicketUserRepository::class,
TicketUserBuilder::class
];
}

public function getDefinition(): TicketUserDefinition
{
return TicketUserDefinition::getInstance();
}

public function getRepository(): TicketUserRepository
{
return TicketUserRepository::getInstance();
}

public function getBuilder(): TicketUserBuilder
{
return TicketUserBuilder::getInstance();
}
}

+ 21
- 0
common/logic/Ticket/TicketUser/Wrapper/TicketUserManager.php Vedi File

@@ -0,0 +1,21 @@
<?php

namespace common\logic\Ticket\TicketUser\Wrapper;

use common\logic\AbstractManager;
use common\logic\Ticket\TicketMessage\Repository\TicketMessageRepository;
use common\logic\Ticket\TicketMessage\Service\TicketMessageBuilder;
use common\logic\Ticket\TicketMessage\Service\TicketMessageDefinition;

/**
* @mixin TicketMessageDefinition
* @mixin TicketMessageRepository
* @mixin TicketMessageBuilder
*/
class TicketUserManager extends AbstractManager
{
public function getContainerFqcn(): string
{
return TicketUserContainer::class;
}
}

+ 52
- 0
console/migrations/m230717_120138_module_ticket.php Vedi File

@@ -0,0 +1,52 @@
<?php

use yii\db\Migration;
use yii\db\Schema;

/**
* Class m230717_120138_module_ticket
*/
class m230717_120138_module_ticket extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->createTable('ticket', [
'id' => 'pk',
'id_producer' => Schema::TYPE_INTEGER.' NOT NULL',
'id_user' => Schema::TYPE_INTEGER.' NOT NULL',
'subject' => Schema::TYPE_STRING.' NOT NULL',
'status' => Schema::TYPE_STRING.' NOT NULL',
'created_at' => Schema::TYPE_DATETIME.' NOT NULL DEFAULT CURRENT_TIMESTAMP',
'updated_at' => Schema::TYPE_DATETIME.' NOT NULL DEFAULT CURRENT_TIMESTAMP'
]);

$this->createTable('ticket_message', [
'id' => 'pk',
'id_ticket' => Schema::TYPE_INTEGER.' NOT NULL',
'id_user' => Schema::TYPE_INTEGER.' NOT NULL',
'message' => Schema::TYPE_TEXT.' NOT NULL',
'created_at' => Schema::TYPE_DATETIME.' NOT NULL DEFAULT CURRENT_TIMESTAMP',
'updated_at' => Schema::TYPE_DATETIME.' NOT NULL DEFAULT CURRENT_TIMESTAMP',
]);

$this->createTable('ticket_user', [
'id' => 'pk',
'id_user' => Schema::TYPE_INTEGER.' NOT NULL',
'id_ticket' => Schema::TYPE_INTEGER.' NOT NULL',
'read_at' => Schema::TYPE_DATETIME.' NOT NULL DEFAULT CURRENT_TIMESTAMP',
]);
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropTable('ticket');
$this->dropTable('ticket_message');
$this->dropTable('ticket_user');
}
}

Loading…
Annulla
Salva