@@ -75,25 +75,28 @@ class AccessController extends BackendController | |||
/** | |||
* Affiche les utilisateurs ayant accès à l'administration de ce producteur. | |||
* Gestion du formulaire permettant d'en ajouter de nouveaux. | |||
* | |||
* @return string | |||
*/ | |||
public function actionIndex() | |||
{ | |||
$userManager = $this->getUserManager(); | |||
$producer = $this->getProducerCurrent(); | |||
$userSearch = new UserSearch(); | |||
$usersArray = $userSearch->search()->query->all(); | |||
$modelAccessUserProducerForm = new AccessUserProducerForm; | |||
if ($modelAccessUserProducerForm->load(\Yii::$app->request->post()) && $modelAccessUserProducerForm->save()) { | |||
$this->setFlash('success', 'Droits ajoutés à l\'utilisateur'); | |||
if ($modelAccessUserProducerForm->load(\Yii::$app->request->post()) && $modelAccessUserProducerForm->validate()) { | |||
$user = $userManager->findOneUserById($modelAccessUserProducerForm->id_user); | |||
if($user && $userManager->grantAccess($user)) { | |||
$this->setFlash('success', 'Droits ajoutés à l\'utilisateur'); | |||
} | |||
else { | |||
$this->addFlash('error', "Une erreur est survenue."); | |||
} | |||
} | |||
$producer = $this->getProducerCurrent(); | |||
$usersAccessArray = $this->getUserManager()->findUsersByProducer($producer); | |||
return $this->render('index', [ | |||
'usersArray' => $usersArray, | |||
'usersAccessArray' => $usersAccessArray, | |||
'usersAccessArray' => $userManager->findUsersByProducer($producer), | |||
'producer' => $producer, | |||
'modelAccessUserProducerForm' => $modelAccessUserProducerForm, | |||
]); | |||
@@ -104,9 +107,11 @@ class AccessController extends BackendController | |||
$userManager = $this->getUserManager(); | |||
$user = $userManager->findOneUserById($idUser); | |||
if ($user) { | |||
$userManager->deleteAccess($user); | |||
$this->setFlash('success', 'Droits de l\'utilisateur supprimé.'); | |||
if ($user && $userManager->deleteAccess($user)) { | |||
$this->addFlash('success', 'Droits de l\'utilisateur supprimé.'); | |||
} | |||
else { | |||
$this->addFlash('error', "Une erreur est survenue."); | |||
} | |||
return $this->redirect(['index']); |
@@ -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); | |||
} | |||
} |
@@ -78,43 +78,6 @@ class CronController extends BackendController | |||
]; | |||
} | |||
/** | |||
* Initialise le compte de démonstration. | |||
* | |||
* @param string $key | |||
*/ | |||
public function actionInitDemo($key = '') | |||
{ | |||
if ($key == '45432df6e842ac71aa0b5bb6b9f25d44') { | |||
$producerManager = $this->getProducerManager(); | |||
$distributionManager = $this->getDistributionManager(); | |||
$producer = $producerManager->findOneProducerDemoAccount(); | |||
$producerManager->setProducerContext($producer); | |||
$distributionManager->setProducerContext($producer); | |||
if ($producer) { | |||
// initialisation de la distribution à J+7 | |||
$dateTime = strtotime("+7 day"); | |||
$dayStr = strtolower(date('l', $dateTime)); | |||
$fieldDeliveryDay = 'delivery_' . $dayStr; | |||
$pointsSaleArray = PointSale::searchAll(['point_sale.id_producer' => $producer->id]); | |||
$activeDistribution = false; | |||
foreach ($pointsSaleArray as $pointSale) { | |||
if ($pointSale->$fieldDeliveryDay) { | |||
$activeDistribution = true; | |||
} | |||
} | |||
if ($activeDistribution) { | |||
$distribution = $distributionManager->createDistributionIfNotExist(date('Y-m-d', $dateTime)); | |||
$distributionManager->activeDistribution($distribution); | |||
} | |||
} | |||
} | |||
} | |||
public function actionPayOrders($date) | |||
{ | |||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||
@@ -202,15 +165,7 @@ class CronController extends BackendController | |||
$orderManager->initOrder($order); | |||
if ($order->auto_payment && $configCredit) { | |||
if ($orderManager->getOrderAmount($order, Order::AMOUNT_REMAINING) > 0) { | |||
$creditHistoryManager->createCreditHistory( | |||
CreditHistory::TYPE_PAYMENT, | |||
$orderManager->getOrderAmount($order, Order::AMOUNT_REMAINING), | |||
$order->distribution->producer, | |||
$order->user, | |||
$userManager->findOneUserById(User::ID_USER_SYSTEM), | |||
MeanPayment::CREDIT, | |||
$order | |||
); | |||
$creditHistoryManager->payOrder($order, $userManager->findOneUserById(User::ID_USER_SYSTEM), false); | |||
$countOrders++; | |||
} | |||
} |
@@ -38,13 +38,7 @@ | |||
namespace backend\controllers; | |||
use common\helpers\GlobalParam; | |||
use common\helpers\Opendistrib; | |||
use common\logic\Development\Development\Development; | |||
use common\logic\Development\DevelopmentPriority\DevelopmentPriority; | |||
use Yii; | |||
use yii\data\ActiveDataProvider; | |||
use yii\web\NotFoundHttpException; | |||
use yii\filters\AccessControl; | |||
/** | |||
@@ -74,9 +68,7 @@ class DevelopmentController extends BackendController | |||
} | |||
/** | |||
* Liste les développements. | |||
* | |||
* @return mixed | |||
* Liste les versions d'Opendistrib | |||
*/ | |||
public function actionIndex() | |||
{ | |||
@@ -90,137 +82,10 @@ class DevelopmentController extends BackendController | |||
]; | |||
} | |||
$producer = $this->getProducerCurrent(); | |||
$producerManager->updateOpendistribVersion($producer); | |||
$producerManager->updateOpendistribVersion($this->getProducerCurrent()); | |||
return $this->render('index', [ | |||
'versionsArray' => $versionsRenderArray | |||
]); | |||
} | |||
public function actionDevelopment($status = Development::STATUS_OPEN) | |||
{ | |||
$dataProvider = new ActiveDataProvider([ | |||
'query' => Development::find() | |||
->with(['developmentPriority', 'developmentPriorityCurrentProducer']) | |||
->where(['status' => $status]) | |||
->orderBy('date DESC'), | |||
]); | |||
return $this->render('development', [ | |||
'dataProvider' => $dataProvider, | |||
'status' => $status | |||
]); | |||
} | |||
/** | |||
* Creates a new Developpement model. | |||
* If creation is successful, the browser will be redirected to the 'view' page. | |||
*/ | |||
public function actionCreate() | |||
{ | |||
$model = new Development(); | |||
if ($model->load(\Yii::$app->request->post())) { | |||
$model->date = date('Y-m-d H:i:s'); | |||
$model->setDateDelivery(); | |||
if ($model->save()) { | |||
$this->setFlash('success', 'Développement ajouté'); | |||
return $this->redirect(['index']); | |||
} | |||
} else { | |||
return $this->render('create', [ | |||
'model' => $model, | |||
]); | |||
} | |||
} | |||
/** | |||
* Updates an existing Developpement model. | |||
* If update is successful, the browser will be redirected to the 'view' page. | |||
* | |||
* @param integer $id | |||
* @return mixed | |||
*/ | |||
public function actionUpdate($id) | |||
{ | |||
$model = $this->findModel($id); | |||
if ($model->load(\Yii::$app->request->post())) { | |||
$model->setDateDelivery(); | |||
if ($model->save()) { | |||
$this->setFlash('success', 'Développement modifié'); | |||
return $this->redirect(['index']); | |||
} | |||
} else { | |||
return $this->render('update', [ | |||
'model' => $model, | |||
]); | |||
} | |||
} | |||
/** | |||
* Deletes an existing Developpement model. | |||
* If deletion is successful, the browser will be redirected to the 'index' page. | |||
* @param integer $id | |||
* @return mixed | |||
*/ | |||
public function actionDelete($id) | |||
{ | |||
$this->findModel($id)->delete(); | |||
$this->setFlash('success', 'Développement supprimé'); | |||
return $this->redirect(['index']); | |||
} | |||
/** | |||
* Définit une priorité pour un développement. | |||
* | |||
* @param integer $idDevelopment | |||
* @param string $priorite | |||
*/ | |||
public function actionPriority($idDevelopment, $priority = null) | |||
{ | |||
$develpmentPriority = DevelopmentPriority::searchOne([ | |||
'id_development' => $idDevelopment, | |||
]); | |||
if (in_array($priority, [DevelopmentPriority::PRIORITY_HIGH, | |||
DevelopmentPriority::PRIORITY_NORMAL, | |||
DevelopmentPriority::PRIORITY_LOW])) { | |||
if ($develpmentPriority) { | |||
$develpmentPriority->priority = $priority; | |||
$develpmentPriority->id_producer = GlobalParam::getCurrentProducerId(); | |||
} else { | |||
$develpmentPriority = new DevelopmentPriority; | |||
$develpmentPriority->id_development = $idDevelopment; | |||
$develpmentPriority->priority = $priority; | |||
$develpmentPriority->id_producer = GlobalParam::getCurrentProducerId(); | |||
} | |||
$develpmentPriority->save(); | |||
} else { | |||
if ($develpmentPriority) { | |||
$develpmentPriority->delete(); | |||
} | |||
} | |||
$this->redirect(['index']); | |||
} | |||
/** | |||
* Finds the Developpement model based on its primary key value. | |||
* If the model is not found, a 404 HTTP exception will be thrown. | |||
*/ | |||
protected function findModel($id) | |||
{ | |||
if (($model = Development::findOne($id)) !== null) { | |||
return $model; | |||
} else { | |||
throw new NotFoundHttpException('The requested page does not exist.'); | |||
} | |||
} | |||
} |
@@ -901,14 +901,23 @@ class OrderController extends BackendController | |||
$comment = $request->post('comment'); | |||
$order = $orderManager->findOneOrderById($idOrder); | |||
$orderManager->initOrder($order); | |||
$user = $userManager->findOneUserById($idUser); | |||
$pointSale = $pointSaleManager->findOnePointSaleById($idPointSale); | |||
if ($order | |||
&& $order->distribution->id_producer == GlobalParam::getCurrentProducerId()) { | |||
// Si changement d'user : on rembourse l'ancien user | |||
$oldIdUser = $order->id_user; | |||
$oldUser = $userManager->findOneUserById($oldIdUser); | |||
$amountPaid = $orderManager->getOrderAmountWithTax($order, Order::AMOUNT_PAID); | |||
if ($oldIdUser != $idUser && $amountPaid > 0) { | |||
$creditHistoryManager->refundOrder($order, $this->getUserCurrent()); | |||
$order = $orderManager->findOneOrderById($idOrder); | |||
$orderManager->initOrder($order); | |||
} | |||
if ($idUser) { | |||
$order->username = ''; | |||
$order->id_user = $idUser; | |||
@@ -994,20 +1003,6 @@ class OrderController extends BackendController | |||
$order = Order::searchOne(['id' => $order->id]); | |||
$orderManager->initOrder($order); | |||
if ($order && $orderManager->isCreditAutoPayment($order)) { | |||
// Si changement d'user : on rembourse l'ancien user | |||
$amountPaid = $orderManager->getOrderAmount($order, Order::AMOUNT_PAID); | |||
if ($oldIdUser != $idUser && $amountPaid > 0) { | |||
$creditHistoryManager->createCreditHistory( | |||
CreditHistory::TYPE_REFUND, | |||
$amountPaid, | |||
$this->getProducerCurrent(), | |||
$oldUser, | |||
$this->getUserCurrent() | |||
); | |||
$order = Order::searchOne(['id' => $order->id]); | |||
$orderManager->initOrder($order); | |||
} | |||
$orderManager->processCredit($order); | |||
} | |||
} | |||
@@ -1101,19 +1096,11 @@ class OrderController extends BackendController | |||
$orderManager = $this->getOrderManager(); | |||
$creditHistoryManager = $this->getCreditHistoryManager(); | |||
$order = $orderManager->findOneOrderById($idOrder); | |||
$orderManager->initOrder($order); | |||
if ($order) { | |||
$creditHistoryManager->createCreditHistory( | |||
$type, | |||
$amount, | |||
GlobalParam::getCurrentProducer(), | |||
$order->user, | |||
GlobalParam::getCurrentUser(), | |||
MeanPayment::CREDIT, | |||
$order | |||
); | |||
$creditHistoryManager->payOrRefundOrder($type, $order, $this->getUserCurrent()); | |||
} | |||
return ['success']; |
@@ -38,6 +38,7 @@ | |||
namespace backend\controllers; | |||
use common\helpers\Alwaysdata; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\Producer\Producer\Model\Producer; | |||
use common\logic\Product\Product\Model\Product; | |||
@@ -130,7 +131,7 @@ class ProducerAdminController extends BackendController | |||
public function actionUpdate(int $id) | |||
{ | |||
$producerManager = $this->getProducerManager(); | |||
$producer = $this->findModel($id); | |||
$producer = $this->findProducer($id); | |||
if ($producer->load(\Yii::$app->request->post()) && $producerManager->saveCreate($producer)) { | |||
$this->setFlash('success', 'Producteur modifié.'); | |||
@@ -147,14 +148,28 @@ class ProducerAdminController extends BackendController | |||
*/ | |||
public function actionBilling(int $id) | |||
{ | |||
$producerManager = $this->getProducerManager(); | |||
$producer = $this->findModel($id); | |||
$producer = $this->findProducer($id); | |||
return $this->render('billing', [ | |||
'producer' => $producer, | |||
]); | |||
} | |||
public function actionAlwaysdata(int $id) | |||
{ | |||
$producer = $this->findProducer($id); | |||
if($producer->contact_email) { | |||
Alwaysdata::createProducerSiteShortUrlRedirection($producer); | |||
Alwaysdata::createProducerEmailRedirection($producer); | |||
} | |||
else { | |||
$this->addFlash('error', "L'adresse email de contact du producteur n'est pas définie."); | |||
} | |||
return $this->redirect(['index']); | |||
} | |||
public function actionUserTransfer($fromProducerId, $toProducerId, $withOrders = 1) | |||
{ | |||
$producerManager = $this->getProducerManager(); | |||
@@ -226,9 +241,11 @@ class ProducerAdminController extends BackendController | |||
/** | |||
* Recherche un producteur. | |||
*/ | |||
protected function findModel(int $id) | |||
protected function findProducer(int $id) | |||
{ | |||
if (($model = Producer::findOne($id)) !== null) { | |||
$producerManager = $this->getProducerManager(); | |||
if (($model = $producerManager->findOneProducerById($id)) !== null) { | |||
return $model; | |||
} else { | |||
throw new NotFoundHttpException('The requested page does not exist.'); |
@@ -38,6 +38,7 @@ | |||
namespace backend\controllers; | |||
use common\helpers\Alwaysdata; | |||
use common\helpers\GlobalParam; | |||
use common\logic\Distribution\Distribution\Model\Distribution; | |||
use common\logic\Order\Order\Model\Order; |
@@ -91,13 +91,13 @@ class SupportController extends BackendController | |||
$ticketMessageManager = $this->getTicketMessageManager(); | |||
$ticket = $ticketManager->instanciateTicket($this->getProducerCurrent(), $userCurrent); | |||
if ($ticket->load(\Yii::$app->request->post()) && $ticketManager->saveCreate($ticket)) { | |||
if ($ticket->load(\Yii::$app->request->post()) && $ticket->validate() && $ticketManager->create($ticket)) { | |||
$ticketMessageManager->createTicketMessage($ticket, $userCurrent, $ticket->message); | |||
$this->setFlash('success', 'Le ticket a bien été créé.'); | |||
return $this->redirect(['view', 'id' => $ticket->id]); | |||
} else { | |||
return $this->render('@backend/views/support/create', [ | |||
'ticket' => $ticket, | |||
'ticket' => $ticket | |||
]); | |||
} | |||
} |
@@ -51,10 +51,12 @@ use common\logic\User\User\Model\User; | |||
use common\logic\User\User\Model\UserSearch; | |||
use common\logic\User\UserProducer\Model\UserProducer; | |||
use common\logic\User\UserUserGroup\Model\UserUserGroup; | |||
use Faker\Provider\HtmlLorem; | |||
use yii\base\UserException; | |||
use yii\filters\AccessControl; | |||
use yii\filters\VerbFilter; | |||
use \Yii; | |||
use yii\helpers\Html; | |||
use yii\web\NotFoundHttpException; | |||
/** | |||
@@ -65,11 +67,6 @@ class UserController extends BackendController | |||
public function behaviors() | |||
{ | |||
return [ | |||
'verbs' => [ | |||
'class' => VerbFilter::class, | |||
'actions' => [ | |||
], | |||
], | |||
'access' => [ | |||
'class' => AccessControl::class, | |||
'rules' => [ | |||
@@ -123,68 +120,14 @@ class UserController extends BackendController | |||
]); | |||
} | |||
public function initForm($model) | |||
{ | |||
$userPointSaleManager = $this->getUserPointSaleManager(); | |||
$userUserGroupManager = $this->getUserUserGroupManager(); | |||
$userProducerManager = $this->getUserProducerManager(); | |||
$userGroupManager = $this->getUserGroupManager(); | |||
$producerCurrent = $this->getProducerCurrent(); | |||
if ($model->id) { | |||
$userPointSaleArray = $userPointSaleManager->findUserPointSalesByUser($model); | |||
if ($userPointSaleArray && count($userPointSaleArray) > 0) { | |||
foreach ($userPointSaleArray as $userPointSale) { | |||
$model->points_sale[] = $userPointSale->id_point_sale; | |||
} | |||
} | |||
$userUserGroupsArray = $userUserGroupManager->findUserUserGroupsByUser($model); | |||
if ($userUserGroupsArray && count($userUserGroupsArray) > 0) { | |||
foreach ($userUserGroupsArray as $userUserGroup) { | |||
$model->user_groups[] = $userUserGroup->id_user_group; | |||
} | |||
} | |||
$userProducer = $userProducerManager->findOneUserProducer($model); | |||
$model->product_price_percent = $userProducer->product_price_percent; | |||
} | |||
$pointsSaleArray = PointSale::find() | |||
->where([ | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
'status' => 1 | |||
]) | |||
->joinWith(['userPointSale' => function ($query) use ($model) { | |||
if ($model->id) { | |||
$query->andOnCondition('user_point_sale.id_user = ' . $model->id); | |||
} | |||
}]) | |||
->all(); | |||
$userGroupsArray = $userGroupManager->findUserGroups(); | |||
return [ | |||
'pointsSaleArray' => $pointsSaleArray, | |||
'userGroupsArray' => $userGroupsArray, | |||
]; | |||
} | |||
/** | |||
* Creates a new User model. | |||
* If creation is successful, the browser will be redirected to the 'view' page. | |||
*/ | |||
public function actionCreate() | |||
{ | |||
$userManager = $this->getUserManager(); | |||
$producerManager = $this->getProducerManager(); | |||
$pointSaleManager = $this->getPointSaleManager(); | |||
$producerCurrent = $this->getProducerCurrent(); | |||
$model = $userManager->instanciateUser(); | |||
$userExist = false; | |||
$posts = Yii::$app->request->post(); | |||
$userExist = false; | |||
if ($posts && isset($posts['User']['email']) && strlen($posts['User']['email']) > 0) { | |||
$userExist = $userManager->findOneUserByEmail($posts['User']['email']); | |||
@@ -232,10 +175,6 @@ class UserController extends BackendController | |||
} | |||
/** | |||
* Updates an existing User model. | |||
* If update is successful, the browser will be redirected to the 'view' page. | |||
*/ | |||
public function actionUpdate($id) | |||
{ | |||
$userManager = $this->getUserManager(); | |||
@@ -262,7 +201,9 @@ class UserController extends BackendController | |||
$this->processLinkUserGroup($model); | |||
$this->processProductPricePercent($model); | |||
$this->setFlash('success', 'Utilisateur modifié.'); | |||
$this->setFlash('success', 'Utilisateur <strong>'.Html::encode($userManager->getUsername($model)).'</strong> modifié.'); | |||
return $this->redirect(['index']); | |||
} | |||
} else { | |||
throw new UserException("Vous ne pouvez pas modifier cet utilisateur."); | |||
@@ -292,7 +233,9 @@ class UserController extends BackendController | |||
] | |||
]); | |||
$this->setFlash('success', 'Nouveau mot de passe envoyé.'); | |||
$this->setFlash('success', 'Nouveau mot de passe envoyé à <strong>'.Html::encode($userManager->getUsername($model)).'</strong>.'); | |||
return $this->redirect(['index']); | |||
} | |||
return $this->render('update', array_merge($this->initForm($model), [ | |||
@@ -301,6 +244,51 @@ class UserController extends BackendController | |||
])); | |||
} | |||
public function initForm($model) | |||
{ | |||
$userPointSaleManager = $this->getUserPointSaleManager(); | |||
$userUserGroupManager = $this->getUserUserGroupManager(); | |||
$userProducerManager = $this->getUserProducerManager(); | |||
$userGroupManager = $this->getUserGroupManager(); | |||
if ($model->id) { | |||
$userPointSaleArray = $userPointSaleManager->findUserPointSalesByUser($model); | |||
if ($userPointSaleArray && count($userPointSaleArray) > 0) { | |||
foreach ($userPointSaleArray as $userPointSale) { | |||
$model->points_sale[] = $userPointSale->id_point_sale; | |||
} | |||
} | |||
$userUserGroupsArray = $userUserGroupManager->findUserUserGroupsByUser($model); | |||
if ($userUserGroupsArray && count($userUserGroupsArray) > 0) { | |||
foreach ($userUserGroupsArray as $userUserGroup) { | |||
$model->user_groups[] = $userUserGroup->id_user_group; | |||
} | |||
} | |||
$userProducer = $userProducerManager->findOneUserProducer($model); | |||
$model->product_price_percent = $userProducer->product_price_percent; | |||
} | |||
$pointsSaleArray = PointSale::find() | |||
->where([ | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
'status' => 1 | |||
]) | |||
->joinWith(['userPointSale' => function ($query) use ($model) { | |||
if ($model->id) { | |||
$query->andOnCondition('user_point_sale.id_user = ' . $model->id); | |||
} | |||
}]) | |||
->all(); | |||
$userGroupsArray = $userGroupManager->findUserGroups(); | |||
return [ | |||
'pointsSaleArray' => $pointsSaleArray, | |||
'userGroupsArray' => $userGroupsArray, | |||
]; | |||
} | |||
/** | |||
* Lie un utilisateur aux points de vente sélectionnés. | |||
*/ | |||
@@ -376,15 +364,16 @@ class UserController extends BackendController | |||
$userProducerManager = $this->getUserProducerManager(); | |||
$user = $userManager->findOneUserById($id); | |||
$producer = $this->getProducerCurrent(); | |||
$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); | |||
} | |||
@@ -395,6 +384,100 @@ class UserController extends BackendController | |||
$this->redirect(array_merge(['index'], $params)); | |||
} | |||
/** | |||
* Affiche les données liées au crédit d'un utilisateur (formulaire, historique). | |||
*/ | |||
public function actionCredit(int $id) | |||
{ | |||
$user = User::find()->with('userProducer')->where(['id' => $id])->one(); | |||
$userProducer = UserProducer::findOne(['id_user' => $id, 'id_producer' => GlobalParam::getCurrentProducerId()]); | |||
if (($userProducer) || $this->isUserCurrentAdmin()) { | |||
$creditForm = new CreditForm(); | |||
if ($creditForm->load(\Yii::$app->request->post()) && $creditForm->validate()) { | |||
$creditForm->id_user = $id; | |||
$creditForm->save(); | |||
$creditForm = new CreditForm; | |||
} | |||
$history = CreditHistory::find() | |||
->with(['order', 'userAction']) | |||
->where([ | |||
'id_user' => $user->id, | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
]) | |||
->orderBy('date DESC') | |||
->all(); | |||
return $this->render('credit', [ | |||
'user' => $user, | |||
'userProducer' => $userProducer, | |||
'creditForm' => $creditForm, | |||
'history' => $history | |||
]); | |||
} else { | |||
throw new UserException("Vous ne pouvez pas créditer un utilisateur qui n'est pas associé à votre établissement."); | |||
} | |||
} | |||
/** | |||
* Modifie l'option "credit_active" d'un utilisateur pour le producteur courant. | |||
* Redirige vers la page de crédit de l'utilisateur. | |||
*/ | |||
public function actionStateCredit($idUser, $state) | |||
{ | |||
$userManager = $this->getUserManager(); | |||
$userProducerManager = $this->getUserProducerManager(); | |||
$user = $userManager->findOneUserById($idUser); | |||
$userProducer = $userProducerManager->findOneUserProducer($user); | |||
if ($userProducer) { | |||
$userProducer->credit_active = $state; | |||
$userProducer->save(); | |||
} | |||
return $this->redirect(['user/credit', 'id' => $idUser]); | |||
} | |||
/** | |||
* Affiche les commandes d'un utilisateur. | |||
* | |||
* @param integer $id | |||
* @return mixed | |||
*/ | |||
public function actionOrders($id) | |||
{ | |||
$userManager = $this->getUserManager(); | |||
$user = $userManager->findOneUserById($id); | |||
$searchModel = new OrderSearch(); | |||
$dataProvider = $searchModel->search(array_merge(\Yii::$app->request->queryParams, ['id_user' => $id])); | |||
return $this->render('orders', [ | |||
'user' => $user, | |||
'searchModel' => $searchModel, | |||
'dataProvider' => $dataProvider, | |||
]); | |||
} | |||
/** | |||
* Finds the User model based on its primary key value. | |||
* If the model is not found, a 404 HTTP exception will be thrown. | |||
*/ | |||
protected function findModel($id) | |||
{ | |||
$userManager = $this->getUserManager(); | |||
if (($user = $userManager->findOneUserById($id)) !== null) { | |||
return $user; | |||
} else { | |||
throw new NotFoundHttpException("Utilisateur introuvable"); | |||
} | |||
} | |||
/** | |||
* Affiche la liste des emails des utilisateurs liés à un point de vente donné. | |||
*/ | |||
@@ -484,99 +567,4 @@ class UserController extends BackendController | |||
'usersPointSaleHasOrder' => $usersPointSaleHasOrder, | |||
]); | |||
} | |||
/** | |||
* Affiche les données liées au crédit d'un utilisateur (formulaire, historique). | |||
*/ | |||
public function actionCredit(int $id) | |||
{ | |||
$user = User::find()->with('userProducer')->where(['id' => $id])->one(); | |||
$userProducer = UserProducer::findOne(['id_user' => $id, 'id_producer' => GlobalParam::getCurrentProducerId()]); | |||
if (($userProducer) || $this->isUserCurrentAdmin()) { | |||
$creditForm = new CreditForm(); | |||
if ($creditForm->load(\Yii::$app->request->post()) && $creditForm->validate()) { | |||
$creditForm->id_user = $id; | |||
$creditForm->save(); | |||
$creditForm = new CreditForm; | |||
} | |||
$history = CreditHistory::find() | |||
->with(['order', 'userAction']) | |||
->where([ | |||
'id_user' => $user->id, | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
]) | |||
->orderBy('date DESC') | |||
->all(); | |||
return $this->render('credit', [ | |||
'user' => $user, | |||
'userProducer' => $userProducer, | |||
'creditForm' => $creditForm, | |||
'history' => $history | |||
]); | |||
} else { | |||
throw new UserException("Vous ne pouvez pas créditer un utilisateur qui n'est pas associé à votre établissement."); | |||
} | |||
} | |||
/** | |||
* Affiche les commandes d'un utilisateur. | |||
* | |||
* @param integer $id | |||
* @return mixed | |||
*/ | |||
public function actionOrders($id) | |||
{ | |||
$userManager = $this->getUserManager(); | |||
$user = $userManager->findOneUserById($id); | |||
$searchModel = new OrderSearch(); | |||
$dataProvider = $searchModel->search(array_merge(\Yii::$app->request->queryParams, ['id_user' => $id])); | |||
return $this->render('orders', [ | |||
'user' => $user, | |||
'searchModel' => $searchModel, | |||
'dataProvider' => $dataProvider, | |||
]); | |||
} | |||
/** | |||
* Modifie l'option "credit_active" d'un utilisateur pour le producteur courant. | |||
* Redirige vers la page de crédit de l'utilisateur. | |||
*/ | |||
public function actionStateCredit($idUser, $state) | |||
{ | |||
$userManager = $this->getUserManager(); | |||
$userProducerManager = $this->getUserProducerManager(); | |||
$user = $userManager->findOneUserById($idUser); | |||
$producerCurrent = $this->getproducerCurrent(); | |||
$userProducer = $userProducerManager->findOneUserProducer($user); | |||
if ($userProducer) { | |||
$userProducer->credit_active = $state; | |||
$userProducer->save(); | |||
} | |||
return $this->redirect(['user/credit', 'id' => $idUser]); | |||
} | |||
/** | |||
* Finds the User model based on its primary key value. | |||
* If the model is not found, a 404 HTTP exception will be thrown. | |||
*/ | |||
protected function findModel($id) | |||
{ | |||
$userManager = $this->getUserManager(); | |||
if (($user = $userManager->findOneUserById($id)) !== null) { | |||
return $user; | |||
} else { | |||
throw new NotFoundHttpException('The requested page does not exist.'); | |||
} | |||
} | |||
} |
@@ -46,6 +46,7 @@ use common\logic\User\CreditHistory\Wrapper\CreditHistoryManager; | |||
use common\logic\User\User\Model\User; | |||
use common\logic\User\User\Wrapper\UserManager; | |||
use common\logic\User\UserProducer\Model\UserProducer; | |||
use common\logic\User\UserProducer\Wrapper\UserProducerManager; | |||
use Yii; | |||
use yii\base\Model; | |||
@@ -103,27 +104,18 @@ class CreditForm extends Model | |||
public function save() | |||
{ | |||
$userManager = UserManager::getInstance(); | |||
$userProducerManager = UserProducerManager::getInstance(); | |||
$creditHistoryManager = CreditHistoryManager::getInstance(); | |||
$producerManager = ProducerManager::getInstance(); | |||
if ($this->validate()) { | |||
$user = $userManager->findOneUserById($this->id_user); | |||
$creditHistoryManager->createCreditHistory( | |||
$this->type, | |||
$this->amount, | |||
GlobalParam::getCurrentProducer(), | |||
$user, | |||
Yii::$app->user->identity, | |||
$this->mean_payment | |||
); | |||
$creditHistoryManager->creditOrDebitUser($this->type, $user, $this->amount, $this->mean_payment, $userManager->getCurrent()); | |||
// on prévient l'utilisateur que son compte vient d'être crédité | |||
if($this->send_mail) { | |||
$user = User::findOne($this->id_user) ; | |||
$producer = GlobalParam::getCurrentProducer() ; | |||
$userProducer = UserProducer::searchOne([ | |||
'id_user' => $this->id_user | |||
]); | |||
$userProducer = $userProducerManager->findOneUserProducer($user); | |||
$paramsEmail = [ | |||
'from_email' => $producerManager->getEmailOpendistrib($producer), |
@@ -0,0 +1,79 @@ | |||
<?php | |||
use common\helpers\Price; | |||
use yii\grid\GridView; | |||
$userManager = $this->getUserManager(); | |||
$this->setTitle('Crédit'); | |||
?> | |||
<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">Somme totale en crédit</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']); | |||
} | |||
] | |||
] | |||
]); | |||
?> |
@@ -53,18 +53,20 @@ $this->addBreadcrumb($this->getTitle()); | |||
<div class="container-fluidd"> | |||
<div class="row"> | |||
<div class="col-md-8"> | |||
<?php foreach($versionsArray as $version): ?> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title"> | |||
<?= $version['version'] ?> | |||
</h3> | |||
<div id="versions-list"> | |||
<?php foreach($versionsArray as $version): ?> | |||
<div class="panel panel-default"> | |||
<div class="panel-heading"> | |||
<h3 class="panel-title"> | |||
<?= $version['version'] ?> | |||
</h3> | |||
</div> | |||
<div class="panel-body"> | |||
<?= $version['content'] ?> | |||
</div> | |||
</div> | |||
<div class="panel-body"> | |||
<?= $version['content'] ?> | |||
</div> | |||
</div> | |||
<?php endforeach; ?> | |||
<?php endforeach; ?> | |||
</div> | |||
</div> | |||
<div class="col-md-4"> | |||
<div id="panel-participate" class="panel panel-default"> |
@@ -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 }} |
@@ -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): ?> |
@@ -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()], | |||
], | |||
], |
@@ -45,13 +45,16 @@ use common\logic\Producer\Producer\Model\Producer; | |||
<?php $form = ActiveForm::begin(); ?> | |||
<h3>Général</h3> | |||
<?= $form->field($model, 'slug') ?> | |||
<?= $form->field($model, 'name') ?> | |||
<?= $form->field($model, 'type')->textInput(['placeholder' => 'Boulangerie, brasserie, ferme ...']); ?> | |||
<?= $form->field($model, 'postcode') ?> | |||
<?= $form->field($model, 'city') ?> | |||
<?= $form->field($model, 'contact_email') ?> | |||
<?= $form->field($model, 'latitude') ?> | |||
<?= $form->field($model, 'longitude') ?> | |||
<?= $form->field($model, 'code')->label('Code d\'accès') ?> | |||
<?= $form->field($model, 'admin_comment')->textarea(['rows' => 7]) ?> | |||
<h3>Facturation</h3> | |||
<?= $form->field($model, 'option_billing_type') |
@@ -157,52 +157,68 @@ $this->addButton(['label' => 'Nouveau producteur <span class="glyphicon glyphico | |||
} | |||
],*/ | |||
[ | |||
'attribute' => 'À facturer / chiffre d\'affaire', | |||
'label' => 'À facturer / chiffre d\'affaire', | |||
'label' => 'Facturation', | |||
'format' => 'raw', | |||
'value' => function($producer) use ($producerManager) { | |||
$str = ''; | |||
if($producerManager->isBillingFrequencyMonthly($producer)) { | |||
$str .= $producerManager->getSummaryAmountsToBeBilled($producer, 'Mois dernier', 1); | |||
} | |||
elseif($producerManager->isBillingFrequencyQuarterly($producer)) { | |||
$str .= $producerManager->getSummaryAmountsToBeBilled($producer, '3 derniers mois', 3); | |||
} | |||
elseif($producerManager->isBillingFrequencyBiannual($producer)) { | |||
$str .= $producerManager->getSummaryAmountsToBeBilled($producer, '6 derniers mois', 6); | |||
} | |||
$str .= '<ul style="margin: 0px;padding-left: 15px;">'; | |||
$isBillingFrequencyMonthly = $producerManager->isBillingFrequencyMonthly($producer); | |||
$summaryMonthly = $producerManager->getSummaryAmountsToBeBilled($producer, 'Mois dernier', 1); | |||
$isBillingFrequencyQuaterly = $producerManager->isBillingFrequencyQuarterly($producer); | |||
$summaryQuaterly = $producerManager->getSummaryAmountsToBeBilled($producer, '3 derniers mois', 3); | |||
$isBillingFrequencyBiannual = $producerManager->isBillingFrequencyBiannual($producer); | |||
$summaryBiannual = $producerManager->getSummaryAmountsToBeBilled($producer, '6 derniers mois', 6); | |||
if($producer->option_billing_reduction && strlen($str)) { | |||
$str .= '<br /><u>Avec réduction</u> : '; | |||
if($producer->option_billing_reduction_percentage) { | |||
$str .= ' '.$producer->option_billing_reduction_percentage.' %'; | |||
if(($isBillingFrequencyMonthly && $summaryMonthly) | |||
|| ($isBillingFrequencyQuaterly && $summaryQuaterly) | |||
|| ($isBillingFrequencyBiannual && $summaryBiannual)) { | |||
$str .= '<li>'; | |||
if ($isBillingFrequencyMonthly && $summaryMonthly) { | |||
$str .= $summaryMonthly; | |||
} elseif ($isBillingFrequencyQuaterly && $summaryQuaterly) { | |||
$str .= $summaryQuaterly; | |||
} elseif ($isBillingFrequencyBiannual && $summaryBiannual) { | |||
$str .= $summaryBiannual; | |||
} | |||
if ($producer->option_billing_reduction && strlen($str)) { | |||
$str .= '<br /><u>Avec réduction</u> : '; | |||
if ($producer->option_billing_reduction_percentage) { | |||
$str .= ' ' . $producer->option_billing_reduction_percentage . ' %'; | |||
} | |||
} | |||
$str .= '</li>'; | |||
$str .= '<li>Facturation '.strtolower(Producer::$billingFrequencyArray[$producer->option_billing_frequency]).'</li>'; | |||
} | |||
if($producer->option_billing_permanent_transfer) { | |||
$str .= '<li>Virement permanent : <strong>'.Price::format($producer->option_billing_permanent_transfer_amount).'</strong></li>'; | |||
} | |||
$str .= '</ul>'; | |||
return $str; | |||
} | |||
], | |||
[ | |||
'attribute' => 'Facturation', | |||
'label' => 'Détails facturation', | |||
'attribute' => 'admin_comment', | |||
'label' => 'Commentaire', | |||
'format' => 'raw', | |||
'value' => function($model) { | |||
$str = '<ul style="margin: 0px;padding-left: 15px;">'; | |||
$str .= '<li>'.Producer::$billingFrequencyArray[$model->option_billing_frequency].'</li>'; | |||
if($model->option_billing_permanent_transfer) { | |||
$str .= '<li>Virement permanent : <strong>'.Price::format($model->option_billing_permanent_transfer_amount).'</strong></li>'; | |||
'value' => function($producer) { | |||
if($producer->admin_comment) { | |||
return $producer->admin_comment; | |||
} | |||
$str .= '</ul>'; | |||
return $str; | |||
return ''; | |||
} | |||
], | |||
[ | |||
'class' => 'yii\grid\ActionColumn', | |||
'template' => '{update} {billing}', | |||
'template' => '{update} {billing} {alwaysdata}', | |||
'headerOptions' => ['class' => 'column-actions'], | |||
'contentOptions' => ['class' => 'column-actions'], | |||
'buttons' => [ | |||
@@ -226,6 +242,16 @@ $this->addButton(['label' => 'Nouveau producteur <span class="glyphicon glyphico | |||
] | |||
); | |||
}, | |||
'alwaysdata' => function ($url, $model) { | |||
return Html::a( | |||
'<span class="glyphicon glyphicon-road"></span>', | |||
$url, | |||
[ | |||
'title' => 'Redirections Alwaysdata (email et url courte)', | |||
'class' => 'btn btn-default' | |||
] | |||
); | |||
}, | |||
], | |||
], | |||
], |
@@ -120,13 +120,6 @@ $this->addBreadcrumb($this->getTitle()); | |||
Producer::BEHAVIOR_HOME_POINT_SALE_DAY_LIST_INCOMING_DISTRIBUTIONS => 'Distributions à venir', | |||
]); ?> | |||
<?= $form->field($model, 'option_point_sale_wording') ?> | |||
<h4>Logiciel</h4> | |||
<?= $form->field($model, 'option_display_message_new_opendistrib_version') | |||
->dropDownList([ | |||
1 => 'Oui', | |||
0 => 'Non' | |||
], []); ?> | |||
</div> | |||
</div> | |||
@@ -481,6 +474,35 @@ $this->addBreadcrumb($this->getTitle()); | |||
->textarea(['rows' => 15]) ?> | |||
</div> | |||
</div> | |||
<div v-show="currentSection == 'software'" class="panel panel-default"> | |||
<div class="panel-body"> | |||
<h4>Opendistrib</h4> | |||
<?= $form->field($model, 'option_testimony') | |||
->textarea(['rows' => 7]) | |||
->hint("Écrivez ici votre témoignage concernant l'utilisation du logiciel. Il sera publié sur la page 'À propos' du site.") ; ?> | |||
<?= $form->field($model, 'option_time_saved') | |||
->dropDownList([ | |||
null => '--', | |||
0.5 => '30 minutes', | |||
1 => '1 heure', | |||
2 => '2 heures', | |||
3 => '3 heures', | |||
4 => '4 heures', | |||
5 => '5 heures', | |||
6 => '6 heures', | |||
7 => '7 heures', | |||
8 => '8 heures', | |||
]) | |||
->hint("Sélectionnez le temps que vous estimez gagner chaque semaine en utilisant ce logiciel. Cette donnée sera utilisée sur la page 'À propos' du site.") ; ?> | |||
<?= $form->field($model, 'option_display_message_new_opendistrib_version') | |||
->dropDownList([ | |||
1 => 'Oui', | |||
0 => 'Non' | |||
], []); ?> | |||
</div> | |||
</div> | |||
<div class="form-group"> | |||
<?= Html::submitButton('Mettre à jour', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> | |||
</div> |
@@ -1,5 +1,6 @@ | |||
<?php | |||
use common\helpers\Image; | |||
use yii\helpers\Html; | |||
use yii\bootstrap\ActiveForm; | |||
use yii\helpers\ArrayHelper; | |||
@@ -117,9 +118,7 @@ $taxRateManager = $this->getTaxRateManager(); | |||
<?= $form->field($model, 'photo')->fileInput() ?> | |||
<?php | |||
if (strlen($model->photo)) { | |||
$url = Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->photo; | |||
$url = str_replace('//uploads','/uploads', $url) ; | |||
echo '<img class="photo-product" src="' . $url . '" width="200px" /><br />'; | |||
echo '<img class="photo-product" src="' . Image::getThumbnailSmall($model->photo, true). '" width="200px" /><br />'; | |||
echo '<input type="checkbox" name="delete_photo" id="delete_photo" /> <label for="delete_photo">Supprimer la photo</label>'; | |||
} | |||
?> |
@@ -36,6 +36,7 @@ | |||
* termes. | |||
*/ | |||
use common\helpers\Image; | |||
use yii\helpers\Html; | |||
use yii\grid\GridView; | |||
use common\helpers\GlobalParam; | |||
@@ -77,9 +78,7 @@ $this->addButton(['label' => 'Nouveau produit <span class="glyphicon glyphicon-p | |||
'filter' => '', | |||
'value' => function ($model) { | |||
if (strlen($model->photo)) { | |||
$url = Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->photo; | |||
$url = str_replace('//uploads', '/uploads', $url); | |||
return '<img class="photo-product" src="' . $url . '" />'; | |||
return '<img class="photo-product" src="' . Image::getThumbnailSmall($model->photo, true) . '" />'; | |||
} | |||
return ''; | |||
} |
@@ -69,6 +69,7 @@ $producerManager = $this->getProducerManager(); | |||
<?= $form->field($model, 'evoliz_code')->textInput() ?> | |||
<?php endif; ?> | |||
<?php if($pointsSaleArray && count($pointsSaleArray) > 0): ?> | |||
<?= $form->field($model, 'points_sale')->checkboxlist( | |||
ArrayHelper::map($pointsSaleArray, 'id', function ($pointSale) use ($model) { | |||
$commentUserPointSale = isset($pointSale->userPointSale[0]) ? $pointSale->userPointSale[0]->comment : ''; | |||
@@ -81,7 +82,9 @@ $producerManager = $this->getProducerManager(); | |||
'encode' => false | |||
]); | |||
?> | |||
<?php endif; ?> | |||
<?php if($userGroupsArray && count($userGroupsArray) > 0): ?> | |||
<?= $form->field($model, 'user_groups')->checkboxlist( | |||
ArrayHelper::map($userGroupsArray, 'id', function ($userGroup) use ($model) { | |||
return Html::encode($userGroup->name); | |||
@@ -89,6 +92,7 @@ $producerManager = $this->getProducerManager(); | |||
'encode' => false | |||
]); | |||
?> | |||
<?php endif; ?> | |||
<?php /* $form->field($model, 'product_price_percent') | |||
->dropDownList( ProductPrice::percentValues(), [])->hint('Pourcentage appliqué aux prix de chaque produit pour cet utilisateur.');*/ ?> |
@@ -2645,22 +2645,42 @@ termes. | |||
width: 200px; | |||
} | |||
/* line 4, ../sass/development/_index.scss */ | |||
/* line 6, ../sass/development/_index.scss */ | |||
.development-index #versions-list .panel .block { | |||
margin-bottom: 15px; | |||
} | |||
/* line 9, ../sass/development/_index.scss */ | |||
.development-index #versions-list .panel .block .glyphicon { | |||
font-size: 15px; | |||
margin-right: 3px; | |||
} | |||
/* line 14, ../sass/development/_index.scss */ | |||
.development-index #versions-list .panel .block h4 { | |||
font-size: 16px; | |||
border-bottom: solid 1px #e0e0e0; | |||
padding-bottom: 4px; | |||
} | |||
/* line 20, ../sass/development/_index.scss */ | |||
.development-index #versions-list .panel .block ul { | |||
padding: 0px; | |||
list-style-type: none; | |||
} | |||
/* line 33, ../sass/development/_index.scss */ | |||
.development-index #panel-participate ul.contacts { | |||
padding: 0px; | |||
padding-left: 10px; | |||
margin: 0px; | |||
list-style-type: none; | |||
} | |||
/* line 10, ../sass/development/_index.scss */ | |||
/* line 39, ../sass/development/_index.scss */ | |||
.development-index #panel-participate ul.contacts li { | |||
padding-bottom: 10px; | |||
} | |||
/* line 13, ../sass/development/_index.scss */ | |||
/* line 42, ../sass/development/_index.scss */ | |||
.development-index #panel-participate ul.contacts li .glyphicon { | |||
float: left; | |||
} | |||
/* line 17, ../sass/development/_index.scss */ | |||
/* line 46, ../sass/development/_index.scss */ | |||
.development-index #panel-participate ul.contacts li p { | |||
padding-left: 25px; | |||
} |
@@ -80,6 +80,11 @@ var app = new Vue({ | |||
name: 'logiciels-caisse', | |||
nameDisplay: 'Logiciels de caisse', | |||
isAdminSection: 0 | |||
}, | |||
{ | |||
name: 'software', | |||
nameDisplay: 'Opendistrib', | |||
isAdminSection: 0 | |||
} | |||
] | |||
}, window.appInitValues); |
@@ -1,5 +1,34 @@ | |||
.development-index { | |||
#versions-list { | |||
.panel { | |||
.block { | |||
margin-bottom: 15px; | |||
.glyphicon { | |||
font-size: 15px; | |||
margin-right: 3px; | |||
} | |||
h4 { | |||
font-size: 16px; | |||
border-bottom: solid 1px #e0e0e0; | |||
padding-bottom: 4px; | |||
} | |||
ul { | |||
padding: 0px; | |||
list-style-type: none; | |||
li { | |||
} | |||
} | |||
} | |||
} | |||
} | |||
#panel-participate { | |||
ul.contacts { | |||
padding: 0px; |
@@ -20,7 +20,6 @@ class BusinessLogic | |||
$this->getUserProducerContainer(), | |||
$this->getUserPointSaleContainer(), | |||
$this->getUserContainer(), | |||
$this->getOrderSatusHistoryContainer(), | |||
$this->getPointSaleDistributionContainer(), | |||
$this->getProductDistributionContainer(), | |||
$this->getProductCategoryContainer(), |
@@ -20,8 +20,6 @@ use common\logic\Document\Quotation\Wrapper\QuotationContainer; | |||
use common\logic\Document\Quotation\Wrapper\QuotationManager; | |||
use common\logic\Order\Order\Wrapper\OrderContainer; | |||
use common\logic\Order\Order\Wrapper\OrderManager; | |||
use common\logic\Order\OrderStatusHistory\Wrapper\OrderStatusHistoryContainer; | |||
use common\logic\Order\OrderStatusHistory\Wrapper\OrderStatusHistoryManager; | |||
use common\logic\Order\ProductOrder\Wrapper\ProductOrderContainer; | |||
use common\logic\Order\ProductOrder\Wrapper\ProductOrderManager; | |||
use common\logic\PointSale\PointSale\Wrapper\PointSaleContainer; | |||
@@ -113,11 +111,6 @@ trait BusinessLogicTrait | |||
return QuotationManager::getInstance(); | |||
} | |||
public function getOrderStatusHistoryManager(): OrderStatusHistoryManager | |||
{ | |||
return OrderStatusHistoryManager::getInstance(); | |||
} | |||
public function getProductOrderManager(): ProductOrderManager | |||
{ | |||
return ProductOrderManager::getInstance(); | |||
@@ -278,11 +271,6 @@ trait BusinessLogicTrait | |||
return OrderContainer::getInstance(); | |||
} | |||
public function getOrderSatusHistoryContainer(): OrderStatusHistoryContainer | |||
{ | |||
return OrderStatusHistoryContainer::getInstance(); | |||
} | |||
public function getUserPointSaleContainer(): UserPointSaleContainer | |||
{ | |||
return UserPointSaleContainer::getInstance(); |
@@ -37,10 +37,14 @@ | |||
*/ | |||
use common\components\BusinessLogic; | |||
use common\logic\Distribution\Distribution\Model\Distribution; | |||
use common\logic\Ticket\Ticket\Model\Ticket; | |||
use common\logic\User\CreditHistory\Model\CreditHistory; | |||
$serverName = isset($_SERVER['SERVER_NAME']) ?? ''; | |||
return [ | |||
'bootstrap' => ['listener'], | |||
'aliases' => [ | |||
'@bower' => '@vendor/bower-asset', | |||
], | |||
@@ -116,12 +120,26 @@ return [ | |||
'enablePrettyUrl' => true, | |||
'showScriptName' => false, | |||
'enableStrictParsing' => false, | |||
'rules' => [ | |||
], | |||
'rules' => [], | |||
], | |||
'logic' => function () { | |||
return new BusinessLogic(); | |||
} | |||
}, | |||
'listener' => [ | |||
'class' => \justcoded\yii2\eventlistener\components\EventListener::class, | |||
'listeners' => [], | |||
'observers' => [ | |||
CreditHistory::class => [ | |||
common\logic\User\UserProducer\Event\CreditHistoryObserver::class | |||
], | |||
Distribution::class => [ | |||
common\logic\Subscription\Subscription\Event\DistributionObserver::class | |||
], | |||
Ticket::class => [ | |||
common\logic\User\User\Event\TicketObserver::class, | |||
], | |||
], | |||
], | |||
], | |||
'language' => 'fr-FR', | |||
'timeZone' => 'Europe/Paris', |
@@ -37,7 +37,7 @@ | |||
*/ | |||
return [ | |||
'version' => '23.8.A', | |||
'version' => '23.8.B', | |||
'adminEmail' => 'contact@opendistrib.net', | |||
'supportEmail' => 'contact@opendistrib.net', | |||
'user.passwordResetTokenExpire' => 3600, |
@@ -0,0 +1,18 @@ | |||
<?php | |||
namespace common\events; | |||
use yii\base\Event; | |||
use yii\base\Model; | |||
class EntityManagerEvent extends Event | |||
{ | |||
const PRE_CREATE_EVENT = 'entity_manager_event.pre_create'; | |||
const POST_CREATE_EVENT = 'entity_manager_event.post_create'; | |||
const PRE_UPDATE_EVENT = 'entity_manager_event.pre_update'; | |||
const POST_UPDATE_EVENT = 'entity_manager_event.post_update'; | |||
const PRE_DELETE_EVENT = 'entity_manager_event.pre_delete'; | |||
const POST_DELETE_EVENT = 'entity_manager_event.post_delete'; | |||
public Model $model; | |||
} |
@@ -0,0 +1,62 @@ | |||
<?php | |||
namespace common\helpers; | |||
use common\logic\Producer\Producer\Model\Producer; | |||
use GuzzleHttp\Client; | |||
use yii\base\ErrorException; | |||
class Alwaysdata | |||
{ | |||
public static function createProducerEmailRedirection(Producer $producer) | |||
{ | |||
return self::post('mailbox',[ | |||
'domain' => \Yii::$app->params['alwaysdataDomainOpendistribId'], | |||
'name' => $producer->slug, | |||
'password' => Password::generate(13), | |||
'redirect_enabled' => true, | |||
'redirect_to' => $producer->contact_email | |||
]); | |||
} | |||
public static function createProducerSiteShortUrlRedirection(Producer $producer) | |||
{ | |||
return self::post('site', [ | |||
'addresses' => [$producer->slug.'.opendistrib.net'], | |||
'type' => 'redirect', | |||
'url' => 'https://producteurs.opendistrib.net/'.$producer->slug, | |||
'redirect_type' => 'PERMANENT', | |||
'annotation' => 'Opendistrib / '.$producer->name | |||
]); | |||
} | |||
private static function post(string $resource, array $data) | |||
{ | |||
$client = self::getClient($resource); | |||
return $client->request('POST', '', [ | |||
'body' => json_encode($data) | |||
]); | |||
} | |||
private static function getClient(string $resource) | |||
{ | |||
self::checkConfiguration(); | |||
return new Client([ | |||
'base_uri' => \Yii::$app->params['alwaysdataApiUrl'].$resource.'/', | |||
'auth' => [\Yii::$app->params['alwaysdataApiKey'].' account='.\Yii::$app->params['alwaysdataAccount'], ''], | |||
]); | |||
} | |||
private static function checkConfiguration() | |||
{ | |||
if(!isset(\Yii::$app->params['alwaysdataApiUrl']) | |||
|| !isset(\Yii::$app->params['alwaysdataAccount']) | |||
|| !isset(\Yii::$app->params['alwaysdataApiKey']) | |||
|| !isset(\Yii::$app->params['alwaysdataDomainOpendistribId'])) { | |||
throw new ErrorException('Configuration API Alwaysdata absente ou incomplète dans params-local.php'); | |||
} | |||
} | |||
} |
@@ -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(); |
@@ -0,0 +1,58 @@ | |||
<?php | |||
namespace common\helpers; | |||
class Image | |||
{ | |||
const DIR_UPLOADS = 'uploads'; | |||
const THUMBNAIL_SMALL = 'small'; | |||
const THUMBNAIL_MEDIUM = 'medium'; | |||
const THUMBNAIL_BIG = 'big'; | |||
public static function getThumbnailSmall(string $filenameOriginal, bool $absoluteUrl = false) | |||
{ | |||
return self::getThumbnail($filenameOriginal, self::THUMBNAIL_SMALL, $absoluteUrl); | |||
} | |||
public static function getThumbnailMedium(string $filenameOriginal, bool $absoluteUrl = false) | |||
{ | |||
return self::getThumbnail($filenameOriginal, self::THUMBNAIL_MEDIUM, $absoluteUrl); | |||
} | |||
public static function getThumbnailBig(string $filenameOriginal, bool $absoluteUrl = false) | |||
{ | |||
return self::getThumbnail($filenameOriginal, self::THUMBNAIL_BIG, $absoluteUrl); | |||
} | |||
public static function getThumbnail(string $filenameOriginal, string $thumbnail = self::THUMBNAIL_MEDIUM, bool $absoluteUrl = false) | |||
{ | |||
$basePath = self::getBasePath($absoluteUrl); | |||
$thumbnailFilename = self::getThumbnailFilename($filenameOriginal, $thumbnail); | |||
$thumbnailPath = $basePath . $thumbnailFilename; | |||
$originalPath = $basePath . $filenameOriginal; | |||
return self::isThumbnailExist($thumbnailFilename) ? $thumbnailPath : $originalPath; | |||
} | |||
public static function getBasePath(bool $absoluteUrl = false): string | |||
{ | |||
$absoluteUrlPrepend = ''; | |||
if($absoluteUrl) { | |||
$absoluteUrlPrepend = \Yii::$app->urlManagerProducer->getHostInfo(); | |||
} | |||
return $absoluteUrlPrepend . \Yii::$app->urlManagerProducer->baseUrl.'/'.self::DIR_UPLOADS.'/'; | |||
} | |||
public static function getThumbnailFilename(string $filename, string $thumbnail = self::THUMBNAIL_MEDIUM) | |||
{ | |||
$filenameArray = explode('.', $filename); | |||
return $filenameArray[0].'-'.$thumbnail.'.'.$filenameArray[1]; | |||
} | |||
public static function isThumbnailExist(string $thumbnailFilename): bool | |||
{ | |||
return file_exists(\Yii::getAlias('@producer').'/web/'.self::DIR_UPLOADS.'/'.$thumbnailFilename); | |||
} | |||
} |
@@ -49,7 +49,7 @@ class Opendistrib | |||
{ | |||
$directory = opendir($pathVersions); | |||
while( $child = readdir($directory) ){ | |||
if($child != '.' && $child != '..'){ | |||
if($child != '.' && $child != '..' && $child != '_macros.php'){ | |||
$version = str_replace('.php', '', $child); | |||
$versionsArray[] = $version; | |||
} |
@@ -1,95 +1,84 @@ | |||
<?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. | |||
*/ | |||
/** | |||
* 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\helpers; | |||
use yii\web\UploadedFile; | |||
use Yii ; | |||
use Yii; | |||
class Upload | |||
class Upload | |||
{ | |||
public static function uploadFile($model, $champs, $filename_old = '') | |||
public static function uploadFile($model, $champs, $filename_old = '') | |||
{ | |||
$file = UploadedFile::getInstance($model, $champs); | |||
if ($file) { | |||
$file_name = $file->baseName . '-' . uniqid() ; | |||
$file_name_extension = $file_name .'.'.$file->extension ; | |||
$dir_file = '../../producer/web/uploads/' ; | |||
$path_file = $dir_file . $file_name_extension ; | |||
$file_name = $file->baseName . '-' . uniqid(); | |||
$file_name_extension = $file_name . '.' . $file->extension; | |||
$dir_file = '../../producer/web/uploads/'; | |||
$path_file = $dir_file . $file_name_extension; | |||
$file->saveAs($path_file); | |||
// resize image | |||
list($width, $height, $type, $attr) = getimagesize($path_file); | |||
if($width > 500) | |||
{ | |||
if ($width > 500) { | |||
$image = Yii::$app->image->load($path_file); | |||
// big | |||
if($width > 1600) | |||
{ | |||
$image->resize(1600) | |||
->save($dir_file . $file_name . '-big.'.$file->extension); | |||
if ($width > 1600) { | |||
$image->resize(1600)->save($dir_file . $file_name . '-big.' . $file->extension); | |||
} | |||
// medium | |||
if($width > 1024) | |||
{ | |||
$image->resize(1024)->save($dir_file . $file_name_extension) ; | |||
$image->save($dir_file . $file_name . '-medium.'.$file->extension); | |||
if ($width > 1024) { | |||
$image->resize(1024)->save($dir_file . $file_name . '-medium.' . $file->extension); | |||
} | |||
// small | |||
if($width > 500) | |||
{ | |||
$image->resize(500) | |||
->save($dir_file . $file_name . '-small.'.$file->extension); | |||
if ($width > 500) { | |||
$image->resize(500)->save($dir_file . $file_name . '-small.' . $file->extension); | |||
} | |||
} | |||
$model->$champs = $file_name_extension ; | |||
$model->$champs = $file_name_extension; | |||
} else { | |||
$model->$champs = $filename_old; | |||
} | |||
$model->save(); | |||
} | |||
} |
@@ -2,22 +2,39 @@ | |||
namespace common\logic; | |||
use yii\base\Model; | |||
use yii\db\ActiveRecord; | |||
abstract class AbstractBuilder extends AbstractService implements BuilderInterface | |||
{ | |||
public function saveCreate(ActiveRecord $model): bool | |||
public function create(Model $model): bool | |||
{ | |||
return $model->save(); | |||
} | |||
public function saveUpdate(ActiveRecord $model): bool | |||
public function update(Model $model): bool | |||
{ | |||
return $model->save(); | |||
} | |||
public function delete(ActiveRecord $model): bool | |||
public function delete(Model $model): bool | |||
{ | |||
return $model->delete(); | |||
} | |||
/** | |||
* @deprecated | |||
*/ | |||
public function saveCreate(ActiveRecord $model): bool | |||
{ | |||
return $model->save(); | |||
} | |||
/** | |||
* @deprecated | |||
*/ | |||
public function saveUpdate(ActiveRecord $model): bool | |||
{ | |||
return $model->save(); | |||
} | |||
} |
@@ -0,0 +1,8 @@ | |||
<?php | |||
namespace common\logic; | |||
abstract class AbstractGenerator extends AbstractService implements GeneratorInterface | |||
{ | |||
} |
@@ -17,6 +17,7 @@ abstract class AbstractService extends AbstractSingleton implements ServiceInter | |||
RepositoryInterface::class, | |||
BuilderInterface::class, | |||
ResolverInterface::class, | |||
GeneratorInterface::class, | |||
UtilsInterface::class, | |||
]; | |||
} |
@@ -1,148 +0,0 @@ | |||
<?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\Development\Development; | |||
use common\helpers\GlobalParam; | |||
use Yii; | |||
use common\components\ActiveRecordCommon ; | |||
/** | |||
* This is the model class for table "development". | |||
*/ | |||
class Development extends ActiveRecordCommon | |||
{ | |||
const STATUS_OPEN = 'open'; | |||
const STATUS_CLOSED = 'closed'; | |||
const TYPE_EVOLUTION = 'evolution'; | |||
const TYPE_BUG = 'bug'; | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public static function tableName() | |||
{ | |||
return 'development'; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function rules() | |||
{ | |||
return [ | |||
[['subject', 'date'], 'required'], | |||
[['id', 'progress'], 'integer'], | |||
[['description'], 'string'], | |||
[['date', 'date_delivery'], 'safe'], | |||
[['time_estimate'], 'number'], | |||
[['subject', 'status', 'type'], 'string', 'max' => 255], | |||
]; | |||
} | |||
/* | |||
* Relations | |||
*/ | |||
public function getDevelopmentPriority() | |||
{ | |||
return $this->hasMany( | |||
DevelopmentPriorityModel::className(), | |||
['id_development' => 'id']) | |||
->with('producer'); | |||
} | |||
public function getDevelopmentPriorityCurrentProducer() | |||
{ | |||
return $this->hasOne( | |||
DevelopmentPriorityModel::className(), | |||
['id_development' => 'id']) | |||
->where(['id_producer' => GlobalParam::getCurrentProducerId()]) | |||
->with('producer'); | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'id' => 'ID', | |||
'subject' => 'Sujet', | |||
'description' => 'Description', | |||
'date' => 'Date', | |||
'progress' => 'Avancement', | |||
'status' => 'Statut', | |||
'time_estimate' => 'Estimation temps', | |||
'type' => 'Type', | |||
'date_delivery' => 'Date de livraison' | |||
]; | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function getDefaultOptionsSearch() { | |||
return [ | |||
'with' => ['developmentPriority', 'developmentPriorityCurrentProducer'], | |||
'join_with' => [], | |||
'orderby' => 'date DESC', | |||
'attribute_id_producer' => '' | |||
] ; | |||
} | |||
/** | |||
* Définit une date de livraison. | |||
* | |||
* @param string $date | |||
*/ | |||
public function setDateDelivery($date = '') | |||
{ | |||
if (strlen($date)) { | |||
$this->date_delivery = $date; | |||
} | |||
if (strlen($this->date_delivery)) { | |||
$this->date_delivery = date('Y-m-d', strtotime($this->date_delivery)); | |||
} | |||
} | |||
} |
@@ -1,149 +0,0 @@ | |||
<?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\Development\DevelopmentPriority; | |||
use common\logic\Producer\Producer\Producer; | |||
use common\components\ActiveRecordCommon ; | |||
/** | |||
* This is the model class for table "development_priority". | |||
*/ | |||
class DevelopmentPriority extends ActiveRecordCommon | |||
{ | |||
const PRIORITY_HIGH = 'high'; | |||
const PRIORITY_NORMAL = 'normal'; | |||
const PRIORITY_LOW = 'low'; | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public static function tableName() | |||
{ | |||
return 'development_priority'; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function rules() | |||
{ | |||
return [ | |||
[['id_producer', 'id_development'], 'required'], | |||
[['id_producer', 'id_development'], 'integer'], | |||
[['priority'], 'string'], | |||
]; | |||
} | |||
/* | |||
* Relations | |||
*/ | |||
public function getProducer() | |||
{ | |||
return $this->hasOne(Producer::class, ['id' => 'id_producer']); | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'id_producer' => 'Producteur', | |||
'id_development' => 'Développement', | |||
'priority' => 'Priorité' | |||
]; | |||
} | |||
/** | |||
* Retourne les options de base nécessaires à la fonction de recherche. | |||
* | |||
* @return array | |||
*/ | |||
public static function getDefaultOptionsSearch() { | |||
return [ | |||
'with' => [], | |||
'join_with' => [], | |||
'orderby' => '', | |||
'attribute_id_producer' => 'development_priority.id_producer' | |||
] ; | |||
} | |||
/** | |||
* Retourne la priorité. | |||
* | |||
* @return string | |||
*/ | |||
public function getStrPriority() | |||
{ | |||
switch ($this->priority) { | |||
case self::PRIORITY_LOW : return 'Basse'; | |||
break; | |||
case self::PRIORITY_NORMAL : return 'Normale'; | |||
break; | |||
case self::PRIORITY_HIGH : return 'Haute'; | |||
break; | |||
default: return 'Non définie'; | |||
break; | |||
} | |||
} | |||
/** | |||
* Retourne la classe CSS du bouton servant à définir la priorité. | |||
* | |||
* @return string | |||
*/ | |||
public function getClassCssStyleButton() | |||
{ | |||
$styleButton = 'default'; | |||
if ($this->priority == DevelopmentPriorityModel::PRIORITY_LOW) { | |||
$styleButton = 'info'; | |||
} | |||
elseif ($this->priority == DevelopmentPriorityModel::PRIORITY_NORMAL) { | |||
$styleButton = 'warning'; | |||
} | |||
elseif ($this->priority == DevelopmentPriorityModel::PRIORITY_HIGH) { | |||
$styleButton = 'danger'; | |||
} | |||
return $styleButton; | |||
} | |||
} |
@@ -43,11 +43,11 @@ use common\logic\Distribution\PointSaleDistribution\Model\PointSaleDistribution; | |||
use common\logic\Distribution\ProductDistribution\Model\ProductDistribution; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\Producer\Producer\Model\Producer; | |||
use common\logic\Subscription\Subscription\Event\SubscriptionEventSubscriber; | |||
use common\logic\Subscription\Subscription\Event\DistributionObserver; | |||
class Distribution extends ActiveRecordCommon | |||
{ | |||
const EVENT_ACTIVE = 'distribution.active'; | |||
const EVENT_ACTIVE = 'distribution.event.active'; | |||
/** | |||
* @inheritdoc | |||
@@ -81,15 +81,6 @@ class Distribution extends ActiveRecordCommon | |||
]; | |||
} | |||
public function init() | |||
{ | |||
parent::init(); | |||
$this->on(Distribution::EVENT_ACTIVE, function($event) { | |||
SubscriptionEventSubscriber::onActiveDistribution($event->distribution); | |||
}); | |||
} | |||
/* | |||
* Relations | |||
*/ |
@@ -185,9 +185,10 @@ class DistributionBuilder extends AbstractBuilder | |||
// active | |||
public function activeDistribution(Distribution $distribution, bool $active = true): void | |||
{ | |||
$this->pointSaleDistributionBuilder->createAllPointSaleDistributions($distribution, true); | |||
$distribution->active = (int) $active; | |||
$this->saveUpdate($distribution); | |||
$this->update($distribution); | |||
$this->pointSaleDistributionBuilder->createAllPointSaleDistributions($distribution, true); | |||
if ($active) { | |||
$distributionActiveEvent = new DistributionActiveEvent(); |
@@ -0,0 +1,8 @@ | |||
<?php | |||
namespace common\logic; | |||
interface GeneratorInterface | |||
{ | |||
} |
@@ -13,7 +13,6 @@ use common\logic\Distribution\Distribution\Service\DistributionSolver; | |||
use common\logic\Document\Document\Model\Document; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\Order\Order\Repository\OrderRepository; | |||
use common\logic\Order\OrderStatusHistory\Service\OrderStatusHistoryBuilder; | |||
use common\logic\Order\ProductOrder\Model\ProductOrder; | |||
use common\logic\Order\ProductOrder\Service\ProductOrderBuilder; | |||
use common\logic\Order\ProductOrder\Service\ProductOrderSolver; | |||
@@ -43,7 +42,6 @@ class OrderBuilder extends AbstractBuilder | |||
protected ProducerRepository $producerRepository; | |||
protected CreditHistoryBuilder $creditHistoryBuilder; | |||
protected ProductOrderBuilder $productOrderBuilder; | |||
protected OrderStatusHistoryBuilder $orderStatusHistoryBuilder; | |||
protected OrderRepository $orderRepository; | |||
protected DistributionRepository $distributionRepository; | |||
protected SubscriptionBuilder $subscriptionBuilder; | |||
@@ -65,7 +63,6 @@ class OrderBuilder extends AbstractBuilder | |||
$this->producerRepository = $this->loadService(ProducerRepository::class); | |||
$this->creditHistoryBuilder = $this->loadService(CreditHistoryBuilder::class); | |||
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); | |||
$this->orderStatusHistoryBuilder = $this->loadService(OrderStatusHistoryBuilder::class); | |||
$this->orderRepository = $this->loadService(OrderRepository::class); | |||
$this->distributionRepository = $this->loadService(DistributionRepository::class); | |||
$this->subscriptionBuilder = $this->loadService(SubscriptionBuilder::class); | |||
@@ -107,7 +104,6 @@ class OrderBuilder extends AbstractBuilder | |||
/** | |||
* Ajoute l'abonnement' pour une date donnée. | |||
*/ | |||
// add | |||
public function createOrderFromSubscription(Subscription $subscription, string $date, bool $force = false): ?Order | |||
{ | |||
$now = date('Y-m-d'); | |||
@@ -132,8 +128,6 @@ class OrderBuilder extends AbstractBuilder | |||
/** | |||
* Ajoute les commandes pour une date donnée à partir des abonnements. | |||
*/ | |||
// addAll | |||
// createAllFromSubscriptions | |||
public function createAllOrdersFromSubscriptions(string $date, bool $force = false): array | |||
{ | |||
$orderArray = []; | |||
@@ -152,7 +146,6 @@ class OrderBuilder extends AbstractBuilder | |||
return $orderArray; | |||
} | |||
// updateIncomingDistributions | |||
public function updateOrdersIncomingDistributionsFromSubscription(Subscription $subscription, $update = false): array | |||
{ | |||
$orderArray = []; | |||
@@ -254,7 +247,6 @@ class OrderBuilder extends AbstractBuilder | |||
return $productsAdd; | |||
} | |||
// updateFromSubscription | |||
public function updateOrderFromSubscription(Order $order, Subscription $subscription): void | |||
{ | |||
$this->initOrderBaseFromSubscription($order, $subscription); | |||
@@ -314,7 +306,6 @@ class OrderBuilder extends AbstractBuilder | |||
$order->tiller_synchronization = $order->auto_payment; | |||
} | |||
// addUserPointSale | |||
public function createUserPointSale(Order $order): void | |||
{ | |||
if ($order->user) { | |||
@@ -322,7 +313,6 @@ class OrderBuilder extends AbstractBuilder | |||
} | |||
} | |||
// initCommentPointSale | |||
public function initOrderCommentPointSale(Order $order): void | |||
{ | |||
if ($order->user && $order->pointSale) { | |||
@@ -392,7 +382,6 @@ class OrderBuilder extends AbstractBuilder | |||
$this->addProductOrderVat($order, $typeTotal, $price * $productOrder->quantity, $productOrder->taxRate, $taxCalculationMethod); | |||
} | |||
// addVat | |||
public function addProductOrderVat( | |||
Order $order, | |||
string $typeTotal, | |||
@@ -436,7 +425,6 @@ class OrderBuilder extends AbstractBuilder | |||
} | |||
} | |||
// delete | |||
public function deleteOrder(Order $order, bool $force = false): bool | |||
{ | |||
$this->initOrder($order); | |||
@@ -504,8 +492,6 @@ class OrderBuilder extends AbstractBuilder | |||
} | |||
} | |||
// setTillerSynchronization | |||
// updateTillerSynchronization | |||
public function updateOrderTillerSynchronization(Order $order, int $synchroTiller = null): void | |||
{ | |||
if (!is_null($synchroTiller)) { | |||
@@ -526,7 +512,6 @@ class OrderBuilder extends AbstractBuilder | |||
/** | |||
* Changement de statut d'une commande. | |||
*/ | |||
// changeOrderStatus | |||
public function updateOrderStatus(Order $order, string $newStatus, string $origin): void | |||
{ | |||
$orderStatusArray = GlobalParam::get('orderStatus'); | |||
@@ -534,7 +519,6 @@ class OrderBuilder extends AbstractBuilder | |||
switch ($newStatus) { | |||
case 'new-order' : | |||
//$this->orderStatusHistoryBuilder->createOrderStatusHistory($order, $userCurrent, $newStatus, $origin); | |||
$order->status = $newStatus; | |||
$order->save(); | |||
break; | |||
@@ -546,7 +530,6 @@ class OrderBuilder extends AbstractBuilder | |||
case 'refunded': | |||
case 'cancel': | |||
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) { | |||
//$this->orderStatusHistoryBuilder->createOrderStatusHistory($order, $userCurrent, $newStatus, $origin); | |||
$order->status = $newStatus; | |||
$order->save(); | |||
} |
@@ -1,72 +0,0 @@ | |||
<?php | |||
namespace common\logic\Order\OrderStatusHistory\Model; | |||
use common\components\ActiveRecordCommon; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\User\User\Model\User; | |||
/** | |||
* This is the model class for table "order_status_history". | |||
*/ | |||
class OrderStatusHistory extends ActiveRecordCommon | |||
{ | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public static function tableName() | |||
{ | |||
return 'order_status_history'; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function rules() | |||
{ | |||
return [ | |||
[['id_order', 'status', 'id_user', 'date', 'origin'], 'required'], | |||
[['id_order', 'id_user',], 'integer'], | |||
[['date'], 'safe'], | |||
]; | |||
} | |||
/** | |||
* @inheritdoc | |||
*/ | |||
public function attributeLabels() | |||
{ | |||
return [ | |||
'id' => 'ID', | |||
'id_order' => 'Commande', | |||
'id_user' => 'Utilisateur', | |||
'status' => 'Statut', | |||
'origin' => 'Origine', | |||
'date' => 'Date', | |||
]; | |||
} | |||
/* | |||
* Relations | |||
*/ | |||
public function getOrder() | |||
{ | |||
return $this->hasOne(Order::class, ['id' => 'id_order']); | |||
} | |||
public function populateOrder(Order $order): void | |||
{ | |||
$this->populateFieldObject('id_order', 'order', $order); | |||
} | |||
public function getUser() | |||
{ | |||
return $this->hasOne(User::class, ['id' => 'id_user']); | |||
} | |||
public function populateUser(User $user): void | |||
{ | |||
$this->populateFieldObject('id_user', 'user', $user); | |||
} | |||
} |
@@ -1,25 +0,0 @@ | |||
<?php | |||
namespace common\logic\Order\OrderStatusHistory\Repository; | |||
use common\logic\AbstractRepository; | |||
class OrderStatusHistoryRepository extends AbstractRepository | |||
{ | |||
protected OrderStatusHistoryRepositoryQuery $query; | |||
public function loadDependencies(): void | |||
{ | |||
$this->loadQuery(OrderStatusHistoryRepositoryQuery::class); | |||
} | |||
public function getDefaultOptionsSearch(): array | |||
{ | |||
return [ | |||
self::WITH => [], | |||
self::JOIN_WITH => ['order', 'orderStatus'], | |||
self::ORDER_BY => 'date ASC', | |||
self::ATTRIBUTE_ID_PRODUCER => '' | |||
]; | |||
} | |||
} |
@@ -1,18 +0,0 @@ | |||
<?php | |||
namespace common\logic\Order\OrderStatusHistory\Repository; | |||
use common\logic\AbstractRepositoryQuery; | |||
use common\logic\Order\OrderStatusHistory\Model\OrderStatusHistory; | |||
use common\logic\Order\OrderStatusHistory\Service\OrderStatusHistoryDefinition; | |||
use yii\db\ActiveQuery; | |||
class OrderStatusHistoryRepositoryQuery extends AbstractRepositoryQuery | |||
{ | |||
protected OrderStatusHistoryDefinition $definition; | |||
public function loadDependencies(): void | |||
{ | |||
$this->loadDefinition(OrderStatusHistoryDefinition::class); | |||
} | |||
} |
@@ -1,39 +0,0 @@ | |||
<?php | |||
namespace common\logic\Order\OrderStatusHistory\Service; | |||
use common\logic\AbstractBuilder; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\Order\OrderStatusHistory\Model\OrderStatusHistory; | |||
use common\logic\User\User\Model\User; | |||
use common\logic\User\User\Service\UserSolver; | |||
class OrderStatusHistoryBuilder extends AbstractBuilder | |||
{ | |||
protected UserSolver $userSolver; | |||
public function loadDependencies(): void | |||
{ | |||
$this->userSolver = $this->loadService(UserSolver::class); | |||
} | |||
public function instanciateOrderStatusHistory(Order $order, User $user, string $status, string $origin): OrderStatusHistory | |||
{ | |||
$orderStatusHistory = new OrderStatusHistory(); | |||
$orderStatusHistory->populateOrder($order); | |||
$orderStatusHistory->populateUser($user); | |||
$orderStatusHistory->status = $status; | |||
$orderStatusHistory->origin = $origin; | |||
$orderStatusHistory->date = date('Y-m-d H:i:s'); | |||
return $orderStatusHistory; | |||
} | |||
public function createOrderStatusHistory(Order $order, User $user, string $status, string $origin): OrderStatusHistory | |||
{ | |||
$orderStatusHistory = $this->instanciateOrderStatusHistory($order, $user, $status, $origin); | |||
$this->saveCreate($orderStatusHistory); | |||
return $orderStatusHistory; | |||
} | |||
} |
@@ -1,14 +0,0 @@ | |||
<?php | |||
namespace common\logic\Order\OrderStatusHistory\Service; | |||
use common\logic\AbstractDefinition; | |||
use common\logic\Order\OrderStatusHistory\Model\OrderStatusHistory; | |||
class OrderStatusHistoryDefinition extends AbstractDefinition | |||
{ | |||
public function getEntityFqcn(): string | |||
{ | |||
return OrderStatusHistory::class; | |||
} | |||
} |
@@ -1,35 +0,0 @@ | |||
<?php | |||
namespace common\logic\Order\OrderStatusHistory\Wrapper; | |||
use common\logic\AbstractContainer; | |||
use common\logic\Order\OrderStatusHistory\Repository\OrderStatusHistoryRepository; | |||
use common\logic\Order\OrderStatusHistory\Service\OrderStatusHistoryBuilder; | |||
use common\logic\Order\OrderStatusHistory\Service\OrderStatusHistoryDefinition; | |||
class OrderStatusHistoryContainer extends AbstractContainer | |||
{ | |||
public function getServices(): array | |||
{ | |||
return [ | |||
OrderStatusHistoryDefinition::class, | |||
OrderStatusHistoryRepository::class, | |||
OrderStatusHistoryBuilder::class | |||
]; | |||
} | |||
public function getDefinition(): OrderStatusHistoryDefinition | |||
{ | |||
return OrderStatusHistoryDefinition::getInstance(); | |||
} | |||
public function getRepository(): OrderStatusHistoryRepository | |||
{ | |||
return OrderStatusHistoryRepository::getInstance(); | |||
} | |||
public function getBuilder(): OrderStatusHistoryBuilder | |||
{ | |||
return OrderStatusHistoryBuilder::getInstance(); | |||
} | |||
} |
@@ -1,21 +0,0 @@ | |||
<?php | |||
namespace common\logic\Order\OrderStatusHistory\Wrapper; | |||
use common\logic\AbstractManager; | |||
use common\logic\Order\OrderStatusHistory\Repository\OrderStatusHistoryRepository; | |||
use common\logic\Order\OrderStatusHistory\Service\OrderStatusHistoryBuilder; | |||
use common\logic\Order\OrderStatusHistory\Service\OrderStatusHistoryDefinition; | |||
/** | |||
* @mixin OrderStatusHistoryDefinition | |||
* @mixin OrderStatusHistoryRepository | |||
* @mixin OrderStatusHistoryBuilder | |||
*/ | |||
class OrderStatusHistoryManager extends AbstractManager | |||
{ | |||
public function getContainerFqcn(): string | |||
{ | |||
return OrderStatusHistoryContainer::class; | |||
} | |||
} |
@@ -218,7 +218,10 @@ class Producer extends ActiveRecordCommon | |||
'option_tax_calculation_method', | |||
'latest_version_opendistrib', | |||
'option_csv_separator', | |||
'option_point_sale_wording' | |||
'option_point_sale_wording', | |||
'option_testimony', | |||
'contact_email', | |||
'admin_comment', | |||
], | |||
'string' | |||
], | |||
@@ -284,7 +287,8 @@ class Producer extends ActiveRecordCommon | |||
'credit_limit', | |||
'option_billing_permanent_transfer_amount', | |||
'latitude', | |||
'longitude' | |||
'longitude', | |||
'option_time_saved' | |||
], 'double'], | |||
[ | |||
'free_price', | |||
@@ -405,7 +409,11 @@ class Producer extends ActiveRecordCommon | |||
'option_billing_permanent_transfer_amount' => 'Virement permanent : montant', | |||
'option_point_sale_wording' => 'Libellé points de vente', | |||
'latitude' => 'Latitude', | |||
'longitude' => 'Longitude' | |||
'longitude' => 'Longitude', | |||
'option_testimony' => 'Témoignage', | |||
'option_time_saved' => 'Temps gagné / semaine', | |||
'contact_email' => 'Email de contact', | |||
'admin_comment' => 'Commentaire' | |||
]; | |||
} | |||
@@ -193,7 +193,7 @@ class ProducerRepository extends AbstractRepository | |||
if ($isBold) $text .= '<strong>'; | |||
$text .= $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, true); | |||
if ($isBold) $text .= '</strong>'; | |||
$text .= ' / ' . Price::format($turnover, 0); | |||
$text .= ' (' . Price::format($turnover, 0). ' CA)'; | |||
$text .= '<br />'; | |||
$sumInvoicePrice += $this->producerPriceRangeRepository->getAmountToBeBilledByTurnover($turnover, false); | |||
@@ -205,7 +205,7 @@ class ProducerRepository extends AbstractRepository | |||
} | |||
} | |||
if($numberOfMonths > 1) { | |||
if($numberOfMonths > 1 && $sumInvoicePrice > 0) { | |||
$text .= '<br />Total : <strong>'.Price::format($sumInvoicePrice, 0).'</strong>'; | |||
} | |||
@@ -299,4 +299,40 @@ class ProducerRepository extends AbstractRepository | |||
{ | |||
return $this->createQuery()->find(); | |||
} | |||
public function findProducersWithTestimonials(): array | |||
{ | |||
return $this->queryProducersActive() | |||
->filterHasOptionTestimony() | |||
->find(); | |||
} | |||
public function findProducersWithTimeSaved(): array | |||
{ | |||
return $this->queryProducersActive() | |||
->filterHasOptionTimeSaved() | |||
->find(); | |||
} | |||
public function countProducersWithTimeSaved(): int | |||
{ | |||
return count($this->findProducersWithTimeSaved()); | |||
} | |||
public function getTimeSavedByProducersAverage(): int | |||
{ | |||
$producersWithTimeSavedArray = $this->findProducersWithTimeSaved(); | |||
$countProducersWithOptionTimeSaved = count($producersWithTimeSavedArray); | |||
if($countProducersWithOptionTimeSaved) { | |||
$sumTimeSaved = 0; | |||
foreach($producersWithTimeSavedArray as $producerWithTimeSaved) { | |||
$sumTimeSaved += $producerWithTimeSaved->option_time_saved; | |||
} | |||
return round($sumTimeSaved / $countProducersWithOptionTimeSaved); | |||
} | |||
return 0; | |||
} | |||
} |
@@ -33,4 +33,16 @@ class ProducerRepositoryQuery extends AbstractRepositoryQuery | |||
$this->andWhere('name LIKE \'Démo\''); | |||
return $this; | |||
} | |||
public function filterHasOptionTestimony(): self | |||
{ | |||
$this->andWhere('option_testimony IS NOT NULL AND option_testimony != ""'); | |||
return $this; | |||
} | |||
public function filterHasOptionTimeSaved(): self | |||
{ | |||
$this->andWhere('producer.option_time_saved > 0'); | |||
return $this; | |||
} | |||
} |
@@ -178,7 +178,7 @@ class Product extends ActiveRecordCommon | |||
public function afterFind() | |||
{ | |||
if ($this->taxRate == null) { | |||
$producer = Producer::searchOne(['id' => GlobalParam::getCurrentProducerId()]); | |||
$producer = Producer::searchOne(['id' => $this->id_producer]); | |||
if ($producer) { | |||
$this->populateRelation('taxRate', $producer->taxRate); | |||
} |
@@ -0,0 +1,26 @@ | |||
<?php | |||
namespace common\logic\Subscription\Subscription\Event; | |||
use common\logic\Distribution\Distribution\Event\DistributionActiveEvent; | |||
use common\logic\Distribution\Distribution\Model\Distribution; | |||
use common\logic\Order\Order\Wrapper\OrderManager; | |||
use justcoded\yii2\eventlistener\observers\Observer; | |||
class DistributionObserver extends Observer | |||
{ | |||
public function events() | |||
{ | |||
return [ | |||
Distribution::EVENT_ACTIVE => 'onDistributionActive' | |||
]; | |||
} | |||
public static function onDistributionActive(DistributionActiveEvent $event): void | |||
{ | |||
$distribution = $event->distribution; | |||
$orderManager = OrderManager::getInstance(); | |||
$orderManager->createAllOrdersFromSubscriptions($distribution->date); | |||
} | |||
} |
@@ -1,15 +0,0 @@ | |||
<?php | |||
namespace common\logic\Subscription\Subscription\Event; | |||
use common\logic\Distribution\Distribution\Model\Distribution; | |||
use common\logic\Order\Order\Wrapper\OrderManager; | |||
class SubscriptionEventSubscriber | |||
{ | |||
public static function onActiveDistribution(Distribution $distribution): void | |||
{ | |||
$orderManager = OrderManager::getInstance(); | |||
$orderManager->createAllOrdersFromSubscriptions($distribution->date); | |||
} | |||
} |
@@ -39,7 +39,10 @@ | |||
namespace common\logic\Ticket\Ticket\Model; | |||
use common\components\ActiveRecordCommon; | |||
use common\events\EntityManagerEvent; | |||
use common\logic\Distribution\Distribution\Model\Distribution; | |||
use common\logic\Producer\Producer\Model\Producer; | |||
use common\logic\Subscription\Subscription\Event\DistributionObserver; | |||
use common\logic\Ticket\TicketMessage\Model\TicketMessage; | |||
use common\logic\Ticket\TicketUser\Model\TicketUser; | |||
use common\logic\User\User\Model\User; |
@@ -35,7 +35,7 @@ class TicketBuilder extends AbstractBuilder | |||
public function createTicket(Producer $producer, User $user): Ticket | |||
{ | |||
$ticket = $this->instanciateTicket($producer, $user); | |||
$this->saveCreate($ticket); | |||
$this->create($ticket); | |||
return $ticket; | |||
} | |||
@@ -43,7 +43,7 @@ class TicketBuilder extends AbstractBuilder | |||
public function updateTicketStatus(Ticket $ticket, string $status) | |||
{ | |||
$ticket->status = $status; | |||
$this->saveUpdate($ticket); | |||
$this->update($ticket); | |||
$this->updateTicketUpdatedAt($ticket); | |||
} | |||
@@ -61,13 +61,13 @@ class TicketBuilder extends AbstractBuilder | |||
public function updateTicketUpdatedAt(Ticket $ticket) | |||
{ | |||
$ticket->updated_at = date('Y-m-d H:i:s'); | |||
$this->saveUpdate($ticket); | |||
$this->update($ticket); | |||
} | |||
public function createTicketMessage(TicketMessage $ticketMessage) | |||
{ | |||
$this->updateTicketUpdatedAt($ticketMessage->ticket); | |||
return $this->saveCreate($ticketMessage); | |||
return $this->create($ticketMessage); | |||
} | |||
public function viewTicket(Ticket $ticket, User $user) |
@@ -1,12 +0,0 @@ | |||
<?php | |||
namespace common\logic\User\CreditHistory\Event; | |||
use common\logic\Distribution\Distribution\Model\Distribution; | |||
use common\logic\User\CreditHistory\Model\CreditHistory; | |||
use yii\base\Event; | |||
class CreditHistoryCreateEvent extends Event | |||
{ | |||
public CreditHistory $creditHistory; | |||
} |
@@ -47,8 +47,6 @@ use yii\db\ActiveQuery; | |||
class CreditHistory extends ActiveRecordCommon | |||
{ | |||
const EVENT_CREATE = 'creditHistory.create'; | |||
const TYPE_INITIAL_CREDIT = 'initial-credit'; | |||
const TYPE_CREDIT = 'credit'; | |||
const TYPE_PAYMENT = 'payment'; | |||
@@ -97,15 +95,6 @@ class CreditHistory extends ActiveRecordCommon | |||
]; | |||
} | |||
public function init() | |||
{ | |||
$this->on(CreditHistory::EVENT_CREATE, function($event) { | |||
UserProducerEventSubscriber::onCreateCreditHistory($event); | |||
}); | |||
parent::init(); | |||
} | |||
/* | |||
* Relations | |||
*/ |
@@ -6,7 +6,6 @@ use common\logic\AbstractBuilder; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\Order\Order\Service\OrderSolver; | |||
use common\logic\Producer\Producer\Model\Producer; | |||
use common\logic\User\CreditHistory\Event\CreditHistoryCreateEvent; | |||
use common\logic\User\CreditHistory\Model\CreditHistory; | |||
use common\logic\User\User\Model\User; | |||
use yii\base\Event; | |||
@@ -68,11 +67,7 @@ class CreditHistoryBuilder extends AbstractBuilder | |||
$creditHistory = $this->instanciateCreditHistory($type, $amount, $producer, $user, $userAction, $meanPayment, $order); | |||
$creditHistory->setComment($creditHistory->getComment() . $this->orderSolver->getCreditHistoryComment($creditHistory)); | |||
$this->saveCreate($creditHistory); | |||
$creditHistoryCreateEvent = new CreditHistoryCreateEvent(); | |||
$creditHistoryCreateEvent->creditHistory = $creditHistory; | |||
$creditHistory->trigger(CreditHistory::EVENT_CREATE, $creditHistoryCreateEvent); | |||
$this->create($creditHistory); | |||
return $creditHistory; | |||
} |
@@ -0,0 +1,132 @@ | |||
<?php | |||
namespace common\logic\User\CreditHistory\Service; | |||
use common\helpers\MeanPayment; | |||
use common\logic\AbstractService; | |||
use common\logic\Order\Order\Model\Order; | |||
use common\logic\Order\Order\Service\OrderSolver; | |||
use common\logic\Producer\Producer\Repository\ProducerRepository; | |||
use common\logic\User\CreditHistory\Model\CreditHistory; | |||
use common\logic\User\User\Model\User; | |||
use common\logic\User\User\Repository\UserRepository; | |||
use common\logic\UtilsInterface; | |||
use yii\base\ErrorException; | |||
class CreditUtils extends AbstractService implements UtilsInterface | |||
{ | |||
protected CreditHistoryBuilder $creditHistoryBuilder; | |||
protected OrderSolver $orderSolver; | |||
protected ProducerRepository $producerRepository; | |||
protected UserRepository $userRepository; | |||
public function loadDependencies(): void | |||
{ | |||
$this->creditHistoryBuilder = $this->loadService(CreditHistoryBuilder::class); | |||
$this->orderSolver = $this->loadService(OrderSolver::class); | |||
$this->producerRepository = $this->loadService(ProducerRepository::class); | |||
$this->userRepository = $this->loadService(UserRepository::class); | |||
} | |||
public function creditUser(User $user, float $amount, string $meanPayment, User $userAction): void | |||
{ | |||
$this->creditHistoryBuilder->createCreditHistory( | |||
CreditHistory::TYPE_CREDIT, | |||
$amount, | |||
$this->getProducerContext(), | |||
$user, | |||
$userAction, | |||
$meanPayment | |||
); | |||
} | |||
public function debitUser(User $user, float $amount, string $meanPayment, User $userAction): void | |||
{ | |||
$this->creditHistoryBuilder->createCreditHistory( | |||
CreditHistory::TYPE_DEBIT, | |||
$amount, | |||
$this->getProducerContext(), | |||
$user, | |||
$userAction, | |||
$meanPayment | |||
); | |||
} | |||
public function creditOrDebitUser(string $type, User $user, float $amount, string $meanPayment, User $userAction): void | |||
{ | |||
if($type == CreditHistory::TYPE_CREDIT) { | |||
$this->creditUser($user, $amount, $meanPayment, $userAction); | |||
} | |||
elseif($type == CreditHistory::TYPE_DEBIT) { | |||
$this->debitUser($user, $amount, $meanPayment, $userAction); | |||
} | |||
else { | |||
throw new ErrorException('$type a une valeur incorrect'); | |||
} | |||
} | |||
public function payOrder(Order $order, User $userAction, bool $checkCreditLimit): void | |||
{ | |||
$amountRemaining = $this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_REMAINING); | |||
if($checkCreditLimit) { | |||
$creditLimit = $this->producerRepository->getConfig('credit_limit'); | |||
$creditUser = $this->userRepository->getCredit($order->user); | |||
if (!is_null($creditLimit) && $amountRemaining > $creditUser - $creditLimit) { | |||
$amountRemaining = $creditUser - $creditLimit; | |||
} | |||
} | |||
if($amountRemaining > 0) { | |||
$this->creditHistoryBuilder->createCreditHistory( | |||
CreditHistory::TYPE_PAYMENT, | |||
$amountRemaining, | |||
$this->getProducerContext(), | |||
$order->user, | |||
$userAction, | |||
MeanPayment::CREDIT, | |||
$order | |||
); | |||
} | |||
} | |||
public function refundOrder(Order $order, User $userAction): void | |||
{ | |||
$this->creditHistoryBuilder->createCreditHistory( | |||
CreditHistory::TYPE_REFUND, | |||
$this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_PAID), | |||
$this->getProducerContext(), | |||
$order->user, | |||
$userAction, | |||
MeanPayment::CREDIT, | |||
$order | |||
); | |||
} | |||
public function refundSurplusOrder(Order $order, User $userAction): void | |||
{ | |||
$this->creditHistoryBuilder->createCreditHistory( | |||
CreditHistory::TYPE_REFUND, | |||
$this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_SURPLUS), | |||
$this->getProducerContext(), | |||
$order->user, | |||
$userAction, | |||
MeanPayment::CREDIT, | |||
$order | |||
); | |||
} | |||
public function payOrRefundOrder(string $type, Order $order, User $userAction, bool $checkCreditLimit = false): void | |||
{ | |||
if($type == CreditHistory::TYPE_PAYMENT) { | |||
$this->payOrder($order, $userAction, $checkCreditLimit); | |||
} | |||
elseif($type == CreditHistory::TYPE_REFUND) { | |||
$this->refundOrder($order, $userAction); | |||
} | |||
else { | |||
throw new ErrorException('$type a une valeur incorrect'); | |||
} | |||
} | |||
} |
@@ -7,6 +7,7 @@ use common\logic\User\CreditHistory\Repository\CreditHistoryRepository; | |||
use common\logic\User\CreditHistory\Service\CreditHistoryBuilder; | |||
use common\logic\User\CreditHistory\Service\CreditHistoryDefinition; | |||
use common\logic\User\CreditHistory\Service\CreditHistorySolver; | |||
use common\logic\User\CreditHistory\Service\CreditUtils; | |||
class CreditHistoryContainer extends AbstractContainer | |||
{ | |||
@@ -17,6 +18,7 @@ class CreditHistoryContainer extends AbstractContainer | |||
CreditHistorySolver::class, | |||
CreditHistoryBuilder::class, | |||
CreditHistoryRepository::class, | |||
CreditUtils::class, | |||
]; | |||
} | |||
@@ -39,4 +41,9 @@ class CreditHistoryContainer extends AbstractContainer | |||
{ | |||
return CreditHistoryRepository::getInstance(); | |||
} | |||
public function getCreditUtils(): CreditUtils | |||
{ | |||
return CreditUtils::getInstance(); | |||
} | |||
} |
@@ -7,12 +7,14 @@ use common\logic\User\CreditHistory\Repository\CreditHistoryRepository; | |||
use common\logic\User\CreditHistory\Service\CreditHistoryBuilder; | |||
use common\logic\User\CreditHistory\Service\CreditHistoryDefinition; | |||
use common\logic\User\CreditHistory\Service\CreditHistorySolver; | |||
use common\logic\User\CreditHistory\Service\CreditUtils; | |||
/** | |||
* @mixin CreditHistoryDefinition | |||
* @mixin CreditHistorySolver | |||
* @mixin CreditHistoryRepository | |||
* @mixin CreditHistoryBuilder | |||
* @mixin CreditUtils | |||
*/ | |||
class CreditHistoryManager extends AbstractManager | |||
{ |
@@ -0,0 +1,17 @@ | |||
<?php | |||
namespace common\logic\User\User\Event; | |||
use common\logic\User\User\Wrapper\UserManager; | |||
use justcoded\yii2\eventlistener\observers\ActiveRecordObserver; | |||
use yii\db\AfterSaveEvent; | |||
class TicketObserver extends ActiveRecordObserver | |||
{ | |||
public function inserted(AfterSaveEvent $event) | |||
{ | |||
$ticket = $event->sender; | |||
$userManager = UserManager::getInstance(); | |||
$userManager->sendMailNewTicketAdmin($ticket); | |||
} | |||
} |
@@ -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 | |||
*/ | |||
@@ -224,4 +248,10 @@ class UserRepository extends AbstractRepository | |||
return count($results); | |||
} | |||
public function isActive(User $user) | |||
{ | |||
$userProducer = $this->userProducerRepository->findOneUserProducer($user); | |||
return $userProducer ? $userProducer->active : false; | |||
} | |||
} |
@@ -76,10 +76,25 @@ class UserBuilder extends AbstractBuilder | |||
$user->password_reset_token = null; | |||
} | |||
public function grantAccess(User $user): bool | |||
{ | |||
if($this->userRepository->isActive($user)) { | |||
$user->id_producer = $this->getProducerContextId(); | |||
$user->status = User::STATUS_PRODUCER; | |||
return $user->save(); | |||
} | |||
return false; | |||
} | |||
public function deleteAccess(User $user): bool | |||
{ | |||
$user->id_producer = 0; | |||
$user->status = User::STATUS_ACTIVE; | |||
return $user->save(); | |||
if($this->userRepository->isActive($user)) { | |||
$user->id_producer = null; | |||
$user->status = User::STATUS_ACTIVE; | |||
return $user->save(); | |||
} | |||
return false; | |||
} | |||
} |
@@ -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; | |||
} | |||
@@ -6,6 +6,7 @@ use common\helpers\GlobalParam; | |||
use common\helpers\Mailjet; | |||
use common\logic\AbstractService; | |||
use common\logic\Producer\Producer\Model\Producer; | |||
use common\logic\Ticket\Ticket\Model\Ticket; | |||
use common\logic\User\User\Model\User; | |||
use common\logic\UtilsInterface; | |||
@@ -38,7 +39,6 @@ class UserUtils extends AbstractService implements UtilsInterface | |||
/** | |||
* Envoie un email de bienvenue à l'utilisateur lors de son inscription | |||
* via le backend du site. | |||
* | |||
*/ | |||
public function sendMailWelcome(User $user, string $password): void | |||
{ | |||
@@ -54,4 +54,22 @@ class UserUtils extends AbstractService implements UtilsInterface | |||
->send(); | |||
} | |||
} | |||
public function sendMailNewTicketAdmin(Ticket $ticket) | |||
{ | |||
$adminEmail = \Yii::$app->params['adminEmail']; | |||
Mailjet::sendMail([ | |||
'from_email' => $adminEmail, | |||
'from_name' => 'Opendistrib', | |||
'to_email' => $adminEmail, | |||
'to_name' => 'Opendistrib', | |||
'subject' => '[Opendistrib] Nouveau ticket', | |||
'content_view_text' => '@common/mail/newTicketAdmin-text.php', | |||
'content_view_html' => '@common/mail/newTicketAdmin-html.php', | |||
'content_params' => [ | |||
'ticket' => $ticket, | |||
] | |||
]); | |||
} | |||
} |
@@ -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,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, | |||
]; | |||
} |
@@ -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 | |||
{ |
@@ -0,0 +1,18 @@ | |||
<?php | |||
namespace common\logic\User\UserProducer\Event; | |||
use common\logic\User\UserProducer\Wrapper\UserProducerManager; | |||
use justcoded\yii2\eventlistener\observers\ActiveRecordObserver; | |||
use yii\db\AfterSaveEvent; | |||
class CreditHistoryObserver extends ActiveRecordObserver | |||
{ | |||
public function inserted(AfterSaveEvent $event) | |||
{ | |||
$creditHistory = $event->sender; | |||
$userProducerManager = UserProducerManager::getInstance(); | |||
$userProducerManager->updateCredit($creditHistory); | |||
} | |||
} |
@@ -1,14 +0,0 @@ | |||
<?php | |||
namespace common\logic\User\UserProducer\Event; | |||
use common\logic\User\UserProducer\Wrapper\UserProducerManager; | |||
class UserProducerEventSubscriber | |||
{ | |||
public static function onCreateCreditHistory($event) | |||
{ | |||
$userProducerManager = UserProducerManager::getInstance(); | |||
$userProducerManager->updateCredit($event->creditHistory); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} | |||
@@ -111,21 +111,23 @@ class UserProducerBuilder extends AbstractBuilder | |||
$user = $userRepository->findOneUserById($creditHistory->id_user); | |||
$producer = $producerRepository->findOneProducerById($creditHistory->id_producer); | |||
\Yii::$app->mailer->compose( | |||
[ | |||
'html' => 'creditLimitReminder-html', | |||
'text' => 'creditLimitReminder-text' | |||
], | |||
[ | |||
'user' => $user, | |||
'producer' => $producer, | |||
'credit' => $newCredit | |||
] | |||
) | |||
->setTo($user->email) | |||
->setFrom(['contact@opendistrib.net' => 'Opendistrib']) | |||
->setSubject('[Opendistrib] Seuil limite de crédit dépassé') | |||
->send(); | |||
if($user && $user->email && strlen($user->email) > 0) { | |||
\Yii::$app->mailer->compose( | |||
[ | |||
'html' => 'creditLimitReminder-html', | |||
'text' => 'creditLimitReminder-text' | |||
], | |||
[ | |||
'user' => $user, | |||
'producer' => $producer, | |||
'credit' => $newCredit | |||
] | |||
) | |||
->setTo($user->email) | |||
->setFrom(['contact@opendistrib.net' => 'Opendistrib']) | |||
->setSubject('[Opendistrib] Seuil limite de crédit dépassé') | |||
->send(); | |||
} | |||
} | |||
} | |||
@@ -147,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) | |||
@@ -167,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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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, | |||
]; |
@@ -0,0 +1,46 @@ | |||
<?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; | |||
?> | |||
<p>Un nouveau ticket vient d'être ouvert par <strong><?= Html::encode($ticket->producer->name) ?></strong> : | |||
<a href="<?= Yii::$app->urlManagerBackend->createAbsoluteUrl(['support/view', 'id' => $ticket->id]) ?>"><?= Html::encode($ticket->subject) ?></a>.</p> | |||
@@ -0,0 +1,47 @@ | |||
<?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; | |||
?> | |||
Un nouveau ticket vient d'être ouvert par <?= Html::encode($ticket->producer->name) ?> : <?= Html::encode($ticket->subject) ?>. | |||
<?= Yii::$app->urlManagerBackend->createAbsoluteUrl(['support/view', 'id' => $ticket->id]) ?> | |||
@@ -1,45 +1,34 @@ | |||
<?php | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>25/10/2022</li> | |||
</ul> | |||
require_once dirname(__FILE__).'/_macros.php'; | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li>[Administration] Distributions > commandes : ajout ligne avec montant total et poids par point de vente</li> | |||
<li>[Administration] Distributions > formulaire commande : ajout champs prix HT</li> | |||
<li>[Administration] Produits, Utilisateurs, Statistiques et Documents : accès rapide en un clic</li> | |||
<li>[Administration] Produits > liste : possibilité de modifier directement le champs "actif"</li> | |||
<li>[Administration] Utilisateurs > commandes : ajout lien vers modification</li> | |||
<li> | |||
[Administration] Documents > modification : mise en évidence des prix incohérents par rapport à ceux définis au | |||
niveau des produits | |||
</li> | |||
<li>[Administration] Documents > liste : ajout champs "Envoyé"</li> | |||
<li>[Administration] Documents > factures > liste : filtre par utilisateur</li> | |||
<li>[Administration] Paramètres : tri et réagencement</li> | |||
<li>[Administration] Développement : page de suivi des versions du logiciel (liste des évolutions et correctifs)</li> | |||
<li>[Espace producteur] Formulaire de contact avec protection par captcha</li> | |||
</ul> | |||
version( | |||
'25/10/2022', | |||
[ | |||
"[Administration] Distributions > commandes : ajout ligne avec montant total et poids par point de vente", | |||
"[Administration] Distributions > formulaire commande : ajout champs prix HT", | |||
"[Administration] Produits, Utilisateurs, Statistiques et Documents : accès rapide en un clic", | |||
"[Administration] Produits > liste : possibilité de modifier directement le champs 'actif'", | |||
"[Administration] Utilisateurs > commandes : ajout lien vers modification", | |||
"[Administration] Documents > modification : mise en évidence des prix incohérents par rapport à ceux définis au niveau des produits", | |||
"[Administration] Documents > liste : ajout champs 'Envoyé'", | |||
"[Administration] Documents > factures > liste : filtre par utilisateur", | |||
"[Administration] Paramètres : tri et réagencement", | |||
"[Administration] Développement : page de suivi des versions du logiciel (liste des évolutions et correctifs)", | |||
"[Espace producteur] Formulaire de contact avec protection par captcha" | |||
], | |||
[ | |||
"[Administration] Produits > modification : prise en compte des prix spécifiques lors de la mise à jour automatique des commandes des distributions futures", | |||
"[Administration] Produits > prix spécifiques : prise en compte des prix par groupe d'utilisateur et point de vente", | |||
"[Administration] Utilisateurs > crédit : correctif champs 'Commentaire' trop long", | |||
"[Administration] Utilisateurs > liste : correctif nombre de commandes", | |||
"[Administration] Distributions > modification commande : correctif modification prix", | |||
"[Administration] Distributions > modification commande : adaptation changement du point de vente lors de la sélection d'un utilisateur", | |||
"[Administration] Haut de page : utilisateurs vides dans le bloc 'Utilisateurs au crédit négatif'", | |||
"[Administration] Abonnements : ne pas générer de commandes pour le jour même", | |||
"[Backend] Facture > créer : tri des utilisateurs par ordre alphabétique", | |||
"Correctif connexion personnes morales" | |||
] | |||
); | |||
<h4>Correctifs</h4> | |||
<ul> | |||
<li> | |||
[Administration] Produits > modification : prise en compte des prix spécifiques lors de la mise à jour automatique | |||
des commandes des distributions futures | |||
</li> | |||
<li> | |||
[Administration] Produits > prix spécifiques : prise en compte des prix par groupe d'utilisateur et point de vente | |||
</li> | |||
<li>[Administration] Utilisateurs > crédit : correctif champs "Commentaire" trop long</li> | |||
<li>[Administration] Utilisateurs > liste : correctif nombre de commandes</li> | |||
<li>[Administration] Distributions > modification commande : correctif modification prix</li> | |||
<li> | |||
[Administration] Distributions > modification commande : adaptation changement du point de vente lors de la | |||
sélection d'un utilisateur | |||
</li> | |||
<li>[Administration] Haut de page : utilisateurs vides dans le bloc "Utilisateurs au crédit négatif"</li> | |||
<li>[Administration] Abonnements : ne pas générer de commandes pour le jour même</li> | |||
<li>[Backend] Facture > créer : tri des utilisateurs par ordre alphabétique</li> | |||
<li>Correctif connexion personnes morales</li> | |||
</ul> | |||
?> |
@@ -1,17 +1,17 @@ | |||
<?php | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>08/11/2022</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li>[Administration] Documents > édition : liens vers les commandes associées</li> | |||
<li>[Administration] Distributions > édition commande : bouton de réinitialisation des prix facturés</li> | |||
</ul> | |||
version( | |||
'08/11/2022', | |||
[ | |||
"[Administration] Documents > édition : liens vers les commandes associées", | |||
"[Administration] Distributions > édition commande : bouton de réinitialisation des prix facturés" | |||
], | |||
[ | |||
"[Administration] Abonnements : suppression des commandes après la date de fin lors de l'arrêt d'un abonnement", | |||
"[Administration] Distributions > calendrier : amélioration chargement automatique des distributions (affichage pastilles vertes)" | |||
] | |||
); | |||
<h4>Maintenance</h4> | |||
<ul> | |||
<li>[Administration] Abonnements : suppression des commandes après la date de fin lors de l'arrêt d'un abonnement</li> | |||
<li>[Administration] Distributions > calendrier : amélioration chargement automatique des distributions (affichage pastilles vertes)</li> | |||
</ul> | |||
?> |
@@ -1,14 +1,17 @@ | |||
<?php | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>22/11/2022</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li>[Administration] Documents > factures : gestion des bons de livraison associés</li> | |||
<li>[Administration] Communiquer : possibilité de ne pas inclure la liste des produits dans le message</li> | |||
<li>[Administration] Paramètres : possibilité de configurer le séparateur CSV</li> | |||
<li>[Administration] Paramètres > paiement en ligne : montant minimum configurable</li> | |||
<li>[Administration] Développement : mise en avant des nouvelles versions et des informations de contact</li> | |||
</ul> | |||
version( | |||
'22/11/2022', | |||
[ | |||
"[Administration] Documents > factures : gestion des bons de livraison associés", | |||
"[Administration] Communiquer : possibilité de ne pas inclure la liste des produits dans le message", | |||
"[Administration] Paramètres : possibilité de configurer le séparateur CSV", | |||
"[Administration] Paramètres > paiement en ligne : montant minimum configurable", | |||
"[Administration] Développement : mise en avant des nouvelles versions et des informations de contact" | |||
], | |||
[] | |||
); | |||
?> |
@@ -1,11 +1,14 @@ | |||
<?php | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>06/12/2022</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li>[Administration] Listes d'utilisateurs : ordre alphabétique + champs de recherche rapide (commandes, abonnements, documents, points de vente)</li> | |||
<li>[Administration] Abonnements : comportement paiement automatique (déduit, oui, non)</li> | |||
</ul> | |||
version( | |||
'06/12/2022', | |||
[ | |||
"[Administration] Listes d'utilisateurs : ordre alphabétique + champs de recherche rapide (commandes, abonnements, documents, points de vente)", | |||
"[Administration] Abonnements : comportement paiement automatique (déduit, oui, non)" | |||
], | |||
[] | |||
); | |||
?> |
@@ -1,16 +1,16 @@ | |||
<?php | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>23/01/2023</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li>[Administration] Documents : possibilité de regénérer les PDF</li> | |||
</ul> | |||
version( | |||
'23/01/2023', | |||
[ | |||
"[Administration] Documents : possibilité de regénérer les PDF" | |||
], | |||
[ | |||
"[Administration] Documents > listes : optimisation chargement", | |||
"[Espace producteur] Commander : ajustement ordre des points de vente" | |||
] | |||
); | |||
<h4>Maintenance</h4> | |||
<ul> | |||
<li>[Administration] Documents > listes : optimisation chargement</li> | |||
<li>[Espace producteur] Commander : ajustement ordre des points de vente</li> | |||
</ul> | |||
?> |
@@ -1,19 +1,17 @@ | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>27/03/2023</li> | |||
</ul> | |||
<?php | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li> | |||
[Administration] Distributions > édition/création commande : bouton unique "Créer" ou "Modifier". | |||
La gestion du crédit est désormais automatiquement déduite du contexte (utilisateur, point de vente). | |||
</li> | |||
<li> | |||
[Administration] Paramètres : ajout d'une option pour configurer le libellé "Points de vente" affiché sur l'accueil | |||
et le tunnel de commande de l'espace producteur. | |||
</li> | |||
<li> | |||
[Administration] Export vers le logiciel Evoliz : ajout de la TVA + code classification vente | |||
</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
version( | |||
'27/03/2023', | |||
[ | |||
"[Administration] Distributions > édition/création commande : bouton unique 'Créer' ou 'Modifier'. | |||
La gestion du crédit est désormais automatiquement déduite du contexte (utilisateur, point de vente).", | |||
"[Administration] Paramètres : ajout d'une option pour configurer le libellé 'Points de vente' affiché sur l'accueil | |||
et le tunnel de commande de l'espace producteur.", | |||
"[Administration] Export vers le logiciel Evoliz : ajout de la TVA + code classification vente" | |||
], | |||
[] | |||
); | |||
?> |
@@ -1,21 +1,16 @@ | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>27/04/2023</li> | |||
</ul> | |||
<?php | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li> | |||
[Administration] Distributions > édition commande : possibilité de modifier les prix facturés | |||
</li> | |||
<li> | |||
[Administration] Produits > import prix : possibilité d'importer des prix sur base d'un fichier CSV | |||
</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
<h4>Maintenance</h4> | |||
<ul> | |||
<li> | |||
Logiciel de caisse Tiller : synchronisation des commandes partiellement payées | |||
</li> | |||
</ul> | |||
version( | |||
'27/04/2023', | |||
[ | |||
"[Administration] Distributions > édition commande : possibilité de modifier les prix facturés", | |||
"[Administration] Produits > import prix : possibilité d'importer des prix sur base d'un fichier CSV" | |||
], | |||
[ | |||
"Logiciel de caisse Tiller : synchronisation des commandes partiellement payées" | |||
] | |||
); | |||
?> |
@@ -1,14 +1,18 @@ | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>12/06/2023</li> | |||
</ul> | |||
<?php | |||
<h4>Maintenance</h4> | |||
<ul> | |||
<li>[Administration] Logiciel de caisse Tiller : synchroniser automatiquement les commandes payées avec le crédit</li> | |||
<li>[Administration] Correction affichage des points de vente supprimés</li> | |||
<li>[Administration] Distribution > ajout commande : gestion de 5 chiffres après la virgule pour les prix HT</li> | |||
<li>[Administration] Produits > liste : amélioration responsive</li> | |||
<li>[Espace producteur] Produits : mise en évidence des noms de produit</li> | |||
<li>[Site] Profil utilisateur : permettre édition adresse email</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
version( | |||
'12/06/2023', | |||
[], | |||
[ | |||
"[Administration] Logiciel de caisse Tiller : synchroniser automatiquement les commandes payées avec le crédit", | |||
"[Administration] Correction affichage des points de vente supprimés", | |||
"[Administration] Distribution > ajout commande : gestion de 5 chiffres après la virgule pour les prix HT", | |||
"[Administration] Produits > liste : amélioration responsive", | |||
"[Espace producteur] Produits : mise en évidence des noms de produit", | |||
"[Site] Profil utilisateur : permettre édition adresse email" | |||
], | |||
); | |||
?> |
@@ -1,24 +1,25 @@ | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>22/06/2023</li> | |||
</ul> | |||
<?php | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li>[Administration et Espace producteur] Calendrier pour le choix du jour de distribution : affichage du lundi en premier</li> | |||
<li>[Administration] Distribution : alerte remboursement commandes lors de la désactivation d'une distribution</li> | |||
<li>[Administration] Distribution > édition commande : alerte si quantité max d'un produit dépassée</li> | |||
<li>[Administration] Distributions > liste commandes : ajout lien vers fiche client (crédit, profil, commandes)</li> | |||
<li>[Administration] Documents > Bons de livraison : alerte suppression produits</li> | |||
<li>[Administration] Distributions > formulaire commande : raccourci "Entrée" pour passer à la ligne du dessous</li> | |||
<li>[Administration] Utilisateur > édition : ajout info contact facturation</li> | |||
<li>[Administration] Responsive > listes : accès facilité aux boutons d'action</li> | |||
<li>[Espace producteur] Accueil : gestion visibilité produits présents uniquement sur un point de vente à accès restreint</li> | |||
<li>[Espace producteur] Commande > choix du point de vente : ajout informations en fonction du jour choisi</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
<h4>Maintenance</h4> | |||
<ul> | |||
<li>[Espace producteur] Abonnements : correctif disponibilité produits par point de vente</li> | |||
<li>Abonnements > ajout/modification : prise en compte des contraintes de délai et d'heure limite de commande dans la génération des commandes des distributions à venir</li> | |||
</ul> | |||
version( | |||
'22/06/2023', | |||
[ | |||
"[Administration et Espace producteur] Calendrier pour le choix du jour de distribution : affichage du lundi en premier", | |||
"[Administration] Distribution : alerte remboursement commandes lors de la désactivation d'une distribution", | |||
"[Administration] Distribution > édition commande : alerte si quantité max d'un produit dépassée", | |||
"[Administration] Distributions > liste commandes : ajout lien vers fiche client (crédit, profil, commandes)", | |||
"[Administration] Documents > Bons de livraison : alerte suppression produits", | |||
"[Administration] Distributions > formulaire commande : raccourci 'Entrée' pour passer à la ligne du dessous", | |||
"[Administration] Utilisateur > édition : ajout info contact facturation", | |||
"[Administration] Responsive > listes : accès facilité aux boutons d'action", | |||
"[Espace producteur] Accueil : gestion visibilité produits présents uniquement sur un point de vente à accès restreint", | |||
"[Espace producteur] Commande > choix du point de vente : ajout informations en fonction du jour choisi" | |||
], | |||
[ | |||
"[Espace producteur] Abonnements : correctif disponibilité produits par point de vente", | |||
"Abonnements > ajout/modification : prise en compte des contraintes de délai et d'heure limite de commande dans la génération des commandes des distributions à venir" | |||
] | |||
); | |||
?> |
@@ -1,11 +1,15 @@ | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>03/07/2023</li> | |||
</ul> | |||
<?php | |||
<h4>Maintenance</h4> | |||
<ul> | |||
<li>[Administration] Calendrier : couleur du jour sélectionné plus prononcée</li> | |||
<li>[Administration] Distributions > Produits : possibilité de définir une quantité maximum à 0</li> | |||
<li>[Technique] Réécriture requêtes bases de données</li> | |||
</ul> | |||
require_once dirname(__FILE__) . '/_macros.php'; | |||
version( | |||
'03/07/2023', | |||
[], | |||
[ | |||
'[Administration] Calendrier : couleur du jour sélectionné plus prononcée', | |||
'[Administration] Distributions > Produits : possibilité de définir une quantité maximum à 0', | |||
'[Technique] Réécriture requêtes bases de données' | |||
] | |||
); | |||
?> |
@@ -1,12 +1,16 @@ | |||
<h4>Date de sortie</h4> | |||
<ul> | |||
<li>17/08/2023</li> | |||
</ul> | |||
<?php | |||
<h4>Évolutions</h4> | |||
<ul> | |||
<li>[Administration] Système de support</li> | |||
<li>[Site] Évolution du contenu et mise en page : carte et liste des producteurs, à propos, fonctionnalités, code source.</li> | |||
<li>[Site] Lien "Je demande une démo"</li> | |||
<li>[Site & espace producteur] Barre de navigation en haut du site</li> | |||
</ul> | |||
require_once dirname(__FILE__).'/_macros.php'; | |||
version( | |||
'17/08/2023', | |||
[ | |||
'[Administration] Système de support', | |||
'[Site] Évolution du contenu et mise en page : carte et liste des producteurs, à propos, fonctionnalités, code source.', | |||
'[Site] Lien "Je demande une démo"', | |||
'[Site & espace producteur] Barre de navigation en haut du site' | |||
], | |||
[] | |||
); | |||
?> |
@@ -0,0 +1,19 @@ | |||
<?php | |||
require_once dirname(__FILE__).'/_macros.php'; | |||
version( | |||
'28/08/2023', | |||
[ | |||
"[Administration] Utilisateurs : page crédit (somme totale en crédit, liste des clients à relancer, exports CSV)", | |||
"[Administration et espace producteur] Témoignages producteurs : possibilité de saisir un témoignage sur l'utilisation du logiciel dans 'Paramètres > Opendistrib' puis affichage des témoignages sur la page 'À propos'.", | |||
"[Administration] Utilisateur : retour à la liste après modification", | |||
'[Espace producteur] Produits : lien "En savoir plus" pour afficher la description longue', | |||
"[Espace producteur] Commande : affichage d'un message s'il n'y a aucune distributions à venir", | |||
], | |||
[ | |||
"[Administration et espace producteur] Produits : optimisation de l'affichage des images" | |||
] | |||
); | |||
?> |
@@ -0,0 +1,43 @@ | |||
<?php | |||
function version(string $date, array $featuresArray, array $maintenanceArray) { | |||
release_date($date); | |||
features($featuresArray); | |||
maintenance($maintenanceArray); | |||
} | |||
function release_date(string $date) { | |||
$html = '<div class="block">'; | |||
$html .= '<h4><span class="glyphicon glyphicon-calendar"></span> Date de sortie</h4>'; | |||
$html .= '<ul><li>'.$date.'</li></ul>'; | |||
$html .= '</div>'; | |||
echo $html; | |||
} | |||
function features(array $featuresArray) { | |||
if(count($featuresArray) > 0) { | |||
$html = '<div class="block">'; | |||
$html .= '<h4><span class="glyphicon glyphicon-flash"></span> Évolutions</h4>'; | |||
$html .= '<ul>'; | |||
foreach($featuresArray as $feature) { | |||
$html .= '<li>'.$feature.'</li>'; | |||
} | |||
$html .= '</ul>'; | |||
$html .= '</div>'; | |||
echo $html; | |||
} | |||
} | |||
function maintenance(array $maintenanceArray) { | |||
if(count($maintenanceArray) > 0) { | |||
$html = '<div class="block">'; | |||
$html .= '<h4><span class="glyphicon glyphicon-wrench"></span> Maintenance</h4>'; | |||
$html .= '<ul>'; | |||
foreach($maintenanceArray as $maintenance) { | |||
$html .= '<li>'.$maintenance.'</li>'; | |||
} | |||
$html .= '</ul>'; | |||
$html .= '</div>'; | |||
echo $html; | |||
} | |||
} |
@@ -31,7 +31,9 @@ | |||
"bower-asset/jquery": "^3.6", | |||
"yidas/yii2-bower-asset": "2.0.13.1", | |||
"stripe/stripe-php": "^7.95", | |||
"loveorigami/yii2-bootstrap-toggle": "*" | |||
"loveorigami/yii2-bootstrap-toggle": "*", | |||
"justcoded/yii2-event-listener": "*", | |||
"ext-pdo": "*" | |||
}, | |||
"require-dev": { | |||
"yiisoft/yii2-codeception": "*", |
@@ -4,7 +4,7 @@ | |||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", | |||
"This file is @generated automatically" | |||
], | |||
"content-hash": "85c783330a1d88a3ed3c4674e84d10ba", | |||
"content-hash": "7da17be4685def1e9635cc5ab5e5a7d9", | |||
"packages": [ | |||
{ | |||
"name": "2amigos/yii2-chartjs-widget", | |||
@@ -1080,6 +1080,53 @@ | |||
], | |||
"time": "2022-06-20T21:43:03+00:00" | |||
}, | |||
{ | |||
"name": "justcoded/yii2-event-listener", | |||
"version": "1.0.2", | |||
"source": { | |||
"type": "git", | |||
"url": "https://github.com/justcoded/yii2-event-listener.git", | |||
"reference": "7407899c71241a92b6508561cf1527e5f097ca57" | |||
}, | |||
"dist": { | |||
"type": "zip", | |||
"url": "https://api.github.com/repos/justcoded/yii2-event-listener/zipball/7407899c71241a92b6508561cf1527e5f097ca57", | |||
"reference": "7407899c71241a92b6508561cf1527e5f097ca57", | |||
"shasum": "" | |||
}, | |||
"require": { | |||
"php": ">=7.0.0", | |||
"yiisoft/yii2": "~2.0.11" | |||
}, | |||
"type": "yii2-extension", | |||
"autoload": { | |||
"psr-4": { | |||
"justcoded\\yii2\\eventlistener\\": "src/" | |||
} | |||
}, | |||
"notification-url": "https://packagist.org/downloads/", | |||
"license": [ | |||
"BSD-3-Clause" | |||
], | |||
"authors": [ | |||
{ | |||
"name": "Alex Prokopenko", | |||
"email": "aprokopenko@justcoded.com" | |||
} | |||
], | |||
"description": "Yii2 Event Listener", | |||
"keywords": [ | |||
"event listener", | |||
"events", | |||
"listeners", | |||
"yii2" | |||
], | |||
"support": { | |||
"issues": "https://github.com/justcoded/yii2-event-listener/issues", | |||
"source": "https://github.com/justcoded/yii2-event-listener/tree/1.0.2" | |||
}, | |||
"time": "2019-06-24T17:11:24+00:00" | |||
}, | |||
{ | |||
"name": "kartik-v/yii2-mpdf", | |||
"version": "dev-master", | |||
@@ -6435,7 +6482,8 @@ | |||
"prefer-stable": false, | |||
"prefer-lowest": false, | |||
"platform": { | |||
"php": ">=7.4" | |||
"php": ">=7.4", | |||
"ext-pdo": "*" | |||
}, | |||
"platform-dev": [], | |||
"plugin-api-version": "2.3.0" |
@@ -0,0 +1,27 @@ | |||
<?php | |||
namespace console\commands; | |||
use common\logic\Distribution\Distribution\Wrapper\DistributionManager; | |||
use common\logic\Producer\Producer\Wrapper\ProducerManager; | |||
use yii\console\Controller; | |||
class DemoAccountController extends Controller | |||
{ | |||
public function actionIndex() | |||
{ | |||
$producerManager = ProducerManager::getInstance(); | |||
$distributionManager = DistributionManager::getInstance(); | |||
$producerDemo = $producerManager->findOneProducerDemoAccount(); | |||
\Yii::$app->logic->setProducerContext($producerDemo); | |||
if ($producerDemo) { | |||
$dateTime = strtotime("+7 day"); | |||
$distribution = $distributionManager->createDistributionIfNotExist(date('Y-m-d', $dateTime)); | |||
$distributionManager->activeDistribution($distribution); | |||
} | |||
} | |||
} | |||
?> |
@@ -47,7 +47,7 @@ return [ | |||
'id' => 'app-console', | |||
'basePath' => dirname(__DIR__), | |||
'bootstrap' => ['log'], | |||
'controllerNamespace' => 'console\controllers', | |||
'controllerNamespace' => 'console\commands', | |||
'components' => [ | |||
'log' => [ | |||
'targets' => [ |
@@ -0,0 +1,28 @@ | |||
<?php | |||
use yii\db\Migration; | |||
use yii\db\Schema; | |||
/** | |||
* Class m230821_061757_producer_add_option_testimony | |||
*/ | |||
class m230821_061757_producer_add_option_testimony extends Migration | |||
{ | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function safeUp() | |||
{ | |||
$this->addColumn('producer', 'option_testimony', Schema::TYPE_TEXT); | |||
$this->addColumn('producer', 'option_time_saved', Schema::TYPE_FLOAT); | |||
} | |||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function safeDown() | |||
{ | |||
$this->dropColumn('producer', 'option_testimony'); | |||
$this->dropColumn('producer', 'option_time_saved'); | |||
} | |||
} |