Ver código fonte

[Administration] Utilisateurs : page crédit #1152

feature/souke
Guillaume Bourgeois 1 ano atrás
pai
commit
efc49ed87a
21 arquivos alterados com 412 adições e 26 exclusões
  1. +90
    -0
      backend/controllers/CreditController.php
  2. +7
    -5
      backend/controllers/UserController.php
  3. +87
    -0
      backend/views/credit/index.php
  4. +1
    -1
      backend/views/distribution/index.php
  5. +2
    -5
      backend/views/layouts/header.php
  6. +11
    -0
      backend/views/layouts/left.php
  7. +7
    -0
      common/helpers/CSV.php
  8. +8
    -0
      common/logic/AbstractGenerator.php
  9. +1
    -0
      common/logic/AbstractService.php
  10. +8
    -0
      common/logic/GeneratorInterface.php
  11. +26
    -2
      common/logic/User/User/Repository/UserRepository.php
  12. +27
    -8
      common/logic/User/User/Service/UserSolver.php
  13. +50
    -0
      common/logic/User/User/Service/UsersCreditCsvGenerator.php
  14. +4
    -0
      common/logic/User/User/Wrapper/UserContainer.php
  15. +2
    -0
      common/logic/User/User/Wrapper/UserManager.php
  16. +19
    -0
      common/logic/User/UserProducer/Repository/UserProducerRepository.php
  17. +7
    -0
      common/logic/User/UserProducer/Repository/UserProducerRepositoryQuery.php
  18. +12
    -5
      common/logic/User/UserProducer/Service/UserProducerBuilder.php
  19. +14
    -0
      common/logic/User/UserProducer/Service/UserProducerSolver.php
  20. +2
    -0
      common/logic/User/UserProducer/Wrapper/UserProducerContainer.php
  21. +27
    -0
      console/migrations/m230825_090016_active_user_producer_with_credit_positive_or_negative.php

+ 90
- 0
backend/controllers/CreditController.php Ver arquivo

@@ -0,0 +1,90 @@
<?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\CSV;
use common\helpers\Price;
use http\Exception\InvalidArgumentException;
use yii\data\ActiveDataProvider;
use yii\filters\AccessControl;

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

public function actionIndex()
{
$userManager = $this->getUserManager();
$userProducerManager = $this->getUserProducerManager();

$dataProviderUsersWithNegativeCredit = new ActiveDataProvider([
'query' => $userManager->queryUsersWithNegativeCredit(),
'sort' => false,
'pagination' => [
'pageSize' => 30,
],
]);

return $this->render('index', [
'sumUserProducerCredits' => $userProducerManager->sumUserProducerCredits(),
'dataProviderUsersWithNegativeCredit' => $dataProviderUsersWithNegativeCredit
]);
}

public function actionExportUsers(string $type)
{
$this->getUserManager()->exportUsersCreditAsCsv($type);
}
}

+ 7
- 5
backend/controllers/UserController.php Ver arquivo

@@ -367,11 +367,13 @@ class UserController extends BackendController
$userProducer = $userProducerManager->findOneUserProducer($user);

if ($userProducer) {
$userProducer->active = 0;
$userProducer->bookmark = 0;
$userProducer->save();

$this->setFlash('success', 'L\'utilisateur a bien été supprimé de votre établissement.');
if($userProducerManager->hasOutstandingCredit($userProducer)) {
$this->setFlash('error', "Vous ne pouvez pas supprimer cet utilisateur car il a toujours du crédit en cours.");
}
else {
$userProducerManager->unlinkUserProducer($userProducer);
$this->setFlash('success', 'L\'utilisateur a bien été supprimé de votre établissement.');
}
} else {
throw new \yii\web\NotFoundHttpException('L\'enregistrement UserProducer est introuvable', 404);
}

+ 87
- 0
backend/views/credit/index.php Ver arquivo

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

use common\helpers\Price;
use yii\grid\GridView;

$userManager = $this->getUserManager();

$this->setTitle('Somme en crédit');

?>

<div class="row">
<div class="col-md-6">

</div>
<div class="col-md-6">

