public function actionCredit(int $id) | public function actionCredit(int $id) | ||||
{ | { | ||||
$userManager = $this->getUserManager(); | $userManager = $this->getUserManager(); | ||||
$user = $userManager->findOneUserById($id); | |||||
$userProducer = UserProducer::findOne(['id_user' => $id, 'id_producer' => $this->getProducerCurrent()->id]); | |||||
$paymentContainer = $this->getPaymentContainer(); | |||||
$userProducerContainer = $this->getUserProducerContainer(); | |||||
if (($userProducer) || $this->isUserCurrentAdmin()) { | |||||
$user = $userManager->findOneUserById($id); | |||||
$userProducer = $userProducerContainer->getRepository()->findOneUserProducer($user); | |||||
if ($userProducer) { | |||||
$creditForm = new CreditForm(); | $creditForm = new CreditForm(); | ||||
if ($creditForm->load(\Yii::$app->request->post()) && $creditForm->validate()) { | if ($creditForm->load(\Yii::$app->request->post()) && $creditForm->validate()) { | ||||
$creditForm->id_user = $id; | |||||
$creditForm->save(); | |||||
$creditForm = new CreditForm; | |||||
$user = $userManager->findOneUserById($id); | |||||
} | |||||
$paymentContainer->getUtils() | |||||
->creditOrDebitUser($creditForm->type, $user, $creditForm->amount, $creditForm->mean_payment, $user); | |||||
$history = Payment::find() | |||||
->with(['order', 'userAction']) | |||||
->where([ | |||||
'id_user' => $user->id, | |||||
'id_producer' => $this->getProducerCurrent()->id, | |||||
]) | |||||
->andWhere("payment.type = 'initial-credit' OR payment.type = 'credit' OR payment.type = 'debit' OR (payment.type = 'payment' AND payment.mean_payment = 'credit') OR (payment.type = 'refund' AND payment.mean_payment = 'credit')") | |||||
->orderBy('date DESC') | |||||
->all(); | |||||
if($creditForm->send_mail) { | |||||
$paymentContainer->getNotifier() | |||||
->notifyUserCreditMovement($user, $creditForm->type, $creditForm->amount); | |||||
} | |||||
$this->setFlash('success', 'Crédit mis à jour.'); | |||||
return $this->refresh(); | |||||
} | |||||
return $this->render('credit', [ | return $this->render('credit', [ | ||||
'user' => $user, | 'user' => $user, | ||||
'userProducer' => $userProducer, | 'userProducer' => $userProducer, | ||||
'creditForm' => $creditForm, | 'creditForm' => $creditForm, | ||||
'history' => $history | |||||
'dataProvider' => $paymentContainer->getRepository() | |||||
->queryPaymentsCreditHistoryByUser($user)->getDataProvider(20), | |||||
]); | ]); | ||||
} else { | } else { | ||||
throw new UserException("Vous ne pouvez pas créditer un utilisateur qui n'est pas associé à votre établissement."); | |||||
throw new UserException("Utilisateur introuvable."); | |||||
} | } | ||||
} | } | ||||
termes. | termes. | ||||
*/ | */ | ||||
use yii\grid\GridView; | |||||
use yii\helpers\Html; | use yii\helpers\Html; | ||||
use yii\widgets\ActiveForm; | use yii\widgets\ActiveForm; | ||||
use common\helpers\GlobalParam; | use common\helpers\GlobalParam; | ||||
<div class="col-md-8"> | <div class="col-md-8"> | ||||
<h2>Historique <span class="the-credit"><?= number_format($userManager->getCredit($user), 2); ?> €</span></h2> | <h2>Historique <span class="the-credit"><?= number_format($userManager->getCredit($user), 2); ?> €</span></h2> | ||||
<table class="table table-bordered"> | |||||
<thead> | |||||
<tr> | |||||
<th>Date</th> | |||||
<th>Utilisateur</th> | |||||
<th>Type</th> | |||||
<th>- Débit</th> | |||||
<th>+ Crédit</th> | |||||
<th>Paiement</th> | |||||
<th>Commentaire</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<?php if(count($history)): ?> | |||||
<?php foreach($history as $creditHistory): ?> | |||||
<tr> | |||||
<td><?= $paymentManager->getDate($creditHistory, true) ; ?></td> | |||||
<td><?= Html::encode($paymentManager->getStrUserAction($creditHistory)); ?></td> | |||||
<td><?= $paymentManager->getStrWording($creditHistory); ?></td> | |||||
<td> | |||||
<?php if($paymentManager->isTypeDebit($creditHistory)): ?> | |||||
- <?= $paymentManager->getAmount($creditHistory, true); ?> | |||||
<?php endif; ?> | |||||
</td> | |||||
<td> | |||||
<?php if($paymentManager->isTypeCredit($creditHistory)): ?> | |||||
+ <?= $paymentManager->getAmount($creditHistory, true); ?> | |||||
<?php endif; ?> | |||||
</td> | |||||
<td> | |||||
<?= $paymentManager->getStrMeanPayment($creditHistory) ?> | |||||
</td> | |||||
<td> | |||||
<?php if(strlen($creditHistory->getComment())): ?> | |||||
<?= nl2br($creditHistory->getComment()); ?> | |||||
<?php endif; ?> | |||||
</td> | |||||
</tr> | |||||
<?php endforeach; ?> | |||||
<?php else: ?> | |||||
<tr><td colspan="4">Aucun résultat</td></tr> | |||||
<?php endif; ?> | |||||
</tbody> | |||||
</table> | |||||
<?= GridView::widget([ | |||||
'dataProvider' => $dataProvider, | |||||
'columns' => [ | |||||
[ | |||||
'attribute' => 'date', | |||||
'value' => function ($model) use ($paymentManager) { | |||||
return $paymentManager->getDate($model, true); | |||||
} | |||||
], | |||||
[ | |||||
'attribute' => 'id_user_action', | |||||
'value' => function ($model) use ($paymentManager) { | |||||
return $paymentManager->getStrUserAction($model); | |||||
} | |||||
], | |||||
[ | |||||
'label' => 'Type', | |||||
'format' => 'raw', | |||||
'value' => function ($model) use ($paymentManager) { | |||||
return $paymentManager->getStrWording($model); | |||||
} | |||||
], | |||||
[ | |||||
'attribute' => 'mean_payment', | |||||
'value' => function ($model) use ($paymentManager) { | |||||
return $paymentManager->getStrMeanPayment($model); | |||||
} | |||||
], | |||||
[ | |||||
'label' => '- Débit', | |||||
'format' => 'raw', | |||||
'value' => function ($model) use ($paymentManager) { | |||||
if ($paymentManager->isTypeDebit($model)) { | |||||
return '- ' . $paymentManager->getAmount($model, true); | |||||
} | |||||
return ''; | |||||
} | |||||
], | |||||
[ | |||||
'label' => '+ Crédit', | |||||
'format' => 'raw', | |||||
'value' => function ($model) use ($paymentManager) { | |||||
if ($paymentManager->isTypeCredit($model)) { | |||||
return '+ ' . $paymentManager->getAmount($model, true); | |||||
} | |||||
return ''; | |||||
} | |||||
], | |||||
], | |||||
]); ?> | |||||
</div> | </div> | ||||
</div> | </div> |
<?php | |||||
namespace common\logic; | |||||
use common\components\MailerService; | |||||
abstract class AbstractNotifier extends AbstractService implements NotifierInterface | |||||
{ | |||||
protected MailerService $mailer; | |||||
public function loadDependencies(): void | |||||
{ | |||||
$this->mailer = \Yii::$app->mailerService; | |||||
} | |||||
} |
namespace common\logic; | namespace common\logic; | ||||
use yii\data\ActiveDataProvider; | |||||
abstract class AbstractRepository extends AbstractService implements RepositoryInterface | abstract class AbstractRepository extends AbstractService implements RepositoryInterface | ||||
{ | { | ||||
const WITH = 'with'; | const WITH = 'with'; |
use common\components\ActiveRecordCommon; | use common\components\ActiveRecordCommon; | ||||
use common\logic\Distribution\Distribution\Service\DistributionDefinition; | use common\logic\Distribution\Distribution\Service\DistributionDefinition; | ||||
use yii\data\ActiveDataProvider; | |||||
use yii\db\ActiveQuery; | use yii\db\ActiveQuery; | ||||
abstract class AbstractRepositoryQuery extends AbstractService implements RepositoryQueryInterface | abstract class AbstractRepositoryQuery extends AbstractService implements RepositoryQueryInterface | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getDataProvider(int $pageSize): ActiveDataProvider | |||||
{ | |||||
return new ActiveDataProvider([ | |||||
'query' => $this->query, | |||||
'sort' => false, | |||||
'pagination' => [ | |||||
'pageSize' => $pageSize, | |||||
], | |||||
]); | |||||
} | |||||
} | } |
RepositoryQueryInterface::class, | RepositoryQueryInterface::class, | ||||
RepositoryInterface::class, | RepositoryInterface::class, | ||||
BuilderInterface::class, | BuilderInterface::class, | ||||
NotifierInterface::class, | |||||
ResolverInterface::class, | ResolverInterface::class, | ||||
GeneratorInterface::class, | GeneratorInterface::class, | ||||
UtilsInterface::class, | UtilsInterface::class, |
<?php | |||||
namespace common\logic; | |||||
interface NotifierInterface | |||||
{ | |||||
} |
<?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\Payment\Model; | |||||
use common\helpers\GlobalParam; | |||||
use common\helpers\MeanPayment; | |||||
use common\logic\Payment\Repository\PaymentRepository; | |||||
use yii\data\ActiveDataProvider; | |||||
class CreditHistorySearch extends Payment | |||||
{ | |||||
public function rules(): array | |||||
{ | |||||
return [ | |||||
[['id_user', 'id_user_action', 'id_order', 'id_producer'], 'integer'], | |||||
[['date'], 'safe'], | |||||
[['amount'], 'double'], | |||||
[['type', 'mean_payment', 'comment'], 'string', 'max' => 255], | |||||
]; | |||||
} | |||||
public function search($params) | |||||
{ | |||||
$paymentRepository = PaymentRepository::getInstance(); | |||||
$optionsSearch = $paymentRepository->getDefaultOptionsSearch() ; | |||||
$query = Payment::find() | |||||
->with($optionsSearch['with']) | |||||
->innerJoinWith($optionsSearch['join_with'], true) | |||||
->where([ | |||||
'payment.id_producer' => GlobalParam::getCurrentProducerId(), | |||||
]) | |||||
->andWhere("payment.type = 'initial-credit' OR payment.type = 'credit' OR payment.type = 'debit' OR (payment.type = 'payment' AND payment.mean_payment = 'credit') OR (payment.type = 'refund' AND payment.mean_payment = 'credit')") | |||||
->orderBy('id DESC') | |||||
; | |||||
$dataProvider = new ActiveDataProvider([ | |||||
'query' => $query, | |||||
'sort' => false, | |||||
'pagination' => [ | |||||
'pageSize' => 20, | |||||
], | |||||
]); | |||||
$this->load($params); | |||||
if (!$this->validate()) { | |||||
return $dataProvider; | |||||
} | |||||
if(isset($this->id_user) && is_numeric($this->id_user)) { | |||||
$query->andWhere([ | |||||
'payment.id_user' => $this->id_user | |||||
]) ; | |||||
} | |||||
return $dataProvider; | |||||
} | |||||
} |
use common\logic\AbstractRepository; | use common\logic\AbstractRepository; | ||||
use common\logic\Order\Order\Model\Order; | use common\logic\Order\Order\Model\Order; | ||||
use common\logic\Payment\Model\Payment; | use common\logic\Payment\Model\Payment; | ||||
use common\logic\User\User\Model\User; | |||||
class PaymentRepository extends AbstractRepository | class PaymentRepository extends AbstractRepository | ||||
{ | { | ||||
{ | { | ||||
return [ | return [ | ||||
self::WITH => [ | self::WITH => [ | ||||
'user' | |||||
'user', | |||||
'order', | |||||
'userAction' | |||||
], | ], | ||||
self::JOIN_WITH => [], | self::JOIN_WITH => [], | ||||
self::ORDER_BY => Payment::tableName() . '.date ASc', | self::ORDER_BY => Payment::tableName() . '.date ASc', | ||||
->filterByOrder($order) | ->filterByOrder($order) | ||||
->find(); | ->find(); | ||||
} | } | ||||
public function queryPaymentsCreditHistoryByUser(User $user) | |||||
{ | |||||
return $this->createDefaultQuery() | |||||
->filterByUser($user) | |||||
->filterIsCredit() | |||||
->orderBy('date DESC'); | |||||
} | |||||
public function findPaymentsCreditHistoryByUser(User $user): array | |||||
{ | |||||
return $this->queryPaymentsCreditHistoryByUser($user)->find(); | |||||
} | |||||
} | } |
use common\logic\AbstractRepositoryQuery; | use common\logic\AbstractRepositoryQuery; | ||||
use common\logic\Order\Order\Model\Order; | use common\logic\Order\Order\Model\Order; | ||||
use common\logic\Payment\Service\PaymentDefinition; | use common\logic\Payment\Service\PaymentDefinition; | ||||
use common\logic\User\User\Model\User; | |||||
class PaymentRepositoryQuery extends AbstractRepositoryQuery | class PaymentRepositoryQuery extends AbstractRepositoryQuery | ||||
{ | { | ||||
$this->andWhere(['id_order' => $order->id]); | $this->andWhere(['id_order' => $order->id]); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function filterByUser(User $user): self | |||||
{ | |||||
$this->andWhere(['id_user' => $user->id]); | |||||
return $this; | |||||
} | |||||
public function filterIsCredit() | |||||
{ | |||||
$this->andWhere("payment.type = 'initial-credit' OR payment.type = 'credit' OR payment.type = 'debit' OR (payment.type = 'payment' AND payment.mean_payment = 'credit') OR (payment.type = 'refund' AND payment.mean_payment = 'credit')"); | |||||
return $this; | |||||
} | |||||
} | } |
<?php | |||||
namespace common\logic\Payment\Service; | |||||
use common\logic\AbstractNotifier; | |||||
use common\logic\User\User\Model\User; | |||||
use common\logic\User\User\Repository\UserRepository; | |||||
class PaymentNotifier extends AbstractNotifier | |||||
{ | |||||
protected UserRepository $userRepository; | |||||
public function loadDependencies(): void | |||||
{ | |||||
parent::loadDependencies(); | |||||
$this->userRepository = $this->loadService(UserRepository::class); | |||||
} | |||||
public function notifyUserCreditMovement(User $user, string $type, float $amount) | |||||
{ | |||||
$producer = $this->getProducerContext(); | |||||
$credit = $this->userRepository->getCredit($user, true); | |||||
$this->mailer->sendFromProducer( | |||||
'Mouvement de crédit', | |||||
'creditUser', | |||||
[ | |||||
'user' => $user, | |||||
'producer' => $producer, | |||||
'credit' => $credit, | |||||
'type' => $type, | |||||
'amount' => $amount | |||||
], | |||||
$user->email, | |||||
$producer | |||||
); | |||||
} | |||||
} |
use common\logic\AbstractContainer; | use common\logic\AbstractContainer; | ||||
use common\logic\Payment\Repository\PaymentRepository; | use common\logic\Payment\Repository\PaymentRepository; | ||||
use common\logic\Payment\Service\PaymentNotifier; | |||||
use common\logic\Payment\Service\PaymentUtils; | use common\logic\Payment\Service\PaymentUtils; | ||||
use common\logic\Payment\Service\PaymentBuilder; | use common\logic\Payment\Service\PaymentBuilder; | ||||
use common\logic\Payment\Service\PaymentDefinition; | use common\logic\Payment\Service\PaymentDefinition; | ||||
PaymentSolver::class, | PaymentSolver::class, | ||||
PaymentBuilder::class, | PaymentBuilder::class, | ||||
PaymentRepository::class, | PaymentRepository::class, | ||||
PaymentNotifier::class, | |||||
PaymentUtils::class, | PaymentUtils::class, | ||||
]; | ]; | ||||
} | } | ||||
return PaymentRepository::getInstance(); | return PaymentRepository::getInstance(); | ||||
} | } | ||||
public function getPaymentUtils(): PaymentUtils | |||||
public function getNotifier(): PaymentNotifier | |||||
{ | |||||
return PaymentNotifier::getInstance(); | |||||
} | |||||
public function getUtils(): PaymentUtils | |||||
{ | { | ||||
return PaymentUtils::getInstance(); | return PaymentUtils::getInstance(); | ||||
} | } |
* Retourne le crédit de l'utilisateur pour un producteur donné. | * Retourne le crédit de l'utilisateur pour un producteur donné. | ||||
* | * | ||||
*/ | */ | ||||
public function getCredit(User $user): float | |||||
public function getCredit(User $user, bool $reloadUserProducer = false): float | |||||
{ | { | ||||
$userProducer = $this->userSolver->getUserProducer($user); | |||||
if($reloadUserProducer) { | |||||
$userProducer = $this->userProducerRepository->findOneUserProducer($user); | |||||
} | |||||
else { | |||||
$userProducer = $this->userSolver->getUserProducer($user); | |||||
} | |||||
return $userProducer ? $userProducer->credit : 0; | return $userProducer ? $userProducer->credit : 0; | ||||
} | } | ||||
<p>Bonjour <?= Html::encode($user->name); ?>,</p> | <p>Bonjour <?= Html::encode($user->name); ?>,</p> | ||||
<p>Votre producteur <strong><?= Html::encode($producer->name); ?></strong> vient | <p>Votre producteur <strong><?= Html::encode($producer->name); ?></strong> vient | ||||
de <?php if($creditForm->type == Payment::TYPE_CREDIT): ?>créditer<?php else: ?>débiter<?php endif; ?> votre compte de <strong><?= Price::format($creditForm->amount); ?></strong> sur le site <a href="http://www.opendistrib.net/">Opendistrib</a>.</p> | |||||
de <?php if($type == Payment::TYPE_CREDIT): ?>créditer<?php else: ?>débiter<?php endif; ?> votre compte de <strong><?= Price::format($amount); ?></strong> sur le site <a href="http://www.opendistrib.net/">Opendistrib</a>.</p> | |||||
<p>Votre compte est désormais à <strong><?= Price::format($userProducer->credit); ?></strong><br /> | |||||
<p>Votre compte est désormais à <strong><?= Price::format($credit); ?></strong><br /> | |||||
<a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['credit/history','slug_producer' => $producer->slug]) ?>">Cliquez ici</a> pour voir l'historique de votre crédit.</p> | <a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['credit/history','slug_producer' => $producer->slug]) ?>">Cliquez ici</a> pour voir l'historique de votre crédit.</p> | ||||
<p>À bientôt.</p> | <p>À bientôt.</p> |
Bonjour <?= $user->name; ?>,</p> | Bonjour <?= $user->name; ?>,</p> | ||||
Votre producteur <?= $producer->name; ?> vient de <?php if($creditForm->type == Payment::TYPE_CREDIT): ?>créditer<?php else: ?>débiter<?php endif; ?> votre compte de <?= Price::format($creditForm->amount); ?> sur le site http://www.opendistrib.net/ | |||||
Votre producteur <?= $producer->name; ?> vient de <?php if($type == Payment::TYPE_CREDIT): ?>créditer<?php else: ?>débiter<?php endif; ?> votre compte de <?= Price::format($amount); ?> sur le site http://www.opendistrib.net/ | |||||
Votre compte est désormais à : <?= Price::format($userProducer->credit); ?>. | |||||
Votre compte est désormais à : <?= Price::format($credit); ?>. | |||||
Suivez ce lien pour voir l'historique de votre crédit : <?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['credit/history','slug_producer' => $producer->slug]) ?>"> | Suivez ce lien pour voir l'historique de votre crédit : <?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['credit/history','slug_producer' => $producer->slug]) ?>"> | ||||
À bientôt | À bientôt |
use common\helpers\GlobalParam; | use common\helpers\GlobalParam; | ||||
use common\helpers\MeanPayment; | use common\helpers\MeanPayment; | ||||
use common\logic\Payment\Model\Payment; | use common\logic\Payment\Model\Payment; | ||||
use common\logic\Payment\Model\CreditHistorySearch; | |||||
use producer\models\CreditForm; | use producer\models\CreditForm; | ||||
use yii\data\ActiveDataProvider; | |||||
use yii\filters\VerbFilter; | use yii\filters\VerbFilter; | ||||
class CreditController extends ProducerBaseController | class CreditController extends ProducerBaseController | ||||
*/ | */ | ||||
public function actionHistory(string $returnPayment = '') | public function actionHistory(string $returnPayment = '') | ||||
{ | { | ||||
$producer = $this->getProducerCurrent(); | |||||
if (\Yii::$app->user->isGuest) { | if (\Yii::$app->user->isGuest) { | ||||
return $this->redirect($this->getUrlManagerFrontend()->createAbsoluteUrl(['site/producer', 'id' => $producer->id])); | return $this->redirect($this->getUrlManagerFrontend()->createAbsoluteUrl(['site/producer', 'id' => $producer->id])); | ||||
} | } | ||||
$searchModel = new CreditHistorySearch(); | |||||
$searchModel->id_user = GlobalParam::getCurrentUserId(); | |||||
$dataProvider = $searchModel->search(\Yii::$app->request->queryParams); | |||||
$userProducer = $this->getUserProducerManager()->findOneUserProducer($this->getUserCurrent()); | |||||
$userContainer = $this->getUserContainer(); | |||||
$paymentContainer = $this->getPaymentContainer(); | |||||
$userCurrent = $this->getUserCurrent(); | |||||
if (strlen($returnPayment)) { | if (strlen($returnPayment)) { | ||||
if ($returnPayment == 'success') { | if ($returnPayment == 'success') { | ||||
} | } | ||||
return $this->render('history', [ | return $this->render('history', [ | ||||
'searchModel' => $searchModel, | |||||
'dataProvider' => $dataProvider, | |||||
'creditUser' => $userProducer->credit | |||||
'dataProvider' => $paymentContainer->getRepository() | |||||
->queryPaymentsCreditHistoryByUser($userCurrent)->getDataProvider(20), | |||||
'creditUser' => $userContainer->getRepository()->getCredit($userCurrent) | |||||
]); | ]); | ||||
} | } | ||||