</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="info-box">
<span class="info-box-icon <?= $sumUserProducerCredits >= 0 ? 'bg-green' : 'bg-red' ?>"><i
class="fa fa-euro"></i></span>
<div class="info-box-content">
<span class="info-box-text">Total</span>
<span class="info-box-number"><?= Price::format($sumUserProducerCredits); ?></span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="info-box">
<span class="info-box-icon bg-orange"><i class="fa fa-download"></i></span>
<div class="info-box-content">
<span class="info-box-text">Exports<br />
<a class="btn btn-default btn-sm" href="<?= Yii::$app->urlManager->createUrl(['credit/export-users', 'type' => 'negative']); ?>">Clients au crédit négatif (CSV)</a>
<a class="btn btn-default btn-sm" href="<?= Yii::$app->urlManager->createUrl(['credit/export-users', 'type' => 'positive']); ?>">Clients au crédit positif (CSV)</a>
</span>
</div>
</div>
</div>
</div>

<h3>Clients avec un crédit négatif</h3>

<?=

GridView::widget([
'dataProvider' => $dataProviderUsersWithNegativeCredit,
'summary' => '',
'columns' => [
[
'label' => 'Client',
'value' => function ($user) use ($userManager) {
return $userManager->getUsernameFromArray($user, true);
}
],
[
'label' => 'Email',
'format' => 'raw',
'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-hide-on-mobile'],
'value' => function ($user) {
return $user['email'];
}
],
[
'label' => 'Téléphone',
'format' => 'raw',
'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-hide-on-mobile'],
'value' => function ($user) {
return $user['phone'];
}
],
[
'label' => 'Crédit',
'format' => 'raw',
'value' => function ($user) {
return Price::format($user['credit']);
}
]
]
]);
?>

+ 1
- 1
backend/views/distribution/index.php Ver arquivo

@@ -613,7 +613,7 @@ $this->setPageTitle('Distributions') ;
<option value="0">--</option>
<option v-for="user in users" :value="user.id_user">
<template v-if="user.name_legal_person && user.name_legal_person.length">
Personne morale / {{ user.name_legal_person }}
{{ user.name_legal_person }} (personne morale)
</template>
<template v-else>
{{ user.lastname +' '+ user.name }}

+ 2
- 5
backend/views/layouts/header.php Ver arquivo

@@ -224,10 +224,7 @@ $producer = GlobalParam::getCurrentProducer();

<?php

$usersNegativeCreditArray = $userManager->queryUsersBy(['id_producer' => GlobalParam::getCurrentProducerId()])
->andWhere('user_producer.credit < 0')
->orderBy('lastname, name ASC')
->all();
$usersNegativeCreditArray = $userManager->findUsersWithNegativeCredit();

?>

@@ -241,7 +238,7 @@ $producer = GlobalParam::getCurrentProducer();

<ul class="dropdown-menu">
<?php if (count($usersNegativeCreditArray)): ?>
<li class="header">Utilisateurs au crédit négatif</li>
<li class="header"><a href="<?= Yii::$app->urlManager->createUrl(['credit/index']); ?>">Utilisateurs au crédit négatif</a></li>
<li>
<ul class="menu">
<?php foreach ($usersNegativeCreditArray as $user): ?>

+ 11
- 0
backend/views/layouts/left.php Ver arquivo

@@ -43,6 +43,7 @@ use common\logic\Ticket\Ticket\Wrapper\TicketManager;

$producerManager = $this->getProducerManager();
$userManager = $this->getUserManager();
$userProducerManager = $this->getUserProducerManager();
$ticketManager = $this->getTicketManager();
$producer = GlobalParam::getCurrentProducer();

@@ -70,6 +71,9 @@ $producer = GlobalParam::getCurrentProducer();
$countTicketsAdminUnreadLabel = '<span class="pull-right-container"><small class="label pull-right bg-green">'.$countTicketsAdminUnread.'</small></span>';
}

$sumUserProducerCredits = $userProducerManager->sumUserProducerCredits();
$sumUserProducerCreditsLabel = '<span class="pull-right-container"><small class="label pull-right '.($sumUserProducerCredits >= 0 ? 'bg-green' : 'bg-red') .'">'.number_format($sumUserProducerCredits, 2).' €</small></span>';

?>

<?= dmstr\widgets\Menu::widget(
@@ -106,6 +110,13 @@ $producer = GlobalParam::getCurrentProducer();
'url' => ['/user/index'],
'items' => [
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/user/index'], 'visible' => $userManager->isCurrentProducer()],
[
'label' => 'Crédit',
'icon' => 'euro',
'url' => ['/credit/index'],
'template' => '<a href="{url}">{icon} {label}' . $sumUserProducerCreditsLabel . '</a>',
'visible' => $userManager->isCurrentProducer() && $producerManager->getConfig('credit')
],
['label' => 'Groupes', 'icon' => 'users', 'url' => ['/user-group/index'], 'visible' => $userManager->isCurrentProducer()],
],
],

+ 7
- 0
common/helpers/CSV.php Ver arquivo

@@ -42,6 +42,13 @@ use common\logic\Producer\Producer\Wrapper\ProducerManager;

class CSV
{
public static function send(string $filename, array $data)
{
CSV::downloadSendHeaders($filename);
echo CSV::array2csv($data);
die();
}

public static function array2csv(array &$array)
{
$producerManager = ProducerManager::getInstance();

+ 8
- 0
common/logic/AbstractGenerator.php Ver arquivo

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

namespace common\logic;

abstract class AbstractGenerator extends AbstractService implements GeneratorInterface
{

}

+ 1
- 0
common/logic/AbstractService.php Ver arquivo

@@ -17,6 +17,7 @@ abstract class AbstractService extends AbstractSingleton implements ServiceInter
RepositoryInterface::class,
BuilderInterface::class,
ResolverInterface::class,
GeneratorInterface::class,
UtilsInterface::class,
];
}

+ 8
- 0
common/logic/GeneratorInterface.php Ver arquivo

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

namespace common\logic;

interface GeneratorInterface
{

}

+ 26
- 2
common/logic/User/User/Repository/UserRepository.php Ver arquivo

@@ -83,11 +83,11 @@ class UserRepository extends AbstractRepository
public function queryUsersBy(array $params = [])
{
if (!isset($params['id_producer'])) {
$params['id_producer'] = GlobalParam::getCurrentProducerId();
$params['id_producer'] = $this->getProducerContextId();
}

$query = (new Query())
->select(['user.id AS user_id', 'user.name', 'user.lastname', 'user.phone', 'user.email', 'user.created_at', 'user.date_last_connection', 'user_producer.*', 'user.address', 'user.name_legal_person'])
->select(['user.id AS user_id', 'user.type', 'user.name', 'user.lastname', 'user.phone', 'user.email', 'user.created_at', 'user.date_last_connection', 'user_producer.*', 'user.address', 'user.name_legal_person'])
->from('user');

$active = (isset($params['inactive']) && $params['inactive']) ? 0 : 1;
@@ -159,6 +159,30 @@ class UserRepository extends AbstractRepository
return $query;
}

public function queryUsersWithNegativeCredit()
{
return $this->queryUsersBy()
->andWhere('user_producer.credit < 0')
->orderBy('credit ASC');
}

public function findUsersWithNegativeCredit()
{
return $this->queryUsersWithNegativeCredit()->all();
}

public function queryUsersWithPositiveCredit()
{
return $this->queryUsersBy()
->andWhere('user_producer.credit > 0')
->orderBy('lastname, name ASC');
}

public function findUsersWithPositiveCredit()
{
return $this->queryUsersWithPositiveCredit()->all();
}

/**
* Finds user by password reset token
*/

+ 27
- 8
common/logic/User/User/Service/UserSolver.php Ver arquivo

@@ -24,30 +24,49 @@ class UserSolver extends AbstractService implements SolverInterface
$username = '';
if (isset($modelArray['name_legal_person']) && strlen($modelArray['name_legal_person'])) {
$username = $modelArray['name_legal_person'];

if ($withType) {
$username = 'Personne morale / ' . $username;
}
} else {
$username = $modelArray['lastname'] . ' ' . $modelArray['name'];
}

if ($withType && $modelArray['type'] == User::TYPE_LEGAL_PERSON) {
$username = $username . ' (personne morale)';
}

return $username;
}

public function getContactSummaryFromArrayAsHtml(array $user): string
{
$html = '';

if (strlen($user['phone'])) {
$html .= $user['phone'];
}

if (strlen($user['phone']) && strlen($user['email'])) {
$html .= '<br />';
}

if (strlen($user['email'])) {
$html .= $user['email'];
}

return $html;
}

public function getUsername(User $user, $withType = false): string
{
$username = '';
if (isset($user->name_legal_person) && strlen($user->name_legal_person)) {
$username = $user->name_legal_person;

if ($withType) {
$username = 'Personne morale / ' . $username;
}
} else {
$username = $user->lastname . ' ' . $user->name;
}

if ($withType) {
$username = $username . ' (personne morale)';
}

return $username;
}


+ 50
- 0
common/logic/User/User/Service/UsersCreditCsvGenerator.php Ver arquivo

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

namespace common\logic\User\User\Service;

use common\helpers\CSV;
use common\helpers\Price;
use common\logic\User\User\Repository\UserRepository;
use common\logic\AbstractGenerator;
use yii\base\ErrorException;

class UsersCreditCsvGenerator extends AbstractGenerator
{
protected UserSolver $userSolver;
protected UserRepository $userRepository;

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

public function exportUsersCreditAsCsv(string $type)
{
if($type == 'negative') {
$filename = 'Utilisateurs_credit_negatif.csv';
$usersArray = $this->userRepository->findUsersWithNegativeCredit();
}
elseif($type == 'positive') {
$filename = 'Utilisateurs_credit_positif.csv';
$usersArray = $this->userRepository->findUsersWithPositiveCredit();
}
else {
throw new ErrorException('Le paramètre $type est invalide.');
}

$data = [
['Client', 'Email', 'Téléphone', 'Crédit']
];
foreach($usersArray as $user) {
$data[] = [
$this->userSolver->getUsernameFromArray($user, true),
$user['email'],
$user['phone'],
Price::format($user['credit']),
];
}

CSV::send($filename, $data);
}
}

+ 4
- 0
common/logic/User/User/Wrapper/UserContainer.php Ver arquivo

@@ -4,8 +4,10 @@ namespace common\logic\User\User\Wrapper;

use common\logic\AbstractContainer;
use common\logic\User\User\Repository\UserRepository;
use common\logic\User\User\Repository\UserRepositoryQuery;
use common\logic\User\User\Service\UserBuilder;
use common\logic\User\User\Service\UserDefinition;
use common\logic\User\User\Service\UsersCreditCsvGenerator;
use common\logic\User\User\Service\UserSolver;
use common\logic\User\User\Service\UserUtils;

@@ -16,8 +18,10 @@ class UserContainer extends AbstractContainer
return [
UserDefinition::class,
UserSolver::class,
UserRepositoryQuery::class,
UserRepository::class,
UserBuilder::class,
UsersCreditCsvGenerator::class,
UserUtils::class,
];
}

+ 2
- 0
common/logic/User/User/Wrapper/UserManager.php Ver arquivo

@@ -6,6 +6,7 @@ use common\logic\AbstractManager;
use common\logic\User\User\Repository\UserRepository;
use common\logic\User\User\Service\UserBuilder;
use common\logic\User\User\Service\UserDefinition;
use common\logic\User\User\Service\UsersCreditCsvGenerator;
use common\logic\User\User\Service\UserSolver;
use common\logic\User\User\Service\UserUtils;

@@ -15,6 +16,7 @@ use common\logic\User\User\Service\UserUtils;
* @mixin UserRepository
* @mixin UserBuilder
* @mixin UserUtils
* @mixin UsersCreditCsvGenerator
*/
class UserManager extends AbstractManager
{

+ 19
- 0
common/logic/User/UserProducer/Repository/UserProducerRepository.php Ver arquivo

@@ -47,4 +47,23 @@ class UserProducerRepository extends AbstractRepository
$userProducer = $this->findOneUserProducer($user);
return $userProducer ? $userProducer->bookmark : false;
}

public function findUserProducersWithNegativeOrPositiveCredit()
{
return $this->createDefaultQuery()
->filterHasNegativeOrPositiveCredit()
->find();
}

public function sumUserProducerCredits()
{
$sumUserProducersCredits = 0;
$userProducersWithNegativeOrPositiveCreditArray = $this->findUserProducersWithNegativeOrPositiveCredit();

foreach ($userProducersWithNegativeOrPositiveCreditArray as $userProducerWithNegativeOrPositiveCredit) {
$sumUserProducersCredits += $userProducerWithNegativeOrPositiveCredit->credit;
}

return $sumUserProducersCredits;
}
}

+ 7
- 0
common/logic/User/UserProducer/Repository/UserProducerRepositoryQuery.php Ver arquivo

@@ -34,4 +34,11 @@ class UserProducerRepositoryQuery extends AbstractRepositoryQuery
$this->andWhere(['bookmark' => $bookmark]);
return $this;
}

public function filterHasNegativeOrPositiveCredit(): self
{
$this->andWhere('user_producer.credit IS NOT NULL AND user_producer.credit != 0');

return $this;
}
}

+ 12
- 5
common/logic/User/UserProducer/Service/UserProducerBuilder.php Ver arquivo

@@ -48,7 +48,7 @@ class UserProducerBuilder extends AbstractBuilder
public function createUserProducer(User $user, Producer $producer, int $bookmark = 1): UserProducer
{
$userProducer = $this->instanciateUserProducer($user, $producer, $bookmark);
$this->saveCreate($userProducer);
$this->create($userProducer);
return $userProducer;
}

@@ -79,7 +79,7 @@ class UserProducerBuilder extends AbstractBuilder
$userProducer->setCredit($userProducer->getCredit() - $creditHistory->getAmount());
}

$this->saveUpdate($userProducer);
$this->update($userProducer);
}

public function initMeanPaymentOrder($creditHistory)
@@ -94,7 +94,7 @@ class UserProducerBuilder extends AbstractBuilder

$order->mean_payment = MeanPayment::CREDIT;

$this->saveUpdate($order);
$this->update($order);
}
}
}
@@ -149,13 +149,13 @@ class UserProducerBuilder extends AbstractBuilder

$userProducer->active = $active;

return $this->saveUpdate($userProducer);
return $this->update($userProducer);
}

public function updateBookmark(UserProducer $userProducer, bool $bookmark)
{
$userProducer->bookmark = $bookmark;
return $this->saveUpdate($userProducer);
return $this->update($userProducer);
}

public function addProducerBookmark(User $user)
@@ -169,4 +169,11 @@ class UserProducerBuilder extends AbstractBuilder
$userProducer = $this->createUserProducerIfNotExist($user, $this->getProducerContext());
return $this->updateBookmark($userProducer, false);
}

public function unlinkUserProducer(UserProducer $userProducer)
{
$userProducer->active = 0;
$userProducer->bookmark = 0;
return $this->update($userProducer);
}
}

+ 14
- 0
common/logic/User/UserProducer/Service/UserProducerSolver.php Ver arquivo

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

namespace common\logic\User\UserProducer\Service;

use common\logic\AbstractSolver;
use common\logic\User\UserProducer\Model\UserProducer;

class UserProducerSolver extends AbstractSolver
{
public function hasOutstandingCredit(UserProducer $userProducer): bool
{
return $userProducer->credit < 0 || $userProducer->credit > 0;
}
}

+ 2
- 0
common/logic/User/UserProducer/Wrapper/UserProducerContainer.php Ver arquivo

@@ -6,6 +6,7 @@ use common\logic\AbstractContainer;
use common\logic\User\UserProducer\Repository\UserProducerRepository;
use common\logic\User\UserProducer\Service\UserProducerBuilder;
use common\logic\User\UserProducer\Service\UserProducerDefinition;
use common\logic\User\UserProducer\Service\UserProducerSolver;

class UserProducerContainer extends AbstractContainer
{
@@ -13,6 +14,7 @@ class UserProducerContainer extends AbstractContainer
{
return [
UserProducerDefinition::class,
UserProducerSolver::class,
UserProducerRepository::class,
UserProducerBuilder::class,
];

+ 27
- 0
console/migrations/m230825_090016_active_user_producer_with_credit_positive_or_negative.php Ver arquivo

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

use yii\db\Migration;

/**
* Class m230825_090016_active_user_producer_with_credit_positive_or_negative
*/
class m230825_090016_active_user_producer_with_credit_positive_or_negative extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->execute('UPDATE user_producer SET active = 1 WHERE credit IS NOT NULL AND (credit < 0 OR credit > 0);');
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
echo "m230825_090016_active_user_producer_with_credit_positive_or_negative cannot be reverted.\n";

return false;
}
}

Carregando…
Cancelar
Salvar