Browse Source

Merge branch 'develop'

master
Guillaume Bourgeois 5 months ago
parent
commit
98b3992fd8
73 changed files with 1739 additions and 372 deletions
  1. +5
    -3
      backend/controllers/CronController.php
  2. +7
    -6
      backend/controllers/DistributionController.php
  3. +5
    -1
      backend/controllers/DocumentController.php
  4. +12
    -8
      backend/controllers/OrderController.php
  5. +7
    -2
      backend/controllers/PointSaleController.php
  6. +6
    -2
      backend/controllers/ProducerAdminController.php
  7. +24
    -7
      backend/controllers/ReportController.php
  8. +9
    -6
      backend/controllers/SubscriptionController.php
  9. +14
    -4
      backend/views/dashboard/index.php
  10. +7
    -11
      backend/views/distribution/index.php
  11. +5
    -1
      backend/views/producer/update.php
  12. +3
    -2
      backend/views/report/index.php
  13. +6
    -2
      backend/views/user/index.php
  14. +16
    -2
      backend/views/user/orders.php
  15. +119
    -95
      backend/web/css/screen.css
  16. +12
    -0
      backend/web/js/backend.js
  17. +1
    -1
      backend/web/js/vuejs/distribution-index.js
  18. +11
    -3
      backend/web/js/vuejs/report-index.js
  19. +27
    -0
      backend/web/sass/_adminlte.scss
  20. +3
    -0
      common/components/BusinessLogic.php
  21. +18
    -0
      common/components/BusinessLogicTrait.php
  22. +5
    -0
      common/config/main.php
  23. +1
    -1
      common/config/params.php
  24. +45
    -0
      common/mail/newProducerTestimony-html.php
  25. +45
    -0
      common/mail/newProducerTestimony-text.php
  26. +26
    -0
      common/versions/24.6.A.php
  27. +1
    -1
      console/commands/ClosingOrdersController.php
  28. +65
    -0
      console/commands/InitOrderStatusHistoryController.php
  29. +46
    -0
      console/migrations/m240527_083421_create_table_order_status_history.php
  30. +26
    -0
      console/migrations/m240530_080239_add_column_producer_option_credit_description.php
  31. +3
    -0
      domain/Distribution/Distribution/DistributionBuilder.php
  32. +2
    -0
      domain/Distribution/Distribution/Event/DistributionActiveEvent.php
  33. +42
    -3
      domain/Order/Order/Order.php
  34. +18
    -65
      domain/Order/Order/OrderBuilder.php
  35. +165
    -1
      domain/Order/Order/OrderManager.php
  36. +28
    -3
      domain/Order/Order/OrderRepository.php
  37. +30
    -5
      domain/Order/Order/OrderRepositoryQuery.php
  38. +132
    -11
      domain/Order/Order/OrderSolver.php
  39. +5
    -4
      domain/Order/Order/TillerManager.php
  40. +36
    -0
      domain/Order/OrderStatus/OrderStatus.php
  41. +18
    -0
      domain/Order/OrderStatus/OrderStatusBuilder.php
  42. +31
    -0
      domain/Order/OrderStatus/OrderStatusDefinition.php
  43. +38
    -0
      domain/Order/OrderStatus/OrderStatusModule.php
  44. +36
    -0
      domain/Order/OrderStatus/OrderStatusRepository.php
  45. +27
    -0
      domain/Order/OrderStatus/OrderStatusSolver.php
  46. +107
    -0
      domain/Order/OrderStatusHistory/OrderStatusHistory.php
  47. +28
    -0
      domain/Order/OrderStatusHistory/OrderStatusHistoryBuilder.php
  48. +13
    -0
      domain/Order/OrderStatusHistory/OrderStatusHistoryDefinition.php
  49. +30
    -0
      domain/Order/OrderStatusHistory/OrderStatusHistoryManager.php
  50. +38
    -0
      domain/Order/OrderStatusHistory/OrderStatusHistoryModule.php
  51. +21
    -0
      domain/Order/OrderStatusHistory/OrderStatusHistorySolver.php
  52. +97
    -0
      domain/PointSale/SharedPointSale/SharedPointSale.php
  53. +22
    -0
      domain/PointSale/SharedPointSale/SharedPointSaleBuilder.php
  54. +13
    -0
      domain/PointSale/SharedPointSale/SharedPointSaleDefinition.php
  55. +23
    -0
      domain/PointSale/SharedPointSale/SharedPointSaleManager.php
  56. +32
    -0
      domain/PointSale/SharedPointSale/SharedPointSaleModule.php
  57. +20
    -0
      domain/Producer/Producer/Event/ProducerObserver.php
  58. +3
    -1
      domain/Producer/Producer/Producer.php
  59. +6
    -0
      domain/Producer/Producer/ProducerModule.php
  60. +19
    -0
      domain/Producer/Producer/ProducerNotifier.php
  61. +3
    -1
      domain/Producer/Producer/ProducerRepository.php
  62. +3
    -2
      domain/Subscription/Subscription/Event/DistributionObserver.php
  63. +0
    -85
      domain/Subscription/Subscription/OrderManager.php
  64. +12
    -0
      domain/User/User/UserRepository.php
  65. +24
    -16
      producer/controllers/OrderController.php
  66. +5
    -4
      producer/controllers/SubscriptionController.php
  67. +12
    -2
      producer/views/credit/history.php
  68. +2
    -0
      producer/views/layouts/main.php
  69. +2
    -2
      producer/views/newsletter/index.php
  70. +1
    -2
      producer/views/order/_form.php
  71. +5
    -5
      producer/views/order/history.php
  72. +6
    -2
      producer/web/css/screen.css
  73. +4
    -0
      producer/web/sass/order/_order.scss

+ 5
- 3
backend/controllers/CronController.php View File

use common\helpers\MeanPayment; use common\helpers\MeanPayment;
use domain\Distribution\Distribution\ExportManager; use domain\Distribution\Distribution\ExportManager;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\User\User\User; use domain\User\User\User;
use Yii; use Yii;
use yii\filters\AccessControl; use yii\filters\AccessControl;
*/ */
$arrayOrders = Order::searchAll([ $arrayOrders = Order::searchAll([
'distribution.date' => $date, 'distribution.date' => $date,
'distribution.id_producer' => $producer->id
'distribution.id_producer' => $producer->id,
], [ ], [
'conditions' => 'date_delete IS NULL'
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]); ]);


$configCredit = $producerModule->getConfig('credit'); $configCredit = $producerModule->getConfig('credit');
'distribution.date' => $date, 'distribution.date' => $date,
'distribution.id_producer' => $producer->id 'distribution.id_producer' => $producer->id
], [ ], [
'conditions' => 'date_delete IS NULL'
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]); ]);


$mail = Yii::$app->mailerService->getMailer()->compose( $mail = Yii::$app->mailerService->getMailer()->compose(

+ 7
- 6
backend/controllers/DistributionController.php View File

if ($ordersArray) { if ($ordersArray) {
foreach ($ordersArray as $order) { foreach ($ordersArray as $order) {
$orderModule->initOrder($order); $orderModule->initOrder($order);
if (is_null($order->date_delete)) {
if($orderModule->getSolver()->isOrderStatusValid($order)) {
$revenues += $orderModule->getOrderAmount($order); $revenues += $orderModule->getOrderAmount($order);
$revenuesWithTax += $orderModule->getOrderAmountWithTax($order); $revenuesWithTax += $orderModule->getOrderAmountWithTax($order);
$weight += $order->weight; $weight += $order->weight;
$productOrderModule = $this->getProductOrderModule(); $productOrderModule = $this->getProductOrderModule();
$userProducerModule = $this->getUserProducerModule(); $userProducerModule = $this->getUserProducerModule();




if ($ordersArray) { if ($ordersArray) {
foreach ($ordersArray as &$order) { foreach ($ordersArray as &$order) {


'isCreditFunctioningMandatory' => $orderModule->getRepository()->isOrderCreditFunctioningMandatory($order), 'isCreditFunctioningMandatory' => $orderModule->getRepository()->isOrderCreditFunctioningMandatory($order),
'isCreditFunctioningUser' => $orderModule->getRepository()->isOrderCreditFunctioningUser($order), 'isCreditFunctioningUser' => $orderModule->getRepository()->isOrderCreditFunctioningUser($order),
'debitCredit' => false, 'debitCredit' => false,
'deliveryNote' => $order->deliveryNote ? $order->deliveryNote->getAttributes() : null
'deliveryNote' => $order->deliveryNote ? $order->deliveryNote->getAttributes() : null,
'labelDeleteAction' => $orderModule->getSolver()->getLabelDeleteAction($order),
'labelOrigin' => $orderModule->getSolver()->getLabelOrigin($order, true),
'orderStatusHistorySummaryTitleTag' => $orderModule->getSolver()->getOrderStatusHistorySummaryTitleTag($order, "\n"),
]); ]);
} }
} }
*/ */
public function actionAjaxProcessAddSubscriptions(string $date) public function actionAjaxProcessAddSubscriptions(string $date)
{ {
$ordersArray = $this->getSubscriptionModule()->getOrderManager()
->createAllOrdersFromSubscriptions($date, true);
$ordersArray = $this->getOrderModule()->getManager()
->createAllOrdersFromSubscriptions($date, $this->getUserCurrent(), true);


if($ordersArray && count($ordersArray)) { if($ordersArray && count($ordersArray)) {
return Ajax::responseSuccess('Les abonnements ont bien été importés.'); return Ajax::responseSuccess('Les abonnements ont bien été importés.');

+ 5
- 1
backend/controllers/DocumentController.php View File

use domain\Document\Invoice\Invoice; use domain\Document\Invoice\Invoice;
use domain\Document\Quotation\Quotation; use domain\Document\Quotation\Quotation;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrder; use domain\Order\ProductOrder\ProductOrder;
use domain\Payment\Payment; use domain\Payment\Payment;
use kartik\mpdf\Pdf; use kartik\mpdf\Pdf;


public function actionAjaxAddProduct($idDocument, $classDocument, $idProduct, $quantity, $price) public function actionAjaxAddProduct($idDocument, $classDocument, $idProduct, $quantity, $price)
{ {
$orderModule = $this->getOrderModule();
$documentModule = $this->getDocumentModule(); $documentModule = $this->getDocumentModule();
$productModule = $this->getProductModule(); $productModule = $this->getProductModule();
$userCurrent = $this->getUserCurrent();


if ($documentModule->isValidClass($classDocument)) { if ($documentModule->isValidClass($classDocument)) {
$document = $this->findModel($idDocument, $classDocument); $document = $this->findModel($idDocument, $classDocument);
$order->id_user = $document->id_user; $order->id_user = $document->id_user;
$order->id_point_sale = null; $order->id_point_sale = null;
$order->id_distribution = null; $order->id_distribution = null;
$order->status = 'tmp-order';
$order->origin = Order::ORIGIN_ADMIN; $order->origin = Order::ORIGIN_ADMIN;
$order->date = date('Y-m-d H:i:s'); $order->date = date('Y-m-d H:i:s');
$fieldIdDocument = 'id_' . $classDocumentComplete::tableName(); $fieldIdDocument = 'id_' . $classDocumentComplete::tableName();
$order->$fieldIdDocument = $document->id; $order->$fieldIdDocument = $document->id;
$order->save(); $order->save();
$orderModule->getManager()->changeOrderStatus($order, OrderStatus::ALIAS_ORDERED, $userCurrent);

} else { } else {
$order = $document->orders[0]; $order = $document->orders[0];
} }

+ 12
- 8
backend/controllers/OrderController.php View File

use domain\Distribution\PointSaleDistribution\PointSaleDistribution; use domain\Distribution\PointSaleDistribution\PointSaleDistribution;
use domain\Distribution\ProductDistribution\ProductDistribution; use domain\Distribution\ProductDistribution\ProductDistribution;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrder; use domain\Order\ProductOrder\ProductOrder;
use domain\Payment\Payment; use domain\Payment\Payment;
use domain\PointSale\PointSale\PointSale; use domain\PointSale\PointSale\PointSale;
/** /**
* Traite le formulaire d'ajout/modification de commande. * Traite le formulaire d'ajout/modification de commande.
*/ */
public function processOrderForm(
/*public function processOrderForm(
Distribution $distribution, Distribution $distribution,
string $date, string $date,
array $pointsSale, array $pointsSale,
} }
} }
} }
}
}*/


/** /**
* Page principale de la gestion des commandes. * Page principale de la gestion des commandes.
*/ */
public function actionIndex($date = '', $returnData = false)
/*public function actionIndex($date = '', $returnData = false)
{ {
$distributionModule = $this-> getDistributionModule(); $distributionModule = $this-> getDistributionModule();
$productModule = $this->getProductModule(); $productModule = $this->getProductModule();
} else { } else {
return $this->render('index', $datas); return $this->render('index', $datas);
} }
}
}*/


/** /**
* Génère un fichier d'export des commandes au format CSV. * Génère un fichier d'export des commandes au format CSV.


$order = $orderModule->findOneOrderById($idOrder); $order = $orderModule->findOneOrderById($idOrder);
if ($order) { if ($order) {
$orderModule->deleteOrder($order);
$orderModule->getManager()->deleteOrder($order, $this->getUserCurrent());
} }


return ['success']; return ['success'];
$orderModule = $this->getOrderModule(); $orderModule = $this->getOrderModule();
$order = $orderModule->findOneOrderById($idOrder); $order = $orderModule->findOneOrderById($idOrder);
if ($order) { if ($order) {
$orderModule->deleteOrder($order);
$orderModule->getManager()->deleteOrder($order, $this->getUserCurrent());
} }


$this->redirect(['index', 'date' => $date]); $this->redirect(['index', 'date' => $date]);
$pointSale = $pointSaleModule->findOnePointSaleById($idPointSale); $pointSale = $pointSaleModule->findOnePointSaleById($idPointSale);
$distribution = $distributionModule->findOneDistribution($date); $distribution = $distributionModule->findOneDistribution($date);
$producerCurrent = $this->getProducerCurrent(); $producerCurrent = $this->getProducerCurrent();
$userCurrent = $this->getUserCurrent();


if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $date) if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $date)
&& ($idUser || strlen($username)) && ($idUser || strlen($username))
$order->id_distribution = $distribution->id; $order->id_distribution = $distribution->id;
$order->origin = Order::ORIGIN_ADMIN; $order->origin = Order::ORIGIN_ADMIN;
$order->comment = $comment; $order->comment = $comment;
$order->status = 'tmp-order';


if ($idUser) { if ($idUser) {
$order->id_user = $idUser; $order->id_user = $idUser;


$order->save(); $order->save();


$orderModule->getManager()->changeOrderStatus($order, OrderStatus::ALIAS_ORDERED, $userCurrent);

$user = false; $user = false;
$userProducer = false; $userProducer = false;
if (isset($order->user) && $order->user) { if (isset($order->user) && $order->user) {
} }


$order->id_point_sale = $idPointSale; $order->id_point_sale = $idPointSale;
$order->date_update = date('Y-m-d H:i:s');
$order->mean_payment = $meanPayment; $order->mean_payment = $meanPayment;
$order->comment = $comment; $order->comment = $comment;


$order->save(); $order->save();


$orderModule->getManager()->changeOrderStatus($order, OrderStatus::ALIAS_UPDATED, $this->getUserCurrent());

$order = Order::searchOne(['id' => $order->id]); $order = Order::searchOne(['id' => $order->id]);
$orderModule->initOrder($order); $orderModule->initOrder($order);
if ($order && $orderModule->isCreditAutoPayment($order, $debitCredit)) { if ($order && $orderModule->isCreditAutoPayment($order, $debitCredit)) {

+ 7
- 2
backend/controllers/PointSaleController.php View File

use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use domain\Distribution\PointSaleDistribution\PointSaleDistribution; use domain\Distribution\PointSaleDistribution\PointSaleDistribution;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\PointSale\PointSale\PointSale; use domain\PointSale\PointSale\PointSale;
use domain\PointSale\PointSale\PointSaleSearch; use domain\PointSale\PointSale\PointSaleSearch;
use domain\PointSale\UserPointSale\UserPointSale; use domain\PointSale\UserPointSale\UserPointSale;
'id_point_sale' => $id, 'id_point_sale' => $id,
], ],
[ [
'conditions' => 'date_delete IS NULL AND distribution.date > :today',
'conditions' => [
'distribution.date > :today',
OrderRepositoryQuery::getSqlFilterIsValid()
],
'params' => [':today' => date('Y-m-d')] 'params' => [':today' => date('Y-m-d')]
] ]
); );


if ($ordersArray) { if ($ordersArray) {
foreach ($ordersArray as $order) { foreach ($ordersArray as $order) {
$orderModule->deleteOrder($order, true);
$orderModule->getManager()->deleteOrder($order, $this->getUserCurrent(), true);
} }
} }



+ 6
- 2
backend/controllers/ProducerAdminController.php View File

use common\helpers\Ajax; use common\helpers\Ajax;
use common\helpers\Alwaysdata; use common\helpers\Alwaysdata;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\Producer\Producer\Producer; use domain\Producer\Producer\Producer;
use domain\Product\Product\Product; use domain\Product\Product\Product;
use Yii; use Yii;
if ($withOrders) { if ($withOrders) {
$countOrders = Order::searchCount([ $countOrders = Order::searchCount([
'id_user' => $idUser, 'id_user' => $idUser,
'distribution.id_producer' => $fromProducerId
], ['conditions' => 'date_delete IS NULL']);
'distribution.id_producer' => $fromProducerId,
], [
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]);
} }


if (($withOrders && $countOrders) || !$withOrders) { if (($withOrders && $countOrders) || !$withOrders) {

+ 24
- 7
backend/controllers/ReportController.php View File

use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\MeanPayment; use common\helpers\MeanPayment;
use common\helpers\Price; use common\helpers\Price;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use Yii; use Yii;
use yii\filters\AccessControl; use yii\filters\AccessControl;




public function actionAjaxReport() public function actionAjaxReport()
{ {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$posts = Yii::$app->request->post(); $posts = Yii::$app->request->post();
$isDownload = $posts['isDownload'] == 1;
$resArray = []; $resArray = [];
$conditionUsers = $this->_generateConditionSqlReport($posts, 'users', 'id_user'); $conditionUsers = $this->_generateConditionSqlReport($posts, 'users', 'id_user');
$conditionPointsSale = $this->_generateConditionSqlReport($posts, 'pointsSale', 'id_point_sale'); $conditionPointsSale = $this->_generateConditionSqlReport($posts, 'pointsSale', 'id_point_sale');
WHERE `order`.id = product_order.id_order WHERE `order`.id = product_order.id_order
AND product.id_producer = " . ((int)GlobalParam::getCurrentProducerId()) . " AND product.id_producer = " . ((int)GlobalParam::getCurrentProducerId()) . "
AND product_order.id_product = product.id AND product_order.id_product = product.id
AND `order`.date_delete IS NULL
AND ".OrderRepositoryQuery::getSqlFilterIsValid()."
" . $conditionUsers . " " . $conditionUsers . "
" . $conditionPointsSale . " " . $conditionPointsSale . "
" . $conditionDistributions . " " . $conditionDistributions . "


$totalGlobal = 0; $totalGlobal = 0;
foreach ($res as $line) { foreach ($res as $line) {
$total = Price::format(round($line['total'], 2));
$roundedTotal = round($line['total'], 2);
$total = $isDownload ? $roundedTotal : Price::format($roundedTotal);

$quantity = $line['quantity'];
if((int) $quantity != $quantity) {
$quantity = round($quantity, 3);
}

if ($line['quantity'] > 0) { if ($line['quantity'] > 0) {
$resArray[] = [ $resArray[] = [
'name' => $line['name'], 'name' => $line['name'],
'quantity' => $line['quantity'],
'quantity' => $quantity,
'total' => $total, 'total' => $total,
]; ];
$totalGlobal += $line['total']; $totalGlobal += $line['total'];
} }
} }


$roundedTotalGlobal = round($totalGlobal, 2);
$totalGlobalFormat = $isDownload ? $roundedTotalGlobal : Price::format($roundedTotalGlobal).' HT';

$resArray[] = [ $resArray[] = [
'name' => '', 'name' => '',
'quantity' => '', 'quantity' => '',
'total' => '<strong>' . Price::format(round($totalGlobal, 2)) . ' HT</strong>',
'total' => $totalGlobalFormat,
]; ];


return $resArray;
if($isDownload) {
CSV::send('rapport.csv', $resArray);
}
else {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return $resArray;
}
} }


public function _generateConditionSqlReport($posts, $name, $fieldOrder) public function _generateConditionSqlReport($posts, $name, $fieldOrder)

+ 9
- 6
backend/controllers/SubscriptionController.php View File

*/ */
public function actionUpdate($id) public function actionUpdate($id)
{ {
$orderModule = $this->getOrderModule();
$subscriptionModule = $this->getSubscriptionModule(); $subscriptionModule = $this->getSubscriptionModule();
$productSubscriptionModule = $this->getProductSubscriptionModule(); $productSubscriptionModule = $this->getProductSubscriptionModule();
$productModule = $this->getProductModule(); $productModule = $this->getProductModule();
$messageOrdersDeleted = ''; $messageOrdersDeleted = '';


if ($model->date_end) { if ($model->date_end) {
$countOrdersDeleted = $subscriptionModule->getOrderManager()
->deleteOrdersIncomingDistributionsFromSubscription($subscription, true);
$countOrdersDeleted = $orderModule->getManager()
->deleteOrdersIncomingDistributionsFromSubscription($subscription, $this->getUserCurrent(), true);
if ($countOrdersDeleted) { if ($countOrdersDeleted) {
$messageOrdersDeleted = '<br />' . $countOrdersDeleted . ' commandes supprimées'; $messageOrdersDeleted = '<br />' . $countOrdersDeleted . ' commandes supprimées';
} }
*/ */
public function actionDelete(int $id) public function actionDelete(int $id)
{ {
$orderModule = $this->getOrderModule();
$subscriptionModule = $this->getSubscriptionModule(); $subscriptionModule = $this->getSubscriptionModule();


$subscription = $subscriptionModule->getRepository()->findOneSubscriptionById($id); $subscription = $subscriptionModule->getRepository()->findOneSubscriptionById($id);


if($subscription) { if($subscription) {
$subscriptionModule->getOrderManager()->deleteOrdersIncomingDistributionsFromSubscription($subscription);
$orderModule->getManager()->deleteOrdersIncomingDistributionsFromSubscription($subscription, $this->getUserCurrent());
$subscriptionModule->deleteSubscription($subscription); $subscriptionModule->deleteSubscription($subscription);
$this->setFlash('success', 'Abonnement supprimé'); $this->setFlash('success', 'Abonnement supprimé');
} }


public function actionUpdateDistributions(int $idSubscription, bool $generate = false, bool $update = false) public function actionUpdateDistributions(int $idSubscription, bool $generate = false, bool $update = false)
{ {
$orderModule = $this->getOrderModule();
$subscriptionModule = $this->getSubscriptionModule(); $subscriptionModule = $this->getSubscriptionModule();
$distributionModule = $this-> getDistributionModule(); $distributionModule = $this-> getDistributionModule();
$subscription = $subscriptionModule->findOneSubscriptionById($idSubscription); $subscription = $subscriptionModule->findOneSubscriptionById($idSubscription);


if ($generate) { if ($generate) {
if ($update) { if ($update) {
$subscriptionModule->getOrderManager()
->deleteOrdersIncomingDistributionsFromSubscription($subscription);
$orderModule->getManager()
->deleteOrdersIncomingDistributionsFromSubscription($subscription, $this->getUserCurrent());
} }
foreach ($matchedDistributionsArray as $distribution) { foreach ($matchedDistributionsArray as $distribution) {
$subscriptionModule->createOrderFromSubscription($subscription, $distribution->date);
$orderModule->getManager()->createOrderFromSubscription($subscription, $distribution->date, $this->getUserCurrent());
} }
$this->setFlash('success', 'Commandes ' . ($update ? 're-' : '') . 'générées dans les distributions futures.'); $this->setFlash('success', 'Commandes ' . ($update ? 're-' : '') . 'générées dans les distributions futures.');
return $this->redirect(['subscription/index']); return $this->redirect(['subscription/index']);

+ 14
- 4
backend/views/dashboard/index.php View File

<table class="table table-condensed table-bordered"> <table class="table table-condensed table-bordered">
<thead> <thead>
<tr> <tr>
<th></th>
<th>Statut</th>
<th>Origine</th>
<th>Date</th> <th>Date</th>
<th>Client</th> <th>Client</th>
<th>Produits</th> <th>Produits</th>
<th>Point de vente</th> <th>Point de vente</th>
<th>Montant</th> <th>Montant</th>
<th>Historique</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php $orderModule->initOrder($order); ?> <?php $orderModule->initOrder($order); ?>


<tr class="<?= $orderModule->getHistoryClass($order) ; ?>"> <tr class="<?= $orderModule->getHistoryClass($order) ; ?>">
<td class="infos"><?= $orderModule->getLabelOrigin($order, true); ?></td>
<td class="history">
<?= $orderModule->getSolver()->getLabelOrderStatus($order); ?>
<?php
$lastOrderStatusHistory = $orderModule->getSolver()->getLastOrderStatusHistory($order);
if($lastOrderStatusHistory) {
echo '<br /><span class="small gray">'.$lastOrderStatusHistory->getDate()->format('d/m/Y à H:i').'</span>';
}
?>
</td>
<td class="infos">
<?= $orderModule->getSolver()->getLabelOrigin($order, true); ?>
</td>
<td class="date"> <td class="date">
<div class="block-date"> <div class="block-date">
<div class="day"><?= strftime('%A', strtotime($order->distribution->date)) ?></div> <div class="day"><?= strftime('%A', strtotime($order->distribution->date)) ?></div>
<td><?= $orderModule->getCartSummary($order); ?></td> <td><?= $orderModule->getCartSummary($order); ?></td>
<td><?= $orderModule->getPointSaleSummary($order) ; ?></td> <td><?= $orderModule->getPointSaleSummary($order) ; ?></td>
<td><?= $orderModule->getOrderAmountWithTax($order, Order::AMOUNT_TOTAL, true) ; ?></td> <td><?= $orderModule->getOrderAmountWithTax($order, Order::AMOUNT_TOTAL, true) ; ?></td>
<td class="history"><?= $orderModule->getHistorySummary($order) ; ?></td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </tbody>

+ 7
- 11
backend/views/distribution/index.php View File

<th class="column-checkbox" v-if="idActivePointSale > 0"> <th class="column-checkbox" v-if="idActivePointSale > 0">
<input type="checkbox" v-model="checkboxSelectAllOrders" @change="selectAllOrdersEvent" /> <input type="checkbox" v-model="checkboxSelectAllOrders" @change="selectAllOrdersEvent" />
</th> </th>
<th class="column-state">Statut</th>
<th class="column-origin">Origine</th> <th class="column-origin">Origine</th>
<th class="column-state">État</th>
<th class="column-user">Utilisateur</th> <th class="column-user">Utilisateur</th>
<th class="column-point-sale" v-if="idActivePointSale == 0">Point de vente</th> <th class="column-point-sale" v-if="idActivePointSale == 0">Point de vente</th>
<th class="column-amount">Montant</th> <th class="column-amount">Montant</th>
<td class="column-checkbox" v-if="idActivePointSale > 0"> <td class="column-checkbox" v-if="idActivePointSale > 0">
<input type="checkbox" v-model="order.selected" /> <input type="checkbox" v-model="order.selected" />
</td> </td>
<td class="column-origin">
<label class="label label-success" v-if="order.origin == 'user'">client</label>
<label class="label label-default" v-else-if="order.origin == 'auto'">auto</label>
<label class="label label-warning" v-else>admin</label>
</td>
<td class="column-state"> <td class="column-state">
<span class="label label-danger" v-if="order.date_delete"><span class="glyphicon glyphicon-trash"></span></span>
<span class="label label-warning" v-if="order.date_update"><span class="glyphicon glyphicon-pencil"></span></span>
<span class="label label-success" v-if="!order.date_update && !order.date_delete"><span class="glyphicon glyphicon-check"></span></span>
<span v-if="order.order_status_alias == 'canceled'" class="label label-danger" :title="order.orderStatusHistorySummaryTitleTag"><span class="glyphicon glyphicon-trash"></span></span>
<span v-if="order.order_status_alias == 'updated'" class="label label-warning" :title="order.orderStatusHistorySummaryTitleTag"><span class="glyphicon glyphicon-pencil"></span></span>
<span v-if="order.order_status_alias == 'ordered'" class="label label-success" :title="order.orderStatusHistorySummaryTitleTag"><span class="glyphicon glyphicon-check"></span></span>
</td> </td>
<td class="column-origin" v-html="order.labelOrigin"></td>
<td class="column-user"> <td class="column-user">
<a v-if="order.user" :href="baseUrl+'/user/view?id='+order.id_user" target="_blank" :class="order.user.trust_alert ? 'user-trust-alert' : ''" :title="order.user.trust_alert ? order.user.trust_alert_comment : ''"> <a v-if="order.user" :href="baseUrl+'/user/view?id='+order.id_user" target="_blank" :class="order.user.trust_alert ? 'user-trust-alert' : ''" :title="order.user.trust_alert ? order.user.trust_alert_comment : ''">
<template v-if="order.user.name_legal_person && order.user.name_legal_person.length"> <template v-if="order.user.name_legal_person && order.user.name_legal_person.length">
</div> </div>
</td> </td>
<td class="column-state-payment"> <td class="column-state-payment">
<template v-if="!order.date_delete">
<template v-if="order.order_status_alias == 'ordered' || order.order_status_alias == 'updated'">
<a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id"> <a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">
<order-state-payment :order="order" :producer="producer"></order-state-payment> <order-state-payment :order="order" :producer="producer"></order-state-payment>
</a> </a>
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="deleteOrderClick"><span class="glyphicon glyphicon-trash"></span> Supprimer</a></li>
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="deleteOrderClick"><span class="glyphicon glyphicon-trash"></span> {{ order.labelDeleteAction }}</a></li>
<li v-if="order.id_subscription > 0"><a class="" :href="baseUrl+'/subscription/update?id='+order.id_subscription"><span class="glyphicon glyphicon-repeat"></span> Modifier l'abonnement lié</a></li> <li v-if="order.id_subscription > 0"><a class="" :href="baseUrl+'/subscription/update?id='+order.id_subscription"><span class="glyphicon glyphicon-repeat"></span> Modifier l'abonnement lié</a></li>
<li v-else><a class="add-subscription" :href="baseUrl+'/subscription/create?idOrder='+order.id"><span class="glyphicon glyphicon-plus"></span><span class="glyphicon glyphicon-repeat"></span>Créer un abonnement</a></li> <li v-else><a class="add-subscription" :href="baseUrl+'/subscription/create?idOrder='+order.id"><span class="glyphicon glyphicon-plus"></span><span class="glyphicon glyphicon-repeat"></span>Créer un abonnement</a></li>
</ul> </ul>

+ 5
- 1
backend/views/producer/update.php View File

<?= $form->field($model, 'option_behavior_cancel_order') <?= $form->field($model, 'option_behavior_cancel_order')
->dropDownList([ ->dropDownList([
Producer::BEHAVIOR_DELETE_ORDER_DELETE => 'Suppression de la commande', Producer::BEHAVIOR_DELETE_ORDER_DELETE => 'Suppression de la commande',
Producer::BEHAVIOR_DELETE_ORDER_STATUS => 'Passage de la commande en statut "supprimé"',
Producer::BEHAVIOR_DELETE_ORDER_STATUS => 'Passage de la commande en statut "annulée"',
], []); ?> ], []); ?>
</div> </div>
</div> </div>
<?= $form->field($model, 'option_check_by_default_prevent_user_credit') <?= $form->field($model, 'option_check_by_default_prevent_user_credit')
->dropDownList(Dropdown::noYesChoices()); ?> ->dropDownList(Dropdown::noYesChoices()); ?>


<?= $form->field($model, 'option_credit_description')
->hint('Description affichée sur la page "Cagnotte" de la boutique')
->textarea(); ?>

<?php if($featureChecker->isEnabled(Feature::ALIAS_ONLINE_PAYMENT)): ?> <?php if($featureChecker->isEnabled(Feature::ALIAS_ONLINE_PAYMENT)): ?>
<h4>Paiement en ligne</h4> <h4>Paiement en ligne</h4>
<?php if($userModule->getAuthorizationChecker()->isGrantedAsAdministrator($userCurrent)): ?> <?php if($userModule->getAuthorizationChecker()->isGrantedAsAdministrator($userCurrent)): ?>

+ 3
- 2
backend/views/report/index.php View File

<tr> <tr>
<th>Produit</th> <th>Produit</th>
<th>Quantité</th> <th>Quantité</th>
<th>Total</th>
<th>Total HT</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
Aucune donnée disponible pour ces critères. Aucune donnée disponible pour ces critères.
</div> </div>
</div> </div>
<a class="btn btn-primary" @click="generateReport()" v-else="!showReport"><span class="fa fa-pencil-square-o"></span> Générer</a>
<a v-else="!showReport" class="btn btn-primary" @click="generateReport(false)"><span class="fa fa-pencil-square-o"></span> Générer</a>
<a class="btn btn-primary" @click="generateReport(true)"><span class="fa fa-download"></span> Télécharger (CSV)</a>
</div> </div>
</div> </div>
</div> </div>

+ 6
- 2
backend/views/user/index.php View File

use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\Price; use common\helpers\Price;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\Producer\Producer\ProducerModule; use domain\Producer\Producer\ProducerModule;
use domain\User\User\UserModule; use domain\User\User\UserModule;
use domain\User\UserProducer\UserProducer; use domain\User\UserProducer\UserProducer;
'orders' => function ($url, $model) { 'orders' => function ($url, $model) {
$url = Yii::$app->urlManager->createUrl(['user/orders', 'id' => $model['id']]); $url = Yii::$app->urlManager->createUrl(['user/orders', 'id' => $model['id']]);
$countOrders = Order::searchCount([ $countOrders = Order::searchCount([
'id_user' => $model['id'],
], ['conditions' => 'date_delete IS NULL']);
'id_user' => $model['id']
], [
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]);


$html = ''; $html = '';
if ($countOrders) { if ($countOrders) {

+ 16
- 2
backend/views/user/orders.php View File

//'filterModel' => $searchModel, //'filterModel' => $searchModel,
'dataProvider' => $dataProvider, 'dataProvider' => $dataProvider,
'columns' => [ 'columns' => [
[
'label' => 'Statut',
'format' => 'raw',
'value' => function ($order) use ($orderModule) {
return $orderModule->getSolver()->getLabelOrderStatus($order);
}
],
[
'label' => 'Origine',
'format' => 'raw',
'value' => function ($order) use ($orderModule) {
return $orderModule->getSolver()->getLabelOrigin($order);;
}
],
[ [
'attribute' => 'distribution.date', 'attribute' => 'distribution.date',
'label' => 'Date', 'label' => 'Date',
'value' => function ($user) {
return date('d/m/Y',strtotime($user->distribution->date));
'value' => function ($order) {
return date('d/m/Y',strtotime($order->distribution->date));
} }
], ],
[ [

+ 119
- 95
backend/web/css/screen.css View File

font-size: 11px; font-size: 11px;
padding: 0px 7px; padding: 0px 7px;
} }
/* line 11, ../sass/_adminlte.scss */
/* line 12, ../sass/_adminlte.scss */
body.skin-black .label.outline {
background-color: white !important;
}
/* line 16, ../sass/_adminlte.scss */
body.skin-black .label.label-default.outline {
color: #444 !important;
border: solid 1px #444;
}
/* line 21, ../sass/_adminlte.scss */
body.skin-black .label.label-success.outline {
color: #00a65a !important;
border: solid 1px #00a65a;
}
/* line 26, ../sass/_adminlte.scss */
body.skin-black .label.label-warning.outline {
color: #f39c12 !important;
border: solid 1px #f39c12;
}
/* line 31, ../sass/_adminlte.scss */
body.skin-black .label.label-danger.outline {
color: #dd4b39 !important;
border: solid 1px #dd4b39;
}
/* line 38, ../sass/_adminlte.scss */
body.skin-black .ui-tooltip { body.skin-black .ui-tooltip {
white-space: pre-wrap; white-space: pre-wrap;
} }
/* line 16, ../sass/_adminlte.scss */
/* line 43, ../sass/_adminlte.scss */
body.skin-black .user-without-account { body.skin-black .user-without-account {
color: gray; color: gray;
font-style: italic; font-style: italic;
} }
/* line 22, ../sass/_adminlte.scss */
/* line 49, ../sass/_adminlte.scss */
body.skin-black .main-header .logo { body.skin-black .main-header .logo {
background-color: white; background-color: white;
font-family: 'highvoltageregular'; font-family: 'highvoltageregular';
font-size: 23px; font-size: 23px;
position: relative; position: relative;
} }
/* line 28, ../sass/_adminlte.scss */
/* line 55, ../sass/_adminlte.scss */
body.skin-black .main-header .logo:hover, body.skin-black .main-header .logo:focus { body.skin-black .main-header .logo:hover, body.skin-black .main-header .logo:focus {
background-color: white; background-color: white;
text-decoration: none; text-decoration: none;
} }
/* line 33, ../sass/_adminlte.scss */
/* line 60, ../sass/_adminlte.scss */
body.skin-black .main-header .logo img { body.skin-black .main-header .logo img {
position: relative; position: relative;
max-width: 300px; max-width: 300px;
max-height: 300px; max-height: 300px;
height: auto; height: auto;
} }
/* line 41, ../sass/_adminlte.scss */
/* line 68, ../sass/_adminlte.scss */
body.skin-black .main-header .logo .logo-lg img { body.skin-black .main-header .logo .logo-lg img {
width: 90px; width: 90px;
top: -2px; top: -2px;
} }
/* line 47, ../sass/_adminlte.scss */
/* line 74, ../sass/_adminlte.scss */
body.skin-black .main-header .logo .logo-mini img { body.skin-black .main-header .logo .logo-mini img {
width: 50px; width: 50px;
} }
/* line 52, ../sass/_adminlte.scss */
/* line 79, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar { body.skin-black .main-header .navbar {
display: block; display: block;
background-color: white; background-color: white;
padding: 0px; padding: 0px;
} }
/* line 57, ../sass/_adminlte.scss */
/* line 84, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel { body.skin-black .main-header .navbar .producer-panel {
position: relative; position: relative;
float: left; float: left;
padding-left: 50px; padding-left: 50px;
margin-left: 7px; margin-left: 7px;
} }
/* line 64, ../sass/_adminlte.scss */
/* line 91, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel.without-logo { body.skin-black .main-header .navbar .producer-panel.without-logo {
padding-left: 10px; padding-left: 10px;
} }
/* line 68, ../sass/_adminlte.scss */
/* line 95, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .logo { body.skin-black .main-header .navbar .producer-panel .logo {
position: absolute; position: absolute;
top: 5px; top: 5px;
text-align: center; text-align: center;
overflow: hidden; overflow: hidden;
} }
/* line 80, ../sass/_adminlte.scss */
/* line 107, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .logo .img-logo { body.skin-black .main-header .navbar .producer-panel .logo .img-logo {
position: absolute; position: absolute;
top: 50%; top: 50%;
max-width: 35px; max-width: 35px;
max-height: 35px; max-height: 35px;
} }
/* line 90, ../sass/_adminlte.scss */
/* line 117, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .title { body.skin-black .main-header .navbar .producer-panel .title {
position: relative; position: relative;
top: 2px; top: 2px;
text-transform: uppercase; text-transform: uppercase;
} }
/* line 95, ../sass/_adminlte.scss */
/* line 122, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .title a { body.skin-black .main-header .navbar .producer-panel .title a {
color: #333; color: #333;
} }
/* line 98, ../sass/_adminlte.scss */
/* line 125, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .title a:hover { body.skin-black .main-header .navbar .producer-panel .title a:hover {
text-decoration: underline; text-decoration: underline;
} }
/* line 103, ../sass/_adminlte.scss */
/* line 130, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .title .producer-id { body.skin-black .main-header .navbar .producer-panel .title .producer-id {
color: gray; color: gray;
font-size: 13px; font-size: 13px;
} }
/* line 110, ../sass/_adminlte.scss */
/* line 137, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .sidebar-toggle { body.skin-black .main-header .navbar .sidebar-toggle {
color: #333; color: #333;
} }
/* line 114, ../sass/_adminlte.scss */
/* line 141, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .link-support { body.skin-black .main-header .navbar .link-support {
float: left; float: left;
padding: 15px 15px; padding: 15px 15px;
border-right: solid 1px #e0e0e0; border-right: solid 1px #e0e0e0;
color: #333; color: #333;
} }
/* line 120, ../sass/_adminlte.scss */
/* line 147, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .link-support:hover { body.skin-black .main-header .navbar .link-support:hover {
text-decoration: none; text-decoration: none;
color: #F39C12; color: #F39C12;
} }
/* line 126, ../sass/_adminlte.scss */
/* line 153, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .navbar-custom-menu .nav { body.skin-black .main-header .navbar .navbar-custom-menu .nav {
display: block; display: block;
} }
/* line 130, ../sass/_adminlte.scss */
/* line 157, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .navbar-custom-menu .navbar-nav > li > a, body.skin-black .main-header .navbar .navbar-custom-menu .navbar-nav > li > a,
body.skin-black .main-header .navbar .navbar-right > li > a { body.skin-black .main-header .navbar .navbar-right > li > a {
border-left: solid 1px #e0e0e0; border-left: solid 1px #e0e0e0;
color: #333; color: #333;
} }
/* line 136, ../sass/_adminlte.scss */
/* line 163, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav > li > a:hover, body.skin-black .main-header .navbar .nav > li > a:active, body.skin-black .main-header .navbar .nav > li > a:focus, body.skin-black .main-header .navbar .nav > li > a:hover, body.skin-black .main-header .navbar .nav > li > a:active, body.skin-black .main-header .navbar .nav > li > a:focus,
body.skin-black .main-header .navbar .nav .open > a, body.skin-black .main-header .navbar .nav .open > a:hover, body.skin-black .main-header .navbar .nav .open > a:focus, body.skin-black .main-header .navbar .nav .open > a, body.skin-black .main-header .navbar .nav .open > a:hover, body.skin-black .main-header .navbar .nav .open > a:focus,
body.skin-black .main-header .navbar .nav > .active > a { body.skin-black .main-header .navbar .nav > .active > a {
color: #F39C12; color: #F39C12;
} }
/* line 142, ../sass/_adminlte.scss */
/* line 169, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .dropdown-menu { body.skin-black .main-header .navbar .dropdown-menu {
-moz-box-shadow: 0px 0px 4px gray; -moz-box-shadow: 0px 0px 4px gray;
-webkit-box-shadow: 0px 0px 4px gray; -webkit-box-shadow: 0px 0px 4px gray;
box-shadow: 0px 0px 4px gray; box-shadow: 0px 0px 4px gray;
} }
/* line 147, ../sass/_adminlte.scss */
/* line 174, ../sass/_adminlte.scss */
body.skin-black .main-header .logo, body.skin-black .main-header .navbar .sidebar-toggle { body.skin-black .main-header .logo, body.skin-black .main-header .navbar .sidebar-toggle {
border-right: solid 1px #e0e0e0; border-right: solid 1px #e0e0e0;
} }
/* line 151, ../sass/_adminlte.scss */
/* line 178, ../sass/_adminlte.scss */
body.skin-black .main-header .link-control-sidebar { body.skin-black .main-header .link-control-sidebar {
display: none; display: none;
} }
/* line 156, ../sass/_adminlte.scss */
/* line 183, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu { body.skin-black .main-header .notifications-menu ul.menu {
max-height: 300px; max-height: 300px;
} }
/* line 159, ../sass/_adminlte.scss */
/* line 186, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a { body.skin-black .main-header .notifications-menu ul.menu li a {
padding-top: 4px; padding-top: 4px;
padding-bottom: 4px; padding-bottom: 4px;
} }
/* line 163, ../sass/_adminlte.scss */
/* line 190, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a h5 { body.skin-black .main-header .notifications-menu ul.menu li a h5 {
margin-bottom: 2px; margin-bottom: 2px;
} }
/* line 166, ../sass/_adminlte.scss */
/* line 193, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a h5 small { body.skin-black .main-header .notifications-menu ul.menu li a h5 small {
float: right; float: right;
} }
/* line 171, ../sass/_adminlte.scss */
/* line 198, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a p { body.skin-black .main-header .notifications-menu ul.menu li a p {
margin-left: 10px; margin-left: 10px;
} }
/* line 182, ../sass/_adminlte.scss */
/* line 209, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .dropdown-menu { body.skin-black .main-header .navbar .nav li.producer-menu .dropdown-menu {
width: 400px; width: 400px;
} }
/* line 186, ../sass/_adminlte.scss */
/* line 213, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .search-producer { body.skin-black .main-header .navbar .nav li.producer-menu .search-producer {
margin: 10px; margin: 10px;
width: 94%; width: 94%;
} }
/* line 191, ../sass/_adminlte.scss */
/* line 218, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .li-alert-no-results { body.skin-black .main-header .navbar .nav li.producer-menu .li-alert-no-results {
display: none; display: none;
} }
/* line 194, ../sass/_adminlte.scss */
/* line 221, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .li-alert-no-results .alert { body.skin-black .main-header .navbar .nav li.producer-menu .li-alert-no-results .alert {
margin-bottom: 0px; margin-bottom: 0px;
margin-left: 10px; margin-left: 10px;
margin-right: 10px; margin-right: 10px;
padding: 15px 15px 10px 15px; padding: 15px 15px 10px 15px;
} }
/* line 202, ../sass/_adminlte.scss */
/* line 229, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .label { body.skin-black .main-header .navbar .nav li.producer-menu .label {
position: relative; position: relative;
top: -2px; top: -2px;
left: 0px; left: 0px;
} }
/* line 208, ../sass/_adminlte.scss */
/* line 235, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu #link-display-producers-offline { body.skin-black .main-header .navbar .nav li.producer-menu #link-display-producers-offline {
color: #F39C12; color: #F39C12;
} }
/* line 212, ../sass/_adminlte.scss */
/* line 239, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .offline { body.skin-black .main-header .navbar .nav li.producer-menu .offline {
display: none; display: none;
} }
/* line 216, ../sass/_adminlte.scss */
/* line 243, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu a { body.skin-black .main-header .navbar .nav li.producer-menu a {
color: #333; color: #333;
} }
/* line 220, ../sass/_adminlte.scss */
/* line 247, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .producer-id { body.skin-black .main-header .navbar .nav li.producer-menu .producer-id {
position: relative; position: relative;
top: 4px; top: 4px;
font-size: 12px; font-size: 12px;
float: right; float: right;
} }
/* line 231, ../sass/_adminlte.scss */
/* line 258, ../sass/_adminlte.scss */
body.skin-black .sidebar .sidebar-menu > li.header { body.skin-black .sidebar .sidebar-menu > li.header {
color: #899397; color: #899397;
} }
/* line 235, ../sass/_adminlte.scss */
/* line 262, ../sass/_adminlte.scss */
body.skin-black .sidebar .label { body.skin-black .sidebar .label {
padding-top: 5px; padding-top: 5px;
position: relative; position: relative;
top: -3px; top: -3px;
} }
/* line 242, ../sass/_adminlte.scss */
/* line 269, ../sass/_adminlte.scss */
body.skin-black .sidebar-menu > li.active > a { body.skin-black .sidebar-menu > li.active > a {
border-color: #F39C12; border-color: #F39C12;
} }
/* line 247, ../sass/_adminlte.scss */
/* line 274, ../sass/_adminlte.scss */
body.skin-black section.sidebar .user-panel { body.skin-black section.sidebar .user-panel {
text-align: center; text-align: center;
} }
/* line 250, ../sass/_adminlte.scss */
/* line 277, ../sass/_adminlte.scss */
body.skin-black section.sidebar .user-panel .image { body.skin-black section.sidebar .user-panel .image {
margin-bottom: 3px; margin-bottom: 3px;
} }
/* line 254, ../sass/_adminlte.scss */
/* line 281, ../sass/_adminlte.scss */
body.skin-black section.sidebar .user-panel .title { body.skin-black section.sidebar .user-panel .title {
font-weight: bold; font-weight: bold;
color: white; color: white;
} }
/* line 261, ../sass/_adminlte.scss */
/* line 288, ../sass/_adminlte.scss */
body.skin-black .content-wrapper { body.skin-black .content-wrapper {
background-color: #f5f5f5; background-color: #f5f5f5;
} }
/* line 264, ../sass/_adminlte.scss */
/* line 291, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header { body.skin-black .content-wrapper .content-header {
background-color: #F5F5F5; background-color: #F5F5F5;
padding-bottom: 15px; padding-bottom: 15px;
border-bottom: solid 1px #e0e0e0; border-bottom: solid 1px #e0e0e0;
border-top: solid 1px #e0e0e0; border-top: solid 1px #e0e0e0;
} }
/* line 270, ../sass/_adminlte.scss */
/* line 297, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header .btn { body.skin-black .content-wrapper .content-header .btn {
padding: 3px 6px; padding: 3px 6px;
font-size: 10px; font-size: 10px;
font-family: Arial; font-family: Arial;
text-transform: uppercase; text-transform: uppercase;
} }
/* line 277, ../sass/_adminlte.scss */
/* line 304, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header h1 { body.skin-black .content-wrapper .content-header h1 {
font-family: 'myriadpro-light'; font-family: 'myriadpro-light';
font-size: 20px; font-size: 20px;
} }
/* line 283, ../sass/_adminlte.scss */
/* line 310, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .col-no-padding-left { body.skin-black .content-wrapper .col-no-padding-left {
padding-left: 0px; padding-left: 0px;
} }
/* line 287, ../sass/_adminlte.scss */
/* line 314, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .col-no-padding-right { body.skin-black .content-wrapper .col-no-padding-right {
padding-right: 0px; padding-right: 0px;
} }
/* line 291, ../sass/_adminlte.scss */
/* line 318, ../sass/_adminlte.scss */
body.skin-black .content-wrapper a { body.skin-black .content-wrapper a {
color: #e08e0b; color: #e08e0b;
} }
/* line 294, ../sass/_adminlte.scss */
/* line 321, ../sass/_adminlte.scss */
body.skin-black .content-wrapper a.disable { body.skin-black .content-wrapper a.disable {
pointer-events: none; pointer-events: none;
cursor: default; cursor: default;
} }
/* line 300, ../sass/_adminlte.scss */
/* line 327, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .label { body.skin-black .content-wrapper .label {
padding-top: 4px; padding-top: 4px;
padding-bottom: 1px; padding-bottom: 1px;
} }
/* line 305, ../sass/_adminlte.scss */
/* line 332, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn { body.skin-black .content-wrapper .btn {
color: white; color: white;
} }
/* line 309, ../sass/_adminlte.scss */
/* line 336, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn-default { body.skin-black .content-wrapper .btn-default {
color: #333; color: #333;
background-color: white; background-color: white;
} }
/* line 314, ../sass/_adminlte.scss */
/* line 341, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn-primary { body.skin-black .content-wrapper .btn-primary {
background-color: #F39C12; background-color: #F39C12;
color: white; color: white;
border-color: #F39C12; border-color: #F39C12;
} }
/* line 321, ../sass/_adminlte.scss */
/* line 348, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .nav.nav-tabs .badge { body.skin-black .content-wrapper .nav.nav-tabs .badge {
margin-left: 4px; margin-left: 4px;
background-color: #e0e0e0; background-color: #e0e0e0;
color: #444; color: #444;
} }
/* line 328, ../sass/_adminlte.scss */
/* line 355, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .tab-content { body.skin-black .content-wrapper .tab-content {
border-left: solid 1px #ddd; border-left: solid 1px #ddd;
border-bottom: solid 1px #ddd; border-bottom: solid 1px #ddd;
padding: 30px 15px 15px 15px; padding: 30px 15px 15px 15px;
background-color: white; background-color: white;
} }
/* line 336, ../sass/_adminlte.scss */
/* line 363, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert { body.skin-black .content-wrapper .alert {
position: relative; position: relative;
} }
/* line 339, ../sass/_adminlte.scss */
/* line 366, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert a { body.skin-black .content-wrapper .alert a {
color: white; color: white;
} }
/* line 342, ../sass/_adminlte.scss */
/* line 369, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert a.btn { body.skin-black .content-wrapper .alert a.btn {
color: #333; color: #333;
text-decoration: none; text-decoration: none;
} }
/* line 347, ../sass/_adminlte.scss */
/* line 374, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert .close { body.skin-black .content-wrapper .alert .close {
font-size: 30px; font-size: 30px;
position: absolute; position: absolute;
color: white; color: white;
opacity: 0.6; opacity: 0.6;
} }
/* line 356, ../sass/_adminlte.scss */
/* line 383, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert .close:hover { body.skin-black .content-wrapper .alert .close:hover {
opacity: 1; opacity: 1;
} }
/* line 361, ../sass/_adminlte.scss */
/* line 388, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert.alert-dark { body.skin-black .content-wrapper .alert.alert-dark {
background-color: #ece4d8; background-color: #ece4d8;
color: black; color: black;
} }
/* line 368, ../sass/_adminlte.scss */
/* line 395, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .small-box h3 { body.skin-black .content-wrapper .small-box h3 {
font-size: 28px; font-size: 28px;
font-family: 'Source Sans Pro',sans-serif; font-family: 'Source Sans Pro',sans-serif;
} }
/* line 373, ../sass/_adminlte.scss */
/* line 400, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .small-box .icon { body.skin-black .content-wrapper .small-box .icon {
top: -2px; top: -2px;
} }
/* line 377, ../sass/_adminlte.scss */
/* line 404, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .small-box .small-box-footer { body.skin-black .content-wrapper .small-box .small-box-footer {
color: white; color: white;
padding-top: 6px; padding-top: 6px;
padding-bottom: 2px; padding-bottom: 2px;
} }
/* line 386, ../sass/_adminlte.scss */
/* line 413, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout h4 .fa { body.skin-black .content-wrapper .callout h4 .fa {
margin-right: 7px; margin-right: 7px;
} }
/* line 389, ../sass/_adminlte.scss */
/* line 416, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout a { body.skin-black .content-wrapper .callout a {
color: white; color: white;
} }
/* line 392, ../sass/_adminlte.scss */
/* line 419, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout .btn { body.skin-black .content-wrapper .callout .btn {
color: #333; color: #333;
text-decoration: none; text-decoration: none;
} }
/* line 399, ../sass/_adminlte.scss */
/* line 426, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table th { body.skin-black .content-wrapper .table th {
font-size: 13px; font-size: 13px;
} }
/* line 402, ../sass/_adminlte.scss */
/* line 429, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table th.column-actions, body.skin-black .content-wrapper .table td.column-actions { body.skin-black .content-wrapper .table th.column-actions, body.skin-black .content-wrapper .table td.column-actions {
width: 172px; width: 172px;
text-align: right; text-align: right;
} }
/* line 406, ../sass/_adminlte.scss */
/* line 433, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table td.text-small, body.skin-black .content-wrapper .table th.text-small { body.skin-black .content-wrapper .table td.text-small, body.skin-black .content-wrapper .table th.text-small {
font-size: 12px; font-size: 12px;
} }
/* line 410, ../sass/_adminlte.scss */
/* line 437, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table.table-bordered > thead > tr > th, body.skin-black .content-wrapper .table.table-bordered > tbody > tr > th, body.skin-black .content-wrapper .table.table-bordered > tfoot > tr > th, body.skin-black .content-wrapper .table.table-bordered > thead > tr > td, body.skin-black .content-wrapper .table.table-bordered > tbody > tr > td, body.skin-black .content-wrapper .table.table-bordered > tfoot > tr > td { body.skin-black .content-wrapper .table.table-bordered > thead > tr > th, body.skin-black .content-wrapper .table.table-bordered > tbody > tr > th, body.skin-black .content-wrapper .table.table-bordered > tfoot > tr > th, body.skin-black .content-wrapper .table.table-bordered > thead > tr > td, body.skin-black .content-wrapper .table.table-bordered > tbody > tr > td, body.skin-black .content-wrapper .table.table-bordered > tfoot > tr > td {
border: 1px solid #ddd; border: 1px solid #ddd;
} }
/* line 419, ../sass/_adminlte.scss */
/* line 446, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table.table-bordered > thead > tr > th, body.skin-black .content-wrapper .table.table-bordered > thead > tr > td { body.skin-black .content-wrapper .table.table-bordered > thead > tr > th, body.skin-black .content-wrapper .table.table-bordered > thead > tr > td {
border-bottom-width: 2px; border-bottom-width: 2px;
} }
/* line 425, ../sass/_adminlte.scss */
/* line 452, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > .active > a, body.skin-black .content-wrapper .pagination > .active > span, body.skin-black .content-wrapper .pagination > .active > a:hover, body.skin-black .content-wrapper .pagination > .active > span:hover, body.skin-black .content-wrapper .pagination > .active > a:focus, body.skin-black .content-wrapper .pagination > .active > span:focus { body.skin-black .content-wrapper .pagination > .active > a, body.skin-black .content-wrapper .pagination > .active > span, body.skin-black .content-wrapper .pagination > .active > a:hover, body.skin-black .content-wrapper .pagination > .active > span:hover, body.skin-black .content-wrapper .pagination > .active > a:focus, body.skin-black .content-wrapper .pagination > .active > span:focus {
background-color: #F39C12; background-color: #F39C12;
border: solid 1px #F39C12; border: solid 1px #F39C12;
color: white; color: white;
} }
/* line 431, ../sass/_adminlte.scss */
/* line 458, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > li > a, body.skin-black .content-wrapper .pagination > li > span { body.skin-black .content-wrapper .pagination > li > a, body.skin-black .content-wrapper .pagination > li > span {
color: #F39C12; color: #F39C12;
} }
/* line 433, ../sass/_adminlte.scss */
/* line 460, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .pagination > li > a:hover, body.skin-black .content-wrapper .pagination > li > span:hover { body.skin-black .content-wrapper .pagination > li > a:hover, body.skin-black .content-wrapper .pagination > li > span:hover {
color: #c87f0a; color: #c87f0a;
} }
/* line 438, ../sass/_adminlte.scss */
/* line 465, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .submenu { body.skin-black .content-wrapper .submenu {
margin-bottom: 25px; margin-bottom: 25px;
} }
/* line 442, ../sass/_adminlte.scss */
/* line 469, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-actions { body.skin-black .content-wrapper .form-actions {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
z-index: 10; z-index: 10;
border-top: solid 1px #e0e0e0; border-top: solid 1px #e0e0e0;
} }
/* line 455, ../sass/_adminlte.scss */
/* line 482, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-actions a, body.skin-black .content-wrapper .form-actions button { body.skin-black .content-wrapper .form-actions a, body.skin-black .content-wrapper .form-actions button {
margin-left: 10px; margin-left: 10px;
} }
/* line 460, ../sass/_adminlte.scss */
/* line 487, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-buttons { body.skin-black .content-wrapper .form-buttons {
margin-top: 25px; margin-top: 25px;
text-align: right; text-align: right;
} }
/* line 467, ../sass/_adminlte.scss */
/* line 494, ../sass/_adminlte.scss */
body.skin-black .main-footer a { body.skin-black .main-footer a {
color: #F39C12; color: #F39C12;
} }
/* line 472, ../sass/_adminlte.scss */
/* line 499, ../sass/_adminlte.scss */
body.skin-black .gridview-pagesize { body.skin-black .gridview-pagesize {
float: right; float: right;
margin-bottom: 8px; margin-bottom: 8px;
} }
/* line 477, ../sass/_adminlte.scss */
/* line 504, ../sass/_adminlte.scss */
body.skin-black #yii-debug-toolbar { body.skin-black #yii-debug-toolbar {
bottom: 64px; bottom: 64px;
} }


/* line 482, ../sass/_adminlte.scss */
/* line 509, ../sass/_adminlte.scss */
body.login-page { body.login-page {
background: none; background: none;
background-color: white; background-color: white;
} }
/* line 486, ../sass/_adminlte.scss */
/* line 513, ../sass/_adminlte.scss */
body.login-page .login-box .login-logo { body.login-page .login-box .login-logo {
text-align: center; text-align: center;
font-family: 'worksans_bold'; font-family: 'worksans_bold';
} }
/* line 490, ../sass/_adminlte.scss */
/* line 517, ../sass/_adminlte.scss */
body.login-page .login-box .login-logo img { body.login-page .login-box .login-logo img {
width: 150px; width: 150px;
} }
/* line 496, ../sass/_adminlte.scss */
/* line 523, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body, body.login-page .login-box .login-box-body,
body.login-page .login-box .login-box-body input#loginform-email, body.login-page .login-box .login-box-body input#loginform-email,
body.login-page .login-box .login-box-body input#loginform-password, body.login-page .login-box .login-box-body input#loginform-password,
body.login-page .login-box .login-box-body .btn-primary { body.login-page .login-box .login-box-body .btn-primary {
font-size: 14px; font-size: 14px;
} }
/* line 503, ../sass/_adminlte.scss */
/* line 530, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .btn-primary { body.login-page .login-box .login-box-body .btn-primary {
background-color: #F39C12; background-color: #F39C12;
border-color: #F39C12; border-color: #F39C12;
padding: 5px 10px; padding: 5px 10px;
margin-bottom: 15px; margin-bottom: 15px;
} }
/* line 509, ../sass/_adminlte.scss */
/* line 536, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .btn-primary:active { body.login-page .login-box .login-box-body .btn-primary:active {
background-color: #f4a62a; background-color: #f4a62a;
border-color: #F39C12; border-color: #F39C12;
} }
/* line 515, ../sass/_adminlte.scss */
/* line 542, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body a { body.login-page .login-box .login-box-body a {
color: #F39C12; color: #F39C12;
} }
/* line 517, ../sass/_adminlte.scss */
/* line 544, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body a:hover { body.login-page .login-box .login-box-body a:hover {
color: #f4a62a; color: #f4a62a;
} }
/* line 522, ../sass/_adminlte.scss */
/* line 549, ../sass/_adminlte.scss */
body.login-page .login-box .login-box-body .checkbox label input { body.login-page .login-box .login-box-body .checkbox label input {
position: relative; position: relative;
top: 0px; top: 0px;

+ 12
- 0
backend/web/js/backend.js View File

opendistrib_tinymce_responsive(); opendistrib_tinymce_responsive();
}); });


function saveData (data, fileName) {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
var blob = new Blob([data], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
}

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

+ 1
- 1
backend/web/js/vuejs/distribution-index.js View File

app.ordersUpdate = JSON.parse(JSON.stringify(response.data.orders)); app.ordersUpdate = JSON.parse(JSON.stringify(response.data.orders));


for (i = 0; i < app.orders.length; i++) { for (i = 0; i < app.orders.length; i++) {
if (!app.orders[i].date_delete) {
if (app.orders[i].order_status_alias == 'ordered' || app.orders[i].order_status_alias == 'updated') {
app.countOrders++; app.countOrders++;
} }
} }

+ 11
- 3
backend/web/js/vuejs/report-index.js View File

} }
this.reportChange(); this.reportChange();
}, },
generateReport: function () {
generateReport: function (isDownload) {
var app = this; var app = this;
app.showLoading = true; app.showLoading = true;


idsUsersArray.push(app.usersArray[i].user_id); idsUsersArray.push(app.usersArray[i].user_id);
} }
} }

var idsPointsSaleArray = []; var idsPointsSaleArray = [];
for (var i = 0; i < app.pointsSaleArray.length; i++) { for (var i = 0; i < app.pointsSaleArray.length; i++) {
if (app.pointsSaleArray[i].checked) { if (app.pointsSaleArray[i].checked) {
} }
} }


data.append('isDownload', isDownload ? 1 : 0);
data.append('users', idsUsersArray); data.append('users', idsUsersArray);
data.append('pointsSale', idsPointsSaleArray); data.append('pointsSale', idsPointsSaleArray);
data.append('distributions', idsDistributionsArray); data.append('distributions', idsDistributionsArray);


axios.post("ajax-report", data) axios.post("ajax-report", data)
.then(function (response) { .then(function (response) {
app.tableReport = response.data;
app.showLoading = false; app.showLoading = false;
app.showReport = true;

if(isDownload) {
saveData(response.data, 'rapport.csv');
}
else {
app.tableReport = response.data;
app.showReport = true;
}
}); });


}, },

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

padding: 0px 7px; padding: 0px 7px;
} }


// Labels
.label {
&.outline {
background-color: white !important;
}

&.label-default.outline {
color: #444 !important;
border: solid 1px #444;
}

&.label-success.outline {
color: #00a65a !important;
border: solid 1px #00a65a;
}

&.label-warning.outline {
color: #f39c12 !important;
border: solid 1px #f39c12;
}

&.label-danger.outline {
color: #dd4b39 !important;
border: solid 1px #dd4b39;
}
}

// Gestion des retours à la ligne (à cause de la difficulté à gérer du HTMl dans les tooltip) // Gestion des retours à la ligne (à cause de la difficulté à gérer du HTMl dans les tooltip)
.ui-tooltip { .ui-tooltip {
white-space: pre-wrap; white-space: pre-wrap;

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

$this->getTicketMessageModule(), $this->getTicketMessageModule(),
$this->getTicketModule(), $this->getTicketModule(),
$this->getPointSaleModule(), $this->getPointSaleModule(),
$this->getSharedPointSaleModule(),
$this->getProductModule(), $this->getProductModule(),
$this->getProductOrderModule(), $this->getProductOrderModule(),
$this->getOrderStatusModule(),
$this->getOrderStatusHistoryModule(),
$this->getQuotationModule(), $this->getQuotationModule(),
$this->getInvoiceModule(), $this->getInvoiceModule(),
$this->getDeliveryNoteModule(), $this->getDeliveryNoteModule(),

+ 18
- 0
common/components/BusinessLogicTrait.php View File

use domain\Feature\FeatureProducer\FeatureProducerModule; use domain\Feature\FeatureProducer\FeatureProducerModule;
use domain\Opinion\OpinionModule; use domain\Opinion\OpinionModule;
use domain\Order\Order\OrderModule; use domain\Order\Order\OrderModule;
use domain\Order\OrderStatus\OrderStatusModule;
use domain\Order\OrderStatusHistory\OrderStatusHistoryModule;
use domain\Order\ProductOrder\ProductOrderModule; use domain\Order\ProductOrder\ProductOrderModule;
use domain\Payment\PaymentModule; use domain\Payment\PaymentModule;
use domain\PointSale\PointSale\PointSaleModule; use domain\PointSale\PointSale\PointSaleModule;
use domain\PointSale\SharedPointSale\SharedPointSaleModule;
use domain\PointSale\UserPointSale\UserPointSaleModule; use domain\PointSale\UserPointSale\UserPointSaleModule;
use domain\Producer\Producer\ProducerModule; use domain\Producer\Producer\ProducerModule;
use domain\Producer\ProducerPriceRange\ProducerPriceRangeModule; use domain\Producer\ProducerPriceRange\ProducerPriceRangeModule;


trait BusinessLogicTrait trait BusinessLogicTrait
{ {
public function getOrderStatusModule(): OrderStatusModule
{
return OrderStatusModule::getInstance();
}

public function getOrderStatusHistoryModule(): OrderStatusHistoryModule
{
return OrderStatusHistoryModule::getInstance();
}

public function getUnitModule(): UnitModule public function getUnitModule(): UnitModule
{ {
return UnitModule::getInstance(); return UnitModule::getInstance();
return PointSaleModule::getInstance(); return PointSaleModule::getInstance();
} }


public function getSharedPointSaleModule(): SharedPointSaleModule
{
return SharedPointSaleModule::getInstance();
}

public function getUserPointSaleModule(): UserPointSaleModule public function getUserPointSaleModule(): UserPointSaleModule
{ {
return UserPointSaleModule::getInstance(); return UserPointSaleModule::getInstance();

+ 5
- 0
common/config/main.php View File

use domain\Document\DeliveryNote\DeliveryNote; use domain\Document\DeliveryNote\DeliveryNote;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Payment\Payment; use domain\Payment\Payment;
use domain\Producer\Producer\Producer;
use domain\Product\Product\Product; use domain\Product\Product\Product;
use domain\Ticket\Ticket\Ticket; use domain\Ticket\Ticket\Ticket;
use domain\Ticket\TicketMessage\TicketMessage; use domain\Ticket\TicketMessage\TicketMessage;
TicketMessage::class => [ TicketMessage::class => [
// Envoi email nouveau message ticket à l'administrateur // Envoi email nouveau message ticket à l'administrateur
\domain\Ticket\TicketMessage\Event\TicketMessageObserver::class, \domain\Ticket\TicketMessage\Event\TicketMessageObserver::class,
],
Producer::class => [
// Envoi d'un email à l'administrateur quand un nouveau témoignage est saisi par un producteur
domain\Producer\Producer\Event\ProducerObserver::class
] ]
], ],
], ],

+ 1
- 1
common/config/params.php View File

*/ */


return [ return [
'version' => '24.5.E',
'version' => '24.6.A',
'maintenanceMode' => false, 'maintenanceMode' => false,
'siteName' => 'Souke', 'siteName' => 'Souke',
'tinyMcePlugins' => 'preview searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link lists wordcount help', 'tinyMcePlugins' => 'preview searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link lists wordcount help',

+ 45
- 0
common/mail/newProducerTestimony-html.php View File

<?php

/**
Copyright Souke (2018)

contact@souke.fr

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 témoignage vient d'être ajouté par <strong><?= Html::encode($producer->name) ?></strong>.</p>



+ 45
- 0
common/mail/newProducerTestimony-text.php View File

<?php

/**
Copyright Souke (2018)

contact@souke.fr

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 témoignage vient d'être ajouté par <?= Html::encode($producer->name) ?>.



+ 26
- 0
common/versions/24.6.A.php View File

<?php

require_once dirname(__FILE__).'/_macros.php';

version(
'03/06/2024',
[
[
"Commandes > Système de statut de commande : les commandes sont maintenant toujours conservées en base de donnée avec un historique des actions.",
"[Boutique] Cagnotte : texte d'information personnalisable (Paramètres > Cagnotte > Description Cagnotte)",
"[Administration] Statistiques > Rapports : export CSV",
],
[
]
],
[
[
"[Administration] Témoignage producteur : alerte quand un producteur saisit un nouveau témoignage"
],
[
]
],
$userCurrent
);

?>

+ 1
- 1
console/commands/ClosingOrdersController.php View File



[$date, $hour] = $this->getDateHour(); [$date, $hour] = $this->getDateHour();
$arrayProducers = $producerModule->getRepository()->findProducers(); $arrayProducers = $producerModule->getRepository()->findProducers();
$userSystem = $userModule->getRepository()->findOneUserById(User::ID_USER_SYSTEM)
$userSystem = $userModule->getRepository()->findOneUserById(User::ID_USER_SYSTEM);


foreach($arrayProducers as $producer) { foreach($arrayProducers as $producer) {
\Yii::$app->logic->setProducerContext($producer); \Yii::$app->logic->setProducerContext($producer);

+ 65
- 0
console/commands/InitOrderStatusHistoryController.php View File

<?php

namespace console\commands;

use domain\Order\Order\OrderModule;
use domain\Order\OrderStatus\OrderStatus;
use domain\Producer\Producer\ProducerModule;
use domain\User\User\UserModule;
use yii\console\Controller;

class InitOrderStatusHistoryController extends Controller
{
// ./yii init-order-status-history/index
public function actionIndex()
{
/*
Remettre à zéro :
-----------------
DELETE FROM `order_status_history`;
UPDATE `order` SET `order`.order_status_alias = NULL;
*/

$producerModule = ProducerModule::getInstance();
$orderModule = OrderModule::getInstance();

$userSystem = UserModule::getInstance()->getRepository()->findOneUserSystem();

foreach($producerModule->getRepository()->findProducers() as $producer) {
\Yii::$app->logic->setProducerContext($producer);

$ordersArray = $orderModule->getRepository()->findOrdersWithOrderStatusAliasNull();
echo ($ordersArray ? count($ordersArray) : '0').' : '.$producer->name."\n";

while ($ordersArray && count($ordersArray)) {
foreach ($ordersArray as $order) {
$orderModule->getManager()->changeOrderStatus(
$order,
OrderStatus::ALIAS_ORDERED,
$userSystem,
new \DateTime($order->date)
);
if($order->date_update) {
$orderModule->getManager()->changeOrderStatus(
$order,
OrderStatus::ALIAS_UPDATED,
$userSystem,
new \DateTime($order->date_update)
);
}
if($order->date_delete) {
$orderModule->getManager()->changeOrderStatus(
$order,
OrderStatus::ALIAS_DELETED,
$userSystem,
new \DateTime($order->date_delete)
);
}

echo 'Order #'.$order->id."\n";
}
$ordersArray = $orderModule->getRepository()->findOrdersWithOrderStatusAliasNull();
}
}
}
}

+ 46
- 0
console/migrations/m240527_083421_create_table_order_status_history.php View File

<?php

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

/**
* Class m240527_083421_create_table_order_status_history
*/
class m240527_083421_create_table_order_status_history extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->dropColumn('order', 'status');
$this->addColumn('order', 'order_status_alias', Schema::TYPE_STRING);
$this->dropTable('order_status_history');
$this->createTable('order_status_history', [
'id' => 'pk',
'id_order' => Schema::TYPE_INTEGER,
'order_status_alias' => Schema::TYPE_STRING,
'date' => Schema::TYPE_DATETIME,
'id_user' => Schema::TYPE_INTEGER
]);
$this->createIndex('id_order', 'order_status_history', 'id_order');
$this->createIndex('id_user', 'order_status_history', 'id_user');
$this->addForeignKey('fk_id_order', 'order_status_history', 'id_order', 'order', 'id');
$this->addForeignKey('fk_id_user', 'order_status_history', 'id_user', 'user', 'id');
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropColumn('order', 'order_status_alias');
$this->addColumn('order', 'status', Schema::TYPE_STRING);

$this->dropIndex('id_order', 'order_status_history');
$this->dropIndex('id_user', 'order_status_history');
$this->dropForeignKey('fk_id_order', 'order_status_history');
$this->dropForeignKey('fk_id_user', 'order_status_history');
$this->dropTable('order_status_history');
}
}

+ 26
- 0
console/migrations/m240530_080239_add_column_producer_option_credit_description.php View File

<?php

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

/**
* Class m240530_080239_add_column_producer_option_credit_description
*/
class m240530_080239_add_column_producer_option_credit_description extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('producer', 'option_credit_description', Schema::TYPE_TEXT);
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropColumn('producer', 'option_credit_description');
}
}

+ 3
- 0
domain/Distribution/Distribution/DistributionBuilder.php View File



namespace domain\Distribution\Distribution; namespace domain\Distribution\Distribution;


use common\helpers\GlobalParam;
use domain\Distribution\Distribution\Event\DistributionActiveEvent; use domain\Distribution\Distribution\Event\DistributionActiveEvent;
use domain\Distribution\PointSaleDistribution\PointSaleDistribution; use domain\Distribution\PointSaleDistribution\PointSaleDistribution;
use domain\Distribution\PointSaleDistribution\PointSaleDistributionBuilder; use domain\Distribution\PointSaleDistribution\PointSaleDistributionBuilder;
use domain\Product\Product\Product; use domain\Product\Product\Product;
use domain\Product\Product\ProductRepository; use domain\Product\Product\ProductRepository;
use domain\Product\Product\ProductSolver; use domain\Product\Product\ProductSolver;
use domain\User\User\User;
use domain\User\UserProducer\UserProducerRepository; use domain\User\UserProducer\UserProducerRepository;
use domain\_\AbstractBuilder; use domain\_\AbstractBuilder;


if ($active) { if ($active) {
$distributionActiveEvent = new DistributionActiveEvent(); $distributionActiveEvent = new DistributionActiveEvent();
$distributionActiveEvent->distribution = $distribution; $distributionActiveEvent->distribution = $distribution;
$distributionActiveEvent->userAction = GlobalParam::getCurrentUser();
$distribution->trigger(Distribution::EVENT_ACTIVE, $distributionActiveEvent); $distribution->trigger(Distribution::EVENT_ACTIVE, $distributionActiveEvent);
} }
} }

+ 2
- 0
domain/Distribution/Distribution/Event/DistributionActiveEvent.php View File

namespace domain\Distribution\Distribution\Event; namespace domain\Distribution\Distribution\Event;


use domain\Distribution\Distribution\Distribution; use domain\Distribution\Distribution\Distribution;
use domain\User\User\User;
use yii\base\Event; use yii\base\Event;


class DistributionActiveEvent extends Event class DistributionActiveEvent extends Event
{ {
public Distribution $distribution; public Distribution $distribution;
public User $userAction;
} }

+ 42
- 3
domain/Order/Order/Order.php View File

use domain\Document\DeliveryNote\DeliveryNote; use domain\Document\DeliveryNote\DeliveryNote;
use domain\Document\Invoice\Invoice; use domain\Document\Invoice\Invoice;
use domain\Document\Quotation\Quotation; use domain\Document\Quotation\Quotation;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\OrderStatusHistory\OrderStatusHistory;
use domain\Order\ProductOrder\ProductOrder; use domain\Order\ProductOrder\ProductOrder;
use domain\Payment\Payment; use domain\Payment\Payment;
use domain\PointSale\PointSale\PointSale; use domain\PointSale\PointSale\PointSale;


class Order extends ActiveRecordCommon class Order extends ActiveRecordCommon
{ {
protected OrderStatus $orderStatusObject;

const EVENT_DELETE = 'order.event.delete'; const EVENT_DELETE = 'order.event.delete';


var $amount = 0; var $amount = 0;
const STATE_PREPARATION = 'preparation'; const STATE_PREPARATION = 'preparation';
const STATE_DELIVERED = 'delivered'; const STATE_DELIVERED = 'delivered';



public function getOrderStatusAlias(): ?string
{
return $this->order_status_alias;
}

public function setOrderStatusAlias(string $orderStatusAlias): self
{
$this->order_status_alias = $orderStatusAlias;
return $this;
}

public function getOrderStatus(): OrderStatus
{
return $this->orderStatusObject;
}

public function setOrderStatus(OrderStatus $orderStatus): self
{
$this->setOrderStatusAlias($orderStatus->getAlias());
$this->orderStatusObject = $orderStatus;
return $this;
}

public function getOrderStatusHistory(): array
{
return $this->orderStatusHistoryRelation;
}

/** /**
* @inheritdoc * @inheritdoc
*/ */
public function rules() public function rules()
{ {
return [ return [
[['id_user', 'date', 'status'], 'required', 'message' => ''],
[['id_user', 'date'], 'required', 'message' => ''],
[ [
[ [
'id_user', 'id_user',
'integer' 'integer'
], ],
[['auto_payment', 'tiller_synchronization', 'delivery_home', 'ignore_when_invoicing'], 'boolean'], [['auto_payment', 'tiller_synchronization', 'delivery_home', 'ignore_when_invoicing'], 'boolean'],
[['status', 'reference', 'delivery_address', 'online_payment_url', 'tiller_external_id'], 'string'],
[['order_status_alias', 'reference', 'delivery_address', 'online_payment_url', 'tiller_external_id'], 'string'],
[['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment', 'tiller_external_id'], 'safe'] [['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment', 'tiller_external_id'], 'safe']
]; ];
} }
'id_user' => 'Id User', 'id_user' => 'Id User',
'date' => 'Date', 'date' => 'Date',
'date_update' => 'Date de modification', 'date_update' => 'Date de modification',
'order_status_alias' => 'Statut',
'id_point_sale' => 'Point de vente', 'id_point_sale' => 'Point de vente',
'id_distribution' => 'Date de distribution', 'id_distribution' => 'Date de distribution',
'id_subscription' => 'Abonnement', 'id_subscription' => 'Abonnement',
'status' => 'Statut',
'id_invoice' => 'Facture', 'id_invoice' => 'Facture',
'id_quotation' => 'Devis', 'id_quotation' => 'Devis',
'id_delivery_note' => 'Bon de livraison', 'id_delivery_note' => 'Bon de livraison',
{ {
$this->populateFieldObject('id_delivery_note', 'deliveryNote', $deliveryNote); $this->populateFieldObject('id_delivery_note', 'deliveryNote', $deliveryNote);
} }

public function getOrderStatusHistoryRelation()
{
return $this->hasMany(OrderStatusHistory::class, ['id_order' => 'id'])
->orderBy(['order_status_history.date' => SORT_ASC]);
}
} }

+ 18
- 65
domain/Order/Order/OrderBuilder.php View File

use domain\Document\Document\DocumentSolver; use domain\Document\Document\DocumentSolver;
use domain\Document\Invoice\Invoice; use domain\Document\Invoice\Invoice;
use domain\Order\Order\Event\OrderDeleteEvent; use domain\Order\Order\Event\OrderDeleteEvent;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\OrderStatus\OrderStatusRepository;
use domain\Order\ProductOrder\ProductOrder; use domain\Order\ProductOrder\ProductOrder;
use domain\Order\ProductOrder\ProductOrderBuilder; use domain\Order\ProductOrder\ProductOrderBuilder;
use domain\Order\ProductOrder\ProductOrderSolver; use domain\Order\ProductOrder\ProductOrderSolver;
protected DeliveryNoteBuilder $deliveryNoteBuilder; protected DeliveryNoteBuilder $deliveryNoteBuilder;
protected DocumentSolver $documentSolver; protected DocumentSolver $documentSolver;
protected ProducerSolver $producerSolver; protected ProducerSolver $producerSolver;
protected OrderStatusRepository $orderStatusRepository;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->deliveryNoteBuilder = $this->loadService(DeliveryNoteBuilder::class); $this->deliveryNoteBuilder = $this->loadService(DeliveryNoteBuilder::class);
$this->documentSolver = $this->loadService(DocumentSolver::class); $this->documentSolver = $this->loadService(DocumentSolver::class);
$this->producerSolver = $this->loadService(ProducerSolver::class); $this->producerSolver = $this->loadService(ProducerSolver::class);
$this->orderStatusRepository = $this->loadService(OrderStatusRepository::class);
} }


public function instanciateOrder(Distribution $distribution): Order public function instanciateOrder(Distribution $distribution): Order
$order = new Order(); $order = new Order();
$order->populateDistribution($distribution); $order->populateDistribution($distribution);
$order->date = date('Y-m-d H:i:s'); $order->date = date('Y-m-d H:i:s');
$order->status = 'tmp-order';
$order->id_user = 0; $order->id_user = 0;


return $order; return $order;
return $order; return $order;
} }


public function initDateUpdate(Order $order)
{
$this->date_update = date('Y-m-d H:i:s');;
}

public function addProductOrdersFromSubscription(Order $order, Subscription $subscription): bool public function addProductOrdersFromSubscription(Order $order, Subscription $subscription): bool
{ {
$productsAdd = false; $productsAdd = false;
$productsAdd = true; $productsAdd = true;
} }


if (!$productsAdd) {
$this->deleteOrder($order);
}

return $productsAdd; return $productsAdd;
} }


$taxCalculationMethod = $this->getProducerContext()->option_tax_calculation_method; $taxCalculationMethod = $this->getProducerContext()->option_tax_calculation_method;
$this->initOrderAmount($order, $taxCalculationMethod); $this->initOrderAmount($order, $taxCalculationMethod);
$this->initOrderPaidAmount($order); $this->initOrderPaidAmount($order);
$this->initOrderStatus($order);
}

public function initOrderStatus(Order $order)
{
$orderStatusAlias = $order->getOrderStatusAlias() ?: OrderStatus::ALIAS_ORDERED;
$orderStatus = $this->orderStatusRepository->getOrderStatusByAlias($orderStatusAlias);
$order->setOrderStatus($orderStatus);
} }


/** /**
} }
} }


public function deleteOrder(Order $order, bool $force = false): bool
{
$return = false;
$this->initOrder($order);

// delete
if ($this->producerSolver->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_DELETE ||
($this->producerSolver->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS && strlen($order->date_delete))
|| $force) {

$this->productOrderBuilder->deleteProductOrdersByOrder($order);

$return = $this->delete($order);
}
// status 'delete'
elseif ($this->producerSolver->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS) {
$order->date_delete = date('Y-m-d H:i:s');
$return = $this->update($order);
}

if($return) {
$orderDeleteEvent = new OrderDeleteEvent();
$orderDeleteEvent->order = $order;
$order->trigger(Order::EVENT_DELETE, $orderDeleteEvent);
}

return $return;
}

/** /**
* Ajuste le crédit pour que la commande soit payée. * Ajuste le crédit pour que la commande soit payée.
*/ */
$this->saveUpdate($order); $this->saveUpdate($order);
} }


/**
* Changement de statut d'une commande.
*/
public function updateOrderStatus(Order $order, string $newStatus, string $origin): void
{
$orderStatusArray = GlobalParam::get('orderStatus');
$userCurrent = $this->userSolver->getCurrent();

switch ($newStatus) {
case 'new-order' :
$order->status = $newStatus;
$order->save();
break;
case 'waiting-paiement-on-delivery':
case 'waiting-paiement-by-credit':
case 'paid-by-credit':
case 'waiting-delevery' :
case 'delivered':
case 'refunded':
case 'cancel':
if (in_array($newStatus, $orderStatusArray[$order->status]['nextStatusAllow'])) {
$order->status = $newStatus;
$order->save();
}
break;
default:
throw new NotFoundHttpException('Statut de commande inconnu.');
}
}

// initReference // initReference
// generateReference // generateReference
public function generateOrderReference(Order $order): void public function generateOrderReference(Order $order): void
if ($pointSale->id == $order->id_point_sale) { if ($pointSale->id == $order->id_point_sale) {
$pointSale->orders[] = $order; $pointSale->orders[] = $order;


if (is_null($order->date_delete)) {
if($this->orderSolver->isOrderStatusValid($order)) {
$pointSale->revenues += (float)$order->amount; $pointSale->revenues += (float)$order->amount;
$pointSale->revenues_with_tax += (float)$order->amount_with_tax; $pointSale->revenues_with_tax += (float)$order->amount_with_tax;
} }

+ 165
- 1
domain/Order/Order/OrderManager.php View File



use domain\_\AbstractService; use domain\_\AbstractService;
use domain\_\ManagerInterface; use domain\_\ManagerInterface;
use domain\Distribution\Distribution\DistributionRepository;
use domain\Distribution\Distribution\DistributionSolver;
use domain\Order\Order\Event\OrderDeleteEvent;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\OrderStatus\OrderStatusRepository;
use domain\Order\OrderStatusHistory\OrderStatusHistoryManager;
use domain\Producer\Producer\Producer;
use domain\Producer\Producer\ProducerSolver;
use domain\Subscription\Subscription\Subscription;
use domain\Subscription\Subscription\SubscriptionRepository;
use domain\Subscription\Subscription\SubscriptionSolver;
use domain\User\User\User;


class OrderManager extends AbstractService implements ManagerInterface class OrderManager extends AbstractService implements ManagerInterface
{ {
protected ProducerSolver $producerSolver;
protected OrderBuilder $orderBuilder;
protected OrderStatusRepository $orderStatusRepository;
protected OrderStatusHistoryManager $orderStatusHistoryManager;
protected DistributionRepository $distributionRepository;
protected \domain\Subscription\Subscription\OrderManager $subscriptionOrderManager;
protected OrderRepository $orderRepository;
protected DistributionSolver $distributionSolver;
protected OrderSolver $orderSolver;
protected SubscriptionSolver $subscriptionSolver;
protected SubscriptionRepository $subscriptionRepository;

public function loadDependencies(): void
{
$this->producerSolver = $this->loadService(ProducerSolver::class);
$this->orderBuilder = $this->loadService(OrderBuilder::class);
$this->orderStatusRepository = $this->loadService(OrderStatusRepository::class);
$this->orderStatusHistoryManager = $this->loadService(OrderStatusHistoryManager::class);
$this->distributionRepository = $this->loadService(DistributionRepository::class);
$this->subscriptionOrderManager = $this->loadService(\domain\Subscription\Subscription\OrderManager::class);
$this->orderRepository = $this->loadService(OrderRepository::class);
$this->distributionSolver = $this->loadService(DistributionSolver::class);
$this->orderSolver = $this->loadService(OrderSolver::class);
$this->subscriptionSolver = $this->loadService(SubscriptionSolver::class);
$this->subscriptionRepository = $this->loadService(SubscriptionRepository::class);
}

public function changeOrderStatus(Order $order, string $orderStatusAlias, User $user, \DateTime $date = null)
{
$orderStatus = $this->orderStatusRepository->getOrderStatusByAlias($orderStatusAlias);

$order->setOrderStatus($orderStatus);
if(!$this->orderSolver->isOrderStatusOrdered($order)) {
$this->orderBuilder->initDateUpdate($order);
}
$this->orderBuilder->update($order);

$this->orderStatusHistoryManager->create(
$order,
$orderStatus,
is_null($date) ? new \DateTime() : $date,
$user
);
}

public function deleteOrder(Order $order, User $user, bool $force = false): bool
{
$return = false;
$this->orderBuilder->initOrder($order);

// delete
if ($this->producerSolver->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_DELETE ||
($this->producerSolver->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS
&& $this->orderSolver->isOrderStatusCanceled($order))
|| $force) {

$this->changeOrderStatus($order, OrderStatus::ALIAS_DELETED, $user);

}
// cancel
elseif ($this->producerSolver->getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS) {
$this->changeOrderStatus($order, OrderStatus::ALIAS_CANCELED, $user);
$this->orderBuilder->update($order);
}

if($return) {
$orderDeleteEvent = new OrderDeleteEvent();
$orderDeleteEvent->order = $order;
$order->trigger(Order::EVENT_DELETE, $orderDeleteEvent);
}

return $return;
}

public function updateOrdersIncomingDistributionsFromSubscription(Subscription $subscription, User $userAction, $update = false): array
{
$orderArray = [];
$matchedDistributionsArray = $this->distributionRepository->findDistributionsIncomingMatchWithSubscrtiption($subscription, true);

if ($update) {
$this->deleteOrdersIncomingDistributionsFromSubscription($subscription, $userAction);
}

if (count($matchedDistributionsArray)) {
foreach ($matchedDistributionsArray as $distribution) {
$orderArray[] = $this->createOrderFromSubscription($subscription, $distribution->date, $userAction);
}
}

return $orderArray;
}

public function deleteOrdersIncomingDistributionsFromSubscription(Subscription $subscription, User $userAction, bool $deleteAfterDateEnd = false): int
{
$ordersArray = $this->orderRepository->findOrdersIncomingBySubscription($subscription, !$deleteAfterDateEnd);
$countOrdersDeleted = 0;

if ($ordersArray && count($ordersArray)) {
foreach ($ordersArray as $order) {
if ($this->distributionSolver->isDistributionAvailable($order->distribution)) {
$theOrder = $this->orderRepository->findOneOrderById($order->id);
$this->orderBuilder->initOrder($theOrder);
$this->deleteOrder($order, $userAction, true);
$countOrdersDeleted++;
}
}
}

return $countOrdersDeleted;
}

public function createOrderFromSubscription(Subscription $subscription, string $date, User $userAction, bool $force = false): ?Order
{
$now = date('Y-m-d');
$distributionDate = date('Y-m-d', strtotime($date));
$distribution = $this->distributionRepository->findOneDistribution($distributionDate);

if ($distribution
&& $distribution->active
&& ($distributionDate > $now || $force)
&& count($subscription->productSubscription)
&& $subscription->pointSale) {

$order = $this->orderBuilder->createOrder($distribution);
$this->orderBuilder->updateOrderFromSubscription($order, $subscription);
$this->changeOrderStatus($order, OrderStatus::ALIAS_ORDERED, $userAction);

return $order;
}

return null;
}

public function createAllOrdersFromSubscriptions(string $date, User $userAction, bool $force = false): array
{
$ordersSubscriptionsArray = [];
$distribution = $this->distributionRepository->findOneDistribution(date('Y-m-d', strtotime($date)));

if ($distribution) {
$orderArray = $this->orderRepository->findOrdersByDistribution($distribution);
$subscriptionArray = $this->subscriptionRepository->findSubscriptionsByDate($date);
foreach ($subscriptionArray as $subscription) {
if (!$this->subscriptionSolver->hasOrderAlreadyExist($subscription, $orderArray)) {
$order = $this->createOrderFromSubscription($subscription, $date, $userAction, $force);
if ($order) {
$ordersSubscriptionsArray[] = $order;
}
}
}
}

return $ordersSubscriptionsArray;
}
} }

+ 28
- 3
domain/Order/Order/OrderRepository.php View File

use domain\Document\Invoice\Invoice; use domain\Document\Invoice\Invoice;
use domain\Document\Invoice\InvoiceRepository; use domain\Document\Invoice\InvoiceRepository;
use domain\Document\Invoice\InvoiceSolver; use domain\Document\Invoice\InvoiceSolver;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrderRepository; use domain\Order\ProductOrder\ProductOrderRepository;
use domain\Payment\Payment; use domain\Payment\Payment;
use domain\Payment\PaymentSolver; use domain\Payment\PaymentSolver;
use domain\User\User\User; use domain\User\User\User;
use domain\User\UserProducer\UserProducerRepository; use domain\User\UserProducer\UserProducerRepository;
use domain\_\AbstractRepository; use domain\_\AbstractRepository;
use phpDocumentor\Reflection\Types\Parent_;
use yii\helpers\Html; use yii\helpers\Html;


class OrderRepository extends AbstractRepository class OrderRepository extends AbstractRepository
]; ];
} }


public function defaultStatus(): void
{
parent::defaultStatus();
$this->query->filterIsOrderStatusNotDeleted();
}

public function findOrdersWithOrderStatusAliasNull()
{
$this->createQuery();
$this->defaultFilterProducerContext();

return $this->query
->filterIsOrderStatusAliasNull()
//->limit(100)
->find();
}

public function findOneOrderById(int $id) public function findOneOrderById(int $id)
{ {
return $this->createDefaultQuery() return $this->createDefaultQuery()
public function countGlobalOrdersByDateAndOrigin(\DateTime $date, string $origin = Order::ORIGIN_USER) public function countGlobalOrdersByDateAndOrigin(\DateTime $date, string $origin = Order::ORIGIN_USER)
{ {
return $this->createQuery() return $this->createQuery()
->filterIsOrderStatusNotDeleted()
->filterByDate($date) ->filterByDate($date)
->filterByOrigin($origin) ->filterByOrigin($origin)
->count(); ->count();
->where('distribution.id_producer = :id_producer') ->where('distribution.id_producer = :id_producer')
->andWhere('distribution.date >= :date_today') ->andWhere('distribution.date >= :date_today')
->andWhere('distribution.date ' . $comparatorDateStart . ' :date_start') ->andWhere('distribution.date ' . $comparatorDateStart . ' :date_start')
->andWhere('order.id_subscription = :id_subscription');
->andWhere('order.id_subscription = :id_subscription')
->andWhere(OrderRepositoryQuery::getSqlFilterIsValid());


$orders->params($params); $orders->params($params);


$paramsOrders[':date_start'] = date('Y-m-d 00:00:00'); $paramsOrders[':date_start'] = date('Y-m-d 00:00:00');
} }


$conditionsOrders .= ' AND '.OrderRepositoryQuery::getSqlFilterIsOrderStatusNotDeleted();

$ordersArray = Order::searchAll([], [ $ordersArray = Order::searchAll([], [
'orderby' => 'IF(ISNULL(date_update), `order`.`date`, `order`.`date_update`) DESC', 'orderby' => 'IF(ISNULL(date_update), `order`.`date`, `order`.`date_update`) DESC',
'conditions' => $conditionsOrders . ' AND (origin = \'' . Order::ORIGIN_USER . '\' OR origin = \'' . Order::ORIGIN_ADMIN . '\' OR (origin = \'' . Order::ORIGIN_AUTO . '\' AND (date_update IS NOT NULL OR date_delete IS NOT NULL)))',
'conditions' => $conditionsOrders . ' AND (origin = \'' . Order::ORIGIN_USER . '\' OR origin = \'' . Order::ORIGIN_ADMIN . '\' OR (origin = \'' . Order::ORIGIN_AUTO . '\' AND date_update IS NOT NULL))',
'params' => $paramsOrders, 'params' => $paramsOrders,
]); ]);


{ {
return Order::searchCount([ return Order::searchCount([
'id_user' => $user->id, 'id_user' => $user->id,
], ['conditions' => 'date_delete IS NULL']);
], [
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]);
} }


public function getTotalAmountSpent(User $user): float public function getTotalAmountSpent(User $user): float

+ 30
- 5
domain/Order/Order/OrderRepositoryQuery.php View File



use domain\Document\DeliveryNote\DeliveryNote; use domain\Document\DeliveryNote\DeliveryNote;
use domain\Document\Invoice\Invoice; use domain\Document\Invoice\Invoice;
use domain\Order\OrderStatus\OrderStatus;
use domain\User\User\User; use domain\User\User\User;
use domain\_\AbstractRepositoryQuery; use domain\_\AbstractRepositoryQuery;


return $this; return $this;
} }


public static function getSqlFilterIsValid(): string
{
return " (`order`.order_status_alias = '".OrderStatus::ALIAS_ORDERED."' OR `order`.order_status_alias = '".OrderStatus::ALIAS_UPDATED."') ";
}

public static function getSqlFilterIsOrderStatusNotDeleted(): string
{
return " (`order`.order_status_alias != '".OrderStatus::ALIAS_DELETED."') ";
}

public function filterIsValid(): self public function filterIsValid(): self
{ {
$this->andWhere('date_delete IS NULL');
$this->andWhere(self::getSqlFilterIsValid());


return $this; return $this;
} }


public function filterIsOrderStatusNotDeleted(): self
{
$this->andWhere('order_status_alias != :status_deleted')
->addParams([':status_deleted' => OrderStatus::ALIAS_DELETED]);

return $this;
}

public function filterIsOrderStatusAliasNull(): self
{
$this->andWhere('order_status_alias IS NULL');
return $this;
}

public function filterByUser(User $user): self public function filterByUser(User $user): self
{ {
$this->andWhere(['order.id_user' => $user->id]); $this->andWhere(['order.id_user' => $user->id]);
public function filterIsIncoming(): self public function filterIsIncoming(): self
{ {
$this->andWhere('distribution.date >= :date_today') $this->andWhere('distribution.date >= :date_today')
->params([':date_today' => date('Y-m-d')]);
->addParams([':date_today' => date('Y-m-d')]);


return $this; return $this;
} }
public function filterIsPassed(): self public function filterIsPassed(): self
{ {
$this->andWhere('distribution.date < :date_today') $this->andWhere('distribution.date < :date_today')
->params([':date_today' => date('Y-m-d')]);
->addParams([':date_today' => date('Y-m-d')]);


return $this; return $this;
} }
public function filterIsInvoiced(Invoice $invoice): self public function filterIsInvoiced(Invoice $invoice): self
{ {
$this->andWhere('order.id_invoice IS NOT NULL AND order.id_invoice = :id_invoice') $this->andWhere('order.id_invoice IS NOT NULL AND order.id_invoice = :id_invoice')
->params([':id_invoice' => $invoice->id]);
->addParams([':id_invoice' => $invoice->id]);


return $this; return $this;
} }
public function filterIsLinkedDeliveryNote(DeliveryNote $deliveryNote): self public function filterIsLinkedDeliveryNote(DeliveryNote $deliveryNote): self
{ {
$this->andWhere('order.id_delivery_note IS NOT NULL AND order.id_delivery_note = :id_delivery_note') $this->andWhere('order.id_delivery_note IS NOT NULL AND order.id_delivery_note = :id_delivery_note')
->params([':id_delivery_note' => $deliveryNote->id]);
->addParams([':id_delivery_note' => $deliveryNote->id]);


return $this; return $this;
} }

+ 132
- 11
domain/Order/Order/OrderSolver.php View File

use common\helpers\Price; use common\helpers\Price;
use domain\Document\Document\Document; use domain\Document\Document\Document;
use domain\Document\Document\DocumentSolver; use domain\Document\Document\DocumentSolver;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\OrderStatus\OrderStatusSolver;
use domain\Order\OrderStatusHistory\OrderStatusHistory;
use domain\Order\OrderStatusHistory\OrderStatusHistorySolver;
use domain\Order\ProductOrder\ProductOrderSolver; use domain\Order\ProductOrder\ProductOrderSolver;
use domain\Payment\Payment; use domain\Payment\Payment;
use domain\Payment\PaymentSolver; use domain\Payment\PaymentSolver;
use domain\Producer\Producer\Producer;
use domain\Producer\Producer\ProducerSolver; use domain\Producer\Producer\ProducerSolver;
use domain\Product\Product\Product; use domain\Product\Product\Product;
use domain\User\User\User; use domain\User\User\User;
protected PaymentSolver $paymentSolver; protected PaymentSolver $paymentSolver;
protected ProducerSolver $producerSolver; protected ProducerSolver $producerSolver;
protected ProductOrderSolver $productOrderSolver; protected ProductOrderSolver $productOrderSolver;
protected OrderStatusHistorySolver $orderStatusHistorySolver;
protected OrderStatusSolver $orderStatusSolver;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->paymentSolver = $this->loadService(PaymentSolver::class); $this->paymentSolver = $this->loadService(PaymentSolver::class);
$this->producerSolver = $this->loadService(ProducerSolver::class); $this->producerSolver = $this->loadService(ProducerSolver::class);
$this->productOrderSolver = $this->loadService(ProductOrderSolver::class); $this->productOrderSolver = $this->loadService(ProductOrderSolver::class);
$this->orderStatusHistorySolver = $this->loadService(OrderStatusHistorySolver::class);
$this->orderStatusSolver = $this->loadService(OrderStatusSolver::class);
} }


public function getFieldNameAmount($typeTotal = Order::AMOUNT_TOTAL, string $typeField = ''): string public function getFieldNameAmount($typeTotal = Order::AMOUNT_TOTAL, string $typeField = ''): string


if (count($ordersArray)) { if (count($ordersArray)) {
foreach ($ordersArray as $order) { foreach ($ordersArray as $order) {
if (is_null($order->date_delete)) {
if($this->isOrderStatusValid($order)) {
foreach ($order->productOrder as $productOrder) { foreach ($order->productOrder as $productOrder) {
if ($productOrder->id_product == $product->id) { if ($productOrder->id_product == $product->id) {
$quantity += $this->productOrderSolver->getQuantityPieces($productOrder); $quantity += $this->productOrderSolver->getQuantityPieces($productOrder);


if (count($ordersArray)) { if (count($ordersArray)) {
foreach ($ordersArray as $order) { foreach ($ordersArray as $order) {
if (is_null($order->date_delete) || $ignoreCancel) {
if ($this->isOrderStatusValid($order) || $ignoreCancel) {
foreach ($order->productOrder as $productOrder) { foreach ($order->productOrder as $productOrder) {
if ($productOrder->id_product == $product->id && if ($productOrder->id_product == $product->id &&
((is_null($unit) && $productOrder->product->unit == $productOrder->unit) ((is_null($unit) && $productOrder->product->unit == $productOrder->unit)
// getClassHistory // getClassHistory
public function getHistoryClass(Order $order): string public function getHistoryClass(Order $order): string
{ {
if (!is_null($order->date_delete)) {
if($this->isOrderStatusCanceled($order)) {
return 'commande-delete'; return 'commande-delete';
} }


'date' => $order->date_update 'date' => $order->date_update
]; ];
} }
if (!is_null($order->date_delete)) {
if ($this->isOrderStatusCanceled($order)) {
$arr = [ $arr = [
'class' => 'delete', 'class' => 'delete',
'glyphicon' => 'remove', 'glyphicon' => 'remove',
'str' => 'Annulée', 'str' => 'Annulée',
'date' => $order->date_delete
'date' => $this->getOrderStatusHistoryByOrderStatusAlias($order,OrderStatus::ALIAS_CANCELED)
->getDate()->format('Y-m-d H:i:s')
]; ];
} }


return '<br><span class="payment-detail-remaining-surplus">'.$text.'</span>'; return '<br><span class="payment-detail-remaining-surplus">'.$text.'</span>';
} }


public function getLabelOrderStatus(Order $order): string
{
$orderStatusCssClass = $this->getOrderStatusCssClass($order);
$orderStatusLabel = $this->getOrderStatusLabel($order);
$orderStatusHistorySummaryTitleTag = $this->getOrderStatusHistorySummaryTitleTag($order);
return '<span class="label label-'.$orderStatusCssClass.'" title="'.$orderStatusHistorySummaryTitleTag.'">'.$orderStatusLabel.'</span>';
}

/** /**
* Retourne l'origine de la commande (client, automatique ou admin) sous forme texte ou HTML. * Retourne l'origine de la commande (client, automatique ou admin) sous forme texte ou HTML.
*/ */
// getStrOrigin
public function getLabelOrigin(Order $order, bool $withLabel = false): string public function getLabelOrigin(Order $order, bool $withLabel = false): string
{ {
$classLabel = ''; $classLabel = '';


if ($order->origin == Order::ORIGIN_USER) { if ($order->origin == Order::ORIGIN_USER) {
$classLabel = 'success'; $classLabel = 'success';
$str = 'Client';
$str = $this->userSolver->isTypeGuest($order->user) ? 'Visiteur' : 'Utilisateur';
} elseif ($order->origin == Order::ORIGIN_AUTO) { } elseif ($order->origin == Order::ORIGIN_AUTO) {
$classLabel = 'default'; $classLabel = 'default';
$str = 'Auto';
$str = 'Abonnement';
} elseif ($order->origin == Order::ORIGIN_ADMIN) { } elseif ($order->origin == Order::ORIGIN_ADMIN) {
$classLabel = 'warning'; $classLabel = 'warning';
$str = 'Vous';
$str = 'Producteur';
} }


if ($withLabel) { if ($withLabel) {
return '<span class="label label-' . $classLabel . '">'
. $str . '</span>';
return '<span class="label label-' . $classLabel . ' outline">' . $str . '</span>';
} else { } else {
return $str; return $str;
} }


return $amount; return $amount;
} }

public function getOrderStatusHistoryByOrderStatusAlias(Order $order, string $orderStatusAlias): ?OrderStatusHistory
{
$orderStatusHistoryReturn = null;
foreach($order->getOrderStatusHistory() as $orderStatusHistory) {
if($orderStatusHistory->getOrderStatusAlias() == $orderStatusAlias) {
$orderStatusHistoryReturn = $orderStatusHistory;
}
}

return $orderStatusHistoryReturn;
}

public function isOrderStatusValid(Order $order): bool
{
return $this->isOrderStatusOrdered($order)
|| $this->isOrderStatusUpdated($order);
}

public function isOrderStatusCanceledOrDeleted(Order $order): bool
{
return $this->isOrderStatusCanceled($order)
|| $this->isOrderStatusDeleted($order);
}

public function isOrderStatusOrdered(Order $order): bool
{
return $order->getOrderStatusAlias() == OrderStatus::ALIAS_ORDERED;
}

public function isOrderStatusUpdated(Order $order): bool
{
return $order->getOrderStatusAlias() == OrderStatus::ALIAS_UPDATED;
}

public function isOrderStatusCanceled(Order $order): bool
{
return $order->getOrderStatusAlias() == OrderStatus::ALIAS_CANCELED;
}

public function isOrderStatusDeleted(Order $order): bool
{
return $order->getOrderStatusAlias() == OrderStatus::ALIAS_DELETED;
}

public function getLabelDeleteAction(Order $order): string
{
$optionBehaviorCancelOrder = $this->producerSolver->getConfig('option_behavior_cancel_order');

if($optionBehaviorCancelOrder == Producer::BEHAVIOR_DELETE_ORDER_STATUS && $this->isOrderStatusValid($order)) {
return 'Annuler';
}

return 'Supprimer';
}

public function getOrderStatusCssClass(Order $order): string
{
if($this->isOrderStatusOrdered($order)) {
return 'success';
}
elseif($this->isOrderStatusUpdated($order)) {
return 'warning';
}
elseif($this->isOrderStatusCanceled($order)) {
return 'danger';
}
elseif($this->isOrderStatusDeleted($order)) {
return 'danger';
}

return '';
}

public function getOrderStatusLabel(Order $order): string
{
return $this->orderStatusSolver->getLabel($order->getOrderStatusAlias());
}

public function getOrderStatusHistorySummaryTitleTag(Order $order, string $lineBreak = '&#013;'): string
{
$titleTagString = '';

foreach($order->getOrderStatusHistory() as $orderStatusHistory) {
$titleTagString .= $this->orderStatusHistorySolver->getOrderStatusHistoryLabel($orderStatusHistory).' '
.date('\l\e d/m/Y à H:i', $orderStatusHistory->getDate()->getTimestamp()).' '
.' par '.$this->userSolver->getUsername($orderStatusHistory->getUser()).' (#'.$orderStatusHistory->getUser()->getId().')'
.$lineBreak;
}

return $titleTagString;
}

public function getLastOrderStatusHistory(Order $order): ?OrderStatusHistory
{
$lastOrderStatusHistory = null;

foreach($order->getOrderStatusHistory() as $orderStatusHistory) {
if(!$lastOrderStatusHistory || $orderStatusHistory->date > $lastOrderStatusHistory->date) {
$lastOrderStatusHistory = $orderStatusHistory;
}
}

return $lastOrderStatusHistory;
}
} }

+ 5
- 4
domain/Order/Order/TillerManager.php View File

use common\components\Tiller\TillerClientV2; use common\components\Tiller\TillerClientV2;
use common\components\Tiller\TillerClientV3; use common\components\Tiller\TillerClientV3;
use common\helpers\MeanPayment; use common\helpers\MeanPayment;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrderSolver; use domain\Order\ProductOrder\ProductOrderSolver;
use domain\Producer\Producer\ProducerSolver; use domain\Producer\Producer\ProducerSolver;
use domain\_\AbstractManager; use domain\_\AbstractManager;
if (!$isSynchro) { if (!$isSynchro) {
$orders = Order::searchAll([ $orders = Order::searchAll([
'distribution.date' => $date, 'distribution.date' => $date,
'order.tiller_synchronization' => 1
'order.tiller_synchronization' => 1,
], [ ], [
'conditions' => 'date_delete IS NULL'
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]); ]);


$strDate = date('Y-m-d\T12:i:s+0000', strtotime($date) + 1); $strDate = date('Y-m-d\T12:i:s+0000', strtotime($date) + 1);


$ordersOpendistrib = Order::searchAll([ $ordersOpendistrib = Order::searchAll([
'distribution.date' => $date, 'distribution.date' => $date,
'order.tiller_synchronization' => 1
'order.tiller_synchronization' => 1,
], [ ], [
'conditions' => 'date_delete IS NULL'
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]); ]);


$ordersOpendistribSynchro = []; $ordersOpendistribSynchro = [];

+ 36
- 0
domain/Order/OrderStatus/OrderStatus.php View File

<?php

namespace domain\Order\OrderStatus;

class OrderStatus
{
const ALIAS_ORDERED = 'ordered';
const ALIAS_UPDATED = 'updated';
const ALIAS_CANCELED = 'canceled';
const ALIAS_DELETED = 'deleted';

public string $alias;
public string $name;

public function getAlias(): string
{
return $this->alias;
}

public function setAlias(string $alias): self
{
$this->alias = $alias;
return $this;
}

public function getName(): string
{
return $this->name;
}

public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}

+ 18
- 0
domain/Order/OrderStatus/OrderStatusBuilder.php View File

<?php

namespace domain\Order\OrderStatus;

use domain\_\AbstractBuilder;

class OrderStatusBuilder extends AbstractBuilder
{
public function instanciateOrderStatus(string $alias, string $name): OrderStatus
{
$orderStatus = new OrderStatus();

$orderStatus->setAlias($alias);
$orderStatus->setName($name);

return $orderStatus;
}
}

+ 31
- 0
domain/Order/OrderStatus/OrderStatusDefinition.php View File

<?php

namespace domain\Order\OrderStatus;

use domain\_\AbstractDefinition;

class OrderStatusDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return OrderStatus::class;
}

public function getOrderStatusList(): array
{
return [
OrderStatus::ALIAS_ORDERED => [
'label' => 'Créée'
],
OrderStatus::ALIAS_UPDATED => [
'label' => 'Modifiée'
],
OrderStatus::ALIAS_CANCELED => [
'label' => 'Annulée'
],
OrderStatus::ALIAS_DELETED => [
'label' => 'Supprimée'
]
];
}
}

+ 38
- 0
domain/Order/OrderStatus/OrderStatusModule.php View File

<?php

namespace domain\Order\OrderStatus;

use domain\_\AbstractModule;

class OrderStatusModule extends AbstractModule
{
public function getServices(): array
{
return [
OrderStatusDefinition::class,
OrderStatusSolver::class,
OrderStatusRepository::class,
OrderStatusBuilder::class,
];
}

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

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

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

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

+ 36
- 0
domain/Order/OrderStatus/OrderStatusRepository.php View File

<?php

namespace domain\Order\OrderStatus;

use domain\_\AbstractRepository;
use yii\base\ErrorException;

class OrderStatusRepository extends AbstractRepository
{
protected OrderStatusDefinition $orderStatusDefinition;

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

public function getDefaultOptionsSearch(): array
{
return [];
}

public function getOrderStatusByAlias(string $alias): OrderStatus
{
$orderStatusArray = $this->orderStatusDefinition->getOrderStatusList();

if(isset($orderStatusArray[$alias])) {
return OrderStatusBuilder::getInstance()->instanciateOrderStatus(
$alias,
$orderStatusArray[$alias]['label']
);
}
else {
throw new ErrorException('Statut de commande introuvable : '.$alias);
}
}
}

+ 27
- 0
domain/Order/OrderStatus/OrderStatusSolver.php View File

<?php

namespace domain\Order\OrderStatus;

use domain\_\AbstractSolver;

class OrderStatusSolver extends AbstractSolver
{
protected OrderStatusDefinition $orderStatusDefinition;

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

public function getLabel(string $orderStatusAlias): string
{
$orderStatusArray = $this->orderStatusDefinition->getOrderStatusList();

if(isset($orderStatusArray[$orderStatusAlias])) {
return $orderStatusArray[$orderStatusAlias]['label'];
}
else {
return '?';
}
}
}

+ 107
- 0
domain/Order/OrderStatusHistory/OrderStatusHistory.php View File

<?php

namespace domain\Order\OrderStatusHistory;

use common\components\ActiveRecordCommon;
use domain\Order\Order\Order;
use domain\Order\OrderStatus\OrderStatus;
use domain\User\User\User;

class OrderStatusHistory extends ActiveRecordCommon
{
protected OrderStatus $orderStatusObject;

public function getOrder(): Order
{
return $this->orderRelation;
}

public function setOrder(Order $order): self
{
$this->populateFieldObject('id_order', 'orderRelation', $order);
return $this;
}

public function getUser(): User
{
return $this->userRelation;
}

public function setUser(User $user): self
{
$this->populateFieldObject('id_user', 'userRelation', $user);
return $this;
}

public function getDate(): \DateTime
{
return new \DateTime($this->date);
}

public function setDate(\DateTime $date): self
{
$this->date = $date->format('Y-m-d H:i:s');
return $this;
}

public function getOrderStatusAlias(): string
{
return $this->order_status_alias;
}

public function setOrderStatusAlias(string $orderStatusAlias): self
{
$this->order_status_alias = $orderStatusAlias;
return $this;
}

public function getOrderStatus(): OrderStatus
{
return $this->orderStatusObject;
}

public function setOrderStatus(OrderStatus $orderStatus): self
{
$this->orderStatusObject = $orderStatus;
$this->setOrderStatusAlias($orderStatus->getAlias());
return $this;
}

public static function tableName()
{
return 'order_status_history';
}

public function rules()
{
return [
[['id_order', 'order_status_alias', 'date', 'id_user'], 'required'],
[['id_order', 'id_user'], 'integer'],
[['order_status_alias'], 'string'],
[['date'], 'safe'],
];
}

public function attributeLabels()
{
return [
'id' => 'ID',
'id_order' => 'Commande',
'order_status_alias' => 'Statut',
'date' => 'Date',
'id_user' => 'Utilisateur'
];
}

/* Relations */

protected function getOrderRelation()
{
return $this->hasOne(Order::class, ['id' => 'id_order']);
}

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

+ 28
- 0
domain/Order/OrderStatusHistory/OrderStatusHistoryBuilder.php View File

<?php

namespace domain\Order\OrderStatusHistory;

use domain\_\AbstractBuilder;
use domain\Order\Order\Order;
use domain\Order\OrderStatus\OrderStatus;
use domain\User\User\User;

class OrderStatusHistoryBuilder extends AbstractBuilder
{
public function instanciateOrderStatusHistory(
Order $order,
OrderStatus $orderStatus,
\DateTime $date,
User $user
): OrderStatusHistory
{
$orderStatusHistory = new OrderStatusHistory();

$orderStatusHistory->setOrder($order);
$orderStatusHistory->setOrderStatus($orderStatus);
$orderStatusHistory->setDate($date);
$orderStatusHistory->setUser($user);

return $orderStatusHistory;
}
}

+ 13
- 0
domain/Order/OrderStatusHistory/OrderStatusHistoryDefinition.php View File

<?php

namespace domain\Order\OrderStatusHistory;

use domain\_\AbstractDefinition;

class OrderStatusHistoryDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return OrderStatusHistory::class;
}
}

+ 30
- 0
domain/Order/OrderStatusHistory/OrderStatusHistoryManager.php View File

<?php

namespace domain\Order\OrderStatusHistory;

use domain\_\AbstractManager;
use domain\Order\Order\Order;
use domain\Order\OrderStatus\OrderStatus;
use domain\User\User\User;

class OrderStatusHistoryManager extends AbstractManager
{
protected OrderStatusHistoryBuilder $orderStatusHistoryBuilder;

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

public function create(
Order $order,
OrderStatus $orderStatus,
\DateTime $date,
User $user
): OrderStatusHistory
{
$orderStatusHistory = $this->orderStatusHistoryBuilder->instanciateOrderStatusHistory($order, $orderStatus, $date, $user);
$this->orderStatusHistoryBuilder->create($orderStatusHistory);
return $orderStatusHistory;
}
}

+ 38
- 0
domain/Order/OrderStatusHistory/OrderStatusHistoryModule.php View File

<?php

namespace domain\Order\OrderStatusHistory;

use domain\_\AbstractModule;

class OrderStatusHistoryModule extends AbstractModule
{
public function getServices(): array
{
return [
OrderStatusHistoryDefinition::class,
OrderStatusHistorySolver::class,
OrderStatusHistoryBuilder::class,
OrderStatusHistoryManager::class,
];
}

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

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

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

public function getManager(): OrderStatusHistoryManager
{
return OrderStatusHistoryManager::getInstance();
}
}

+ 21
- 0
domain/Order/OrderStatusHistory/OrderStatusHistorySolver.php View File

<?php

namespace domain\Order\OrderStatusHistory;

use domain\_\AbstractSolver;
use domain\Order\OrderStatus\OrderStatusSolver;

class OrderStatusHistorySolver extends AbstractSolver
{
protected OrderStatusSolver $orderStatusSolver;

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

public function getOrderStatusHistoryLabel(OrderStatusHistory $orderStatusHistory): string
{
return $this->orderStatusSolver->getLabel($orderStatusHistory->getOrderStatusAlias());
}
}

+ 97
- 0
domain/PointSale/SharedPointSale/SharedPointSale.php View File

<?php

namespace domain\PointSale\SharedPointSale;

use common\components\ActiveRecordCommon;
use domain\PointSale\PointSale\PointSale;
use domain\Producer\Producer\Producer;

class SharedPointSale extends ActiveRecordCommon
{
public function getPointSale(): PointSale
{
return $this->pointSaleRelation;
}

public function setPointSale(PointSale $pointSale): self
{
$this->populateFieldObject('id_point_sale', 'pointSaleRelation', $pointSale);
return $this;
}

public function getProducerWithSharing(): Producer
{
return $this->producerWithSharingRelation;
}

public function setProducerWithSharing(Producer $producerWithSharing): self
{
$this->populateFieldObject('id_producer_with_sharing', 'producerWithSharingRelation', $producerWithSharing);

return $this;
}

public function getPointSaleWithSharing(): ?PointSale
{
return $this->pointSaleWithSharing;
}

public function setPointSaleWithSharing(PointSale $pointSaleWithSharing = null): self
{
if($pointSaleWithSharing) {
$this->populateFieldObject('id_point_sale_with_sharing', 'pointSaleWithSharingRelation', $pointSaleWithSharing);
}

return $this;
}

public function getStatus(): int
{
return $this->status;
}

public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}

public static function tableName()
{
return 'shared_point_sale';
}

public function rules()
{
return [
[['id_point_sale', 'id_producer_with_sharing'], 'required'],
[['id_point_sale', 'id_producer_with_sharing', 'id_point_sale_with_sharing', 'status'], 'integer'],
];
}

public function attributeLabels()
{
return [
'id_point_sale' => 'Point de vente que vous souhaitez partager',
'id_producer_with_sharing' => 'Producteur avec qui vous souhaitez partager un point de vente',
'id_point_sale_with_sharing' => 'Point de vente du producteur avec qui vous souhaitez partager un point de vente',
];
}

/* Relations */

public function getPointSaleRelation()
{
return $this->hasOne(PointSale::class, ['id' => 'id_point_sale']);
}

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

public function getPointSaleWithSharingRelation()
{
return $this->hasOne(PointSale::class, ['id' => 'id_point_sale_with_sharing']);
}
}

+ 22
- 0
domain/PointSale/SharedPointSale/SharedPointSaleBuilder.php View File

<?php

namespace domain\PointSale\SharedPointSale;

use domain\_\AbstractBuilder;
use domain\_\StatusInterface;
use domain\PointSale\PointSale\PointSale;
use domain\Producer\Producer\Producer;

class SharedPointSaleBuilder extends AbstractBuilder
{
public function instanciateSharedPointSale(PointSale $pointSale, Producer $producerWithSharing): SharedPointSale
{
$sharedPointSale = new SharedPointSale();

$sharedPointSale->setPointSale($pointSale);
$sharedPointSale->setProducerWithSharing($producerWithSharing);
$sharedPointSale->setStatus(StatusInterface::STATUS_ONLINE);

return $sharedPointSale;
}
}

+ 13
- 0
domain/PointSale/SharedPointSale/SharedPointSaleDefinition.php View File

<?php

namespace domain\PointSale\SharedPointSale;

use domain\_\AbstractDefinition;

class SharedPointSaleDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return SharedPointSale::class;
}
}

+ 23
- 0
domain/PointSale/SharedPointSale/SharedPointSaleManager.php View File

<?php

namespace domain\PointSale\SharedPointSale;

use domain\_\AbstractManager;
use domain\PointSale\PointSale\PointSale;
use domain\Producer\Producer\Producer;

class SharedPointSaleManager extends AbstractManager
{
protected SharedPointSaleBuilder $sharedPointSaleBuilder;

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

public function createSharedPointSale(PointSale $pointSale, Producer $producerWithSharing)
{
$sharedPointSale = $this->sharedPointSaleBuilder->instanciateSharedPointSale($pointSale, $producerWithSharing);
$this->sharedPointSaleBuilder->create($sharedPointSale);
}
}

+ 32
- 0
domain/PointSale/SharedPointSale/SharedPointSaleModule.php View File

<?php

namespace domain\PointSale\SharedPointSale;

use domain\_\AbstractModule;

class SharedPointSaleModule extends AbstractModule
{
public function getServices(): array
{
return [
SharedPointSaleDefinition::class,
SharedPointSaleBuilder::class,
SharedPointSaleManager::class
];
}

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

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

public function getManager(): SharedPointSaleManager
{
return SharedPointSaleManager::getInstance();
}
}

+ 20
- 0
domain/Producer/Producer/Event/ProducerObserver.php View File

<?php

namespace domain\Producer\Producer\Event;

use domain\Producer\Producer\ProducerModule;
use justcoded\yii2\eventlistener\observers\ActiveRecordObserver;

class ProducerObserver extends ActiveRecordObserver
{
public function updated(\yii\db\AfterSaveEvent $event)
{
$producer = $event->sender;
if(isset($event->changedAttributes['option_testimony'])
&& !strlen($event->changedAttributes['option_testimony'])
&& strlen($producer->option_testimony)) {

ProducerModule::getInstance()->getNotifier()->sendEmailAdminNewTestimony($producer);
}
}
}

+ 3
- 1
domain/Producer/Producer/Producer.php View File

'option_main_color', 'option_main_color',
'option_newsletter_description', 'option_newsletter_description',
'option_leave_period_message_title', 'option_leave_period_message_title',
'option_leave_period_message'
'option_leave_period_message',
'option_credit_description',
], ],
'string' 'string'
], ],
'option_leave_period_message_display' => 'Afficher le message des congés', 'option_leave_period_message_display' => 'Afficher le message des congés',
'option_leave_period_message_title' => 'Titre du message des congés', 'option_leave_period_message_title' => 'Titre du message des congés',
'option_leave_period_message' => 'Message des congés', 'option_leave_period_message' => 'Message des congés',
'option_credit_description' => "Description Cagnotte",
]; ];
} }



+ 6
- 0
domain/Producer/Producer/ProducerModule.php View File

ProducerSolver::class, ProducerSolver::class,
ProducerRepository::class, ProducerRepository::class,
ProducerBuilder::class, ProducerBuilder::class,
ProducerNotifier::class,
ProducerManager::class, ProducerManager::class,
ProducerPageSizer::class, ProducerPageSizer::class,
DolibarrProducerUtils::class, DolibarrProducerUtils::class,
return ProducerBuilder::getInstance(); return ProducerBuilder::getInstance();
} }


public function getNotifier(): ProducerNotifier
{
return ProducerNotifier::getInstance();
}

public function getUtils(): ProducerManager public function getUtils(): ProducerManager
{ {
return ProducerManager::getInstance(); return ProducerManager::getInstance();

+ 19
- 0
domain/Producer/Producer/ProducerNotifier.php View File

<?php

namespace domain\Producer\Producer;

use domain\_\AbstractNotifier;

class ProducerNotifier extends AbstractNotifier
{
public function sendEmailAdminNewTestimony(Producer $producer)
{
$this->mailer->sendAdmin(
'Nouveau témoignage de '.$producer->name,
'newProducerTestimony',
[
'producer' => $producer,
]
);
}
}

+ 3
- 1
domain/Producer/Producer/ProducerRepository.php View File

use common\helpers\Price; use common\helpers\Price;
use domain\Document\Document\DocumentInterface; use domain\Document\Document\DocumentInterface;
use domain\Document\Document\DocumentSolver; use domain\Document\Document\DocumentSolver;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\PointSale\PointSale\PointSale; use domain\PointSale\PointSale\PointSale;
use domain\Producer\ProducerPriceRange\ProducerPriceRangeRepository; use domain\Producer\ProducerPriceRange\ProducerPriceRangeRepository;
use domain\User\User\User; use domain\User\User\User;
SELECT SUM('.$selectSum.') AS turnover SELECT SUM('.$selectSum.') AS turnover
FROM `order`, product_order, distribution, tax_rate FROM `order`, product_order, distribution, tax_rate
WHERE `order`.id = product_order.id_order WHERE `order`.id = product_order.id_order
AND `order`.date_delete IS NULL
AND '.OrderRepositoryQuery::getSqlFilterIsValid().'
AND distribution.id_producer = :id_producer AND distribution.id_producer = :id_producer
AND `order`.id_distribution = distribution.id AND `order`.id_distribution = distribution.id
AND distribution.date > :date_start AND distribution.date > :date_start

+ 3
- 2
domain/Subscription/Subscription/Event/DistributionObserver.php View File



use domain\Distribution\Distribution\Distribution; use domain\Distribution\Distribution\Distribution;
use domain\Distribution\Distribution\Event\DistributionActiveEvent; use domain\Distribution\Distribution\Event\DistributionActiveEvent;
use domain\Order\Order\OrderModule;
use justcoded\yii2\eventlistener\observers\Observer; use justcoded\yii2\eventlistener\observers\Observer;
use domain\Subscription\Subscription\SubscriptionModule; use domain\Subscription\Subscription\SubscriptionModule;


public static function onDistributionActive(DistributionActiveEvent $event): void public static function onDistributionActive(DistributionActiveEvent $event): void
{ {
$distribution = $event->distribution; $distribution = $event->distribution;
$subscriptionModule = SubscriptionModule::getInstance();
$orderModule = OrderModule::getInstance();


$subscriptionModule->getOrderManager()->createAllOrdersFromSubscriptions($distribution->date);
$orderModule->getManager()->createAllOrdersFromSubscriptions($event->distribution->date, $event->userAction);
} }
} }

+ 0
- 85
domain/Subscription/Subscription/OrderManager.php View File

$this->subscriptionRepository = $this->loadService(SubscriptionRepository::class); $this->subscriptionRepository = $this->loadService(SubscriptionRepository::class);
$this->subscriptionSolver = $this->loadService(SubscriptionSolver::class); $this->subscriptionSolver = $this->loadService(SubscriptionSolver::class);
} }

/**
* Ajoute l'abonnement' pour une date donnée.
*/
public function createOrderFromSubscription(Subscription $subscription, string $date, bool $force = false): ?Order
{
$now = date('Y-m-d');
$distributionDate = date('Y-m-d', strtotime($date));
$distribution = $this->distributionRepository->findOneDistribution($distributionDate);

if ($distribution
&& $distribution->active
&& ($distributionDate > $now || $force)
&& count($subscription->productSubscription)
&& $subscription->pointSale) {

$order = $this->orderBuilder->createOrder($distribution);
$this->orderBuilder->updateOrderFromSubscription($order, $subscription);

return $order;
}

return null;
}

/**
* Ajoute les commandes pour une date donnée à partir des abonnements.
*/
public function createAllOrdersFromSubscriptions(string $date, bool $force = false): array
{
$ordersSubscriptionsArray = [];
$distribution = $this->distributionRepository->findOneDistribution(date('Y-m-d', strtotime($date)));

if ($distribution) {
$orderArray = $this->orderRepository->findOrdersByDistribution($distribution);
$subscriptionArray = $this->subscriptionRepository->findSubscriptionsByDate($date);
foreach ($subscriptionArray as $subscription) {
if (!$this->subscriptionSolver->hasOrderAlreadyExist($subscription, $orderArray)) {
$order = $this->createOrderFromSubscription($subscription, $date, $force);
if ($order) {
$ordersSubscriptionsArray[] = $order;
}
}
}
}

return $ordersSubscriptionsArray;
}

public function updateOrdersIncomingDistributionsFromSubscription(Subscription $subscription, $update = false): array
{
$orderArray = [];
$matchedDistributionsArray = $this->distributionRepository->findDistributionsIncomingMatchWithSubscrtiption($subscription, true);

if ($update) {
$this->deleteOrdersIncomingDistributionsFromSubscription($subscription);
}

if (count($matchedDistributionsArray)) {
foreach ($matchedDistributionsArray as $distribution) {
$orderArray[] = $this->createOrderFromSubscription($subscription, $distribution->date);
}
}

return $orderArray;
}

public function deleteOrdersIncomingDistributionsFromSubscription(Subscription $subscription, bool $deleteAfterDateEnd = false): int
{
$ordersArray = $this->orderRepository->findOrdersIncomingBySubscription($subscription, !$deleteAfterDateEnd);
$countOrdersDeleted = 0;

if ($ordersArray && count($ordersArray)) {
foreach ($ordersArray as $order) {
if ($this->distributionSolver->isDistributionAvailable($order->distribution)) {
$theOrder = $this->orderRepository->findOneOrderById($order->id);
$this->orderBuilder->initOrder($theOrder);
$this->orderBuilder->deleteOrder($order, true);
$countOrdersDeleted++;
}
}
}

return $countOrdersDeleted;
}
} }

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

use domain\Producer\Producer\Producer; use domain\Producer\Producer\Producer;
use domain\User\UserProducer\UserProducerRepository; use domain\User\UserProducer\UserProducerRepository;
use domain\_\AbstractRepository; use domain\_\AbstractRepository;
use yii\base\ErrorException;
use yii\db\Query; use yii\db\Query;


class UserRepository extends AbstractRepository class UserRepository extends AbstractRepository
{ {
return $this->countUsersStatusUserOnline() + $this->countUsersStatusProducerOnline(); return $this->countUsersStatusUserOnline() + $this->countUsersStatusProducerOnline();
} }

public function findOneUserSystem(): User
{
$userSystem = $this->findOneUserById(User::ID_USER_SYSTEM);

if(!$userSystem) {
throw new ErrorException("L'utilisateur système n'existe pas dans la base de données.");
}

return $userSystem;
}
} }

+ 24
- 16
producer/controllers/OrderController.php View File

use domain\Config\Unit\UnitDefinition; use domain\Config\Unit\UnitDefinition;
use domain\Distribution\Distribution\Distribution; use domain\Distribution\Distribution\Distribution;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrder; use domain\Order\ProductOrder\ProductOrder;
use domain\PointSale\PointSale\PointSale; use domain\PointSale\PointSale\PointSale;
use domain\Producer\Producer\Producer; use domain\Producer\Producer\Producer;
->where('id_distribution = :id_distribution') ->where('id_distribution = :id_distribution')
->andWhere('id_user = :id_user') ->andWhere('id_user = :id_user')
->andWhere('id_point_sale = :id_point_sale') ->andWhere('id_point_sale = :id_point_sale')
->andWhere(OrderRepositoryQuery::getSqlFilterIsValid())
->params([ ->params([
':id_distribution' => $posts['Order']['id_distribution'], ':id_distribution' => $posts['Order']['id_distribution'],
':id_point_sale' => $posts['Order']['id_point_sale'], ':id_point_sale' => $posts['Order']['id_point_sale'],
if ($order && !$order->online_payment_url) { if ($order && !$order->online_payment_url) {
if ($order->id_point_sale != $posts['Order']['id_point_sale']) { if ($order->id_point_sale != $posts['Order']['id_point_sale']) {
$order->id_point_sale = $posts['Order']['id_point_sale']; $order->id_point_sale = $posts['Order']['id_point_sale'];
$order->date_update = date('Y-m-d H:i:s');
} }
} else { } else {
// gestion user : option_allow_order_guest // gestion user : option_allow_order_guest
$order = new Order; $order = new Order;
$order->load(\Yii::$app->request->post()); $order->load(\Yii::$app->request->post());
$order->id_user = $user ? $user->id : null; $order->id_user = $user ? $user->id : null;
$order->status = 'tmp-order';
$order->date = date('Y-m-d H:i:s'); $order->date = date('Y-m-d H:i:s');
$order->origin = Order::ORIGIN_USER; $order->origin = Order::ORIGIN_USER;
} }


$order->comment_point_sale = ($pointSale && strlen($pointSaleModule->getComment($pointSale))) ? $order->comment_point_sale = ($pointSale && strlen($pointSaleModule->getComment($pointSale))) ?
$pointSaleModule->getComment($pointSale) : ''; $pointSaleModule->getComment($pointSale) : '';
$order->date_delete = null; // la commande est automatiquement réactivée lors d'une modification

// une commande annulée est automatiquement réactivée lors d'une modification
if($orderModule->getSolver()->isOrderStatusCanceled($order)) {
$orderModule->getManager()->changeOrderStatus($order, OrderStatus::ALIAS_UPDATED, $this->getUserCurrent());
}

$order->delivery_home = isset($posts['Order']['delivery_home']) ? $posts['Order']['delivery_home'] : false; $order->delivery_home = isset($posts['Order']['delivery_home']) ? $posts['Order']['delivery_home'] : false;
$order->delivery_address = (isset($posts['Order']['delivery_address']) && $order->delivery_home) ? $posts['Order']['delivery_address'] : null; $order->delivery_address = (isset($posts['Order']['delivery_address']) && $order->delivery_home) ? $posts['Order']['delivery_address'] : null;


} }


$order->comment = isset($posts['Order']['comment']) ? $posts['Order']['comment'] : null; $order->comment = isset($posts['Order']['comment']) ? $posts['Order']['comment'] : null;
if(!$isNewOrder) {
$order->date_update = date('Y-m-d H:i:s');
}
$order->save(); $order->save();


$orderModule->generateOrderReference($order); $orderModule->generateOrderReference($order);
$orderModule->updateOrderStatus($order, 'new-order', 'user');
if($isNewOrder) {
$orderModule->getManager()->changeOrderStatus($order, OrderStatus::ALIAS_ORDERED, $user);
}
else {
$orderModule->getManager()->changeOrderStatus($order, OrderStatus::ALIAS_UPDATED, $user);
}
$producerModule->addUser($user, $producer); $producerModule->addUser($user, $producer);


// suppression de tous les enregistrements ProductOrder // suppression de tous les enregistrements ProductOrder
throw new \yii\web\NotFoundHttpException('Commande introuvable'); throw new \yii\web\NotFoundHttpException('Commande introuvable');
} }


$orderModule->initOrder($order);
$orderModule->getBuilder()->initOrder($order);


if (!$orderModule->isOrderStateOpen($order)) { if (!$orderModule->isOrderStateOpen($order)) {
throw new UserException('Vous ne pouvez plus annuler cette commande.'); throw new UserException('Vous ne pouvez plus annuler cette commande.');
} }


if ($orderModule->isOrderbelongsToUser($order, GlobalParam::getCurrentUser())) { if ($orderModule->isOrderbelongsToUser($order, GlobalParam::getCurrentUser())) {
$orderModule->deleteOrder($order);
$orderModule->getManager()->deleteOrder($order, $this->getUserCurrent());
$this->setFlash('success', 'Votre commande a bien été annulée.'); $this->setFlash('success', 'Votre commande a bien été annulée.');
} }




public function ajaxInfosOrders(Producer $producer, PointSale $pointSaleCurrent = null): array public function ajaxInfosOrders(Producer $producer, PointSale $pointSaleCurrent = null): array
{ {
$producerModule = $this->getProducerModule();
$orderModule = $this->getOrderModule(); $orderModule = $this->getOrderModule();

$dateMini = date('Y-m-d'); $dateMini = date('Y-m-d');
$ordersUserArray = []; $ordersUserArray = [];
if (GlobalParam::getCurrentUserId()) { if (GlobalParam::getCurrentUserId()) {
$paramsOrdersUser[':id_point_sale'] = $pointSaleCurrent->id; $paramsOrdersUser[':id_point_sale'] = $pointSaleCurrent->id;
} }


$conditionsOrdersUser[] = OrderRepositoryQuery::getSqlFilterIsValid();

$ordersUserArray = Order::searchAll([ $ordersUserArray = Order::searchAll([
'id_user' => GlobalParam::getCurrentUserId() 'id_user' => GlobalParam::getCurrentUserId()
], [ ], [
if (GlobalParam::getCurrentUserId()) { if (GlobalParam::getCurrentUserId()) {
$conditionOrderUser = [ $conditionOrderUser = [
'distribution.date' => $date, 'distribution.date' => $date,
'id_user' => GlobalParam::getCurrentUserId(),
'id_user' => GlobalParam::getCurrentUserId()
]; ];

if ($pointSale) { if ($pointSale) {
$conditionOrderUser['id_point_sale'] = $pointSale;
$conditionOrderUser['id_point_sale'] = $pointSale->id;
} }

$orderUser = Order::searchOne($conditionOrderUser);
$orderUser = Order::searchOne($conditionOrderUser, [
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]);


if ($orderUser && $orderUser->online_payment_url) { if ($orderUser && $orderUser->online_payment_url) {
$orderUser = null; $orderUser = null;

+ 5
- 4
producer/controllers/SubscriptionController.php View File



public function actionAjaxProcess() public function actionAjaxProcess()
{ {
$orderModule = $this->getOrderModule();
$subscriptionModule = $this->getSubscriptionModule(); $subscriptionModule = $this->getSubscriptionModule();
$model = new SubscriptionForm(); $model = new SubscriptionForm();
$model->id_producer = GlobalParam::getCurrentProducerId(); $model->id_producer = GlobalParam::getCurrentProducerId();
if ($model->load($posts) && $model->validate() && $model->save()) { if ($model->load($posts) && $model->validate() && $model->save()) {


$subscription = $subscriptionModule->getRepository()->findOneSubscriptionById($model->id); $subscription = $subscriptionModule->getRepository()->findOneSubscriptionById($model->id);
$subscriptionModule->getOrderManager()
->updateOrdersIncomingDistributionsFromSubscription($subscription, $isUpdate);
$orderModule->getManager()
->updateOrdersIncomingDistributionsFromSubscription($subscription, $this->getUserCurrent(), $isUpdate);


if ($isUpdate) { if ($isUpdate) {
$this->setFlash('success', "L'abonnement a bien été modifié"); $this->setFlash('success', "L'abonnement a bien été modifié");
if($subscription) { if($subscription) {
$subscriptionModule->getBuilder()->deleteSubscription($subscription); $subscriptionModule->getBuilder()->deleteSubscription($subscription);
// @TODO : gérer via événements // @TODO : gérer via événements
$this->getSubscriptionModule()->getOrderManager()
->deleteOrdersIncomingDistributionsFromSubscription($subscription);
$this->getOrderModule()->getManager()
->deleteOrdersIncomingDistributionsFromSubscription($subscription, $this->getUserCurrent());


$this->setFlash('success', "L'abonnement a bien été modifié"); $this->setFlash('success', "L'abonnement a bien été modifié");
} }

+ 12
- 2
producer/views/credit/history.php View File

use domain\Feature\Feature\Feature; use domain\Feature\Feature\Feature;
use domain\Feature\Feature\FeatureModule; use domain\Feature\Feature\FeatureModule;
use domain\Payment\PaymentModule; use domain\Payment\PaymentModule;
use yii\grid\GridView;
use domain\Producer\Producer\ProducerModule;use yii\grid\GridView;
use yii\helpers\Html;


$producerModule = ProducerModule::getInstance();
$paymentManager = PaymentModule::getInstance(); $paymentManager = PaymentModule::getInstance();
$featureChecker = FeatureModule::getInstance()->getChecker(); $featureChecker = FeatureModule::getInstance()->getChecker();
$producer = $this->context->getProducerCurrent(); $producer = $this->context->getProducerCurrent();
] ]
); );
} }

?> ?>


<?php
$creditDescription = $producerModule->getSolver()->getConfig('option_credit_description');
if($creditDescription): ?>
<div class="alert alert-info">
<i class="bi bi-info-circle"></i>
<?= nl2br(Html::encode($creditDescription)); ?>
</div>
<?php endif; ?>

<div class="table-responsive"> <div class="table-responsive">
<?= GridView::widget([ <?= GridView::widget([
'summary' => '', 'summary' => '',

+ 2
- 0
producer/views/layouts/main.php View File

use domain\Feature\Feature\Feature; use domain\Feature\Feature\Feature;
use domain\Feature\Feature\FeatureModule; use domain\Feature\Feature\FeatureModule;
use domain\Order\Order\Order; use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\PointSale\PointSale\PointSaleModule; use domain\PointSale\PointSale\PointSaleModule;
use domain\Producer\Producer\ProducerModule; use domain\Producer\Producer\ProducerModule;
use domain\Product\Product\ProductModule; use domain\Product\Product\ProductModule;
]) ])
->params([':date_today' => date('Y-m-d')]) ->params([':date_today' => date('Y-m-d')])
->andWhere('distribution.date >= :date_today') ->andWhere('distribution.date >= :date_today')
->andWhere(OrderRepositoryQuery::getSqlFilterIsValid())
->count(); ->count();
$labelOrders = $countOrders > 0 ? 'success' : 'default'; $labelOrders = $countOrders > 0 ? 'success' : 'default';



+ 2
- 2
producer/views/newsletter/index.php View File

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


<div class="alert alert-dark">
<i class="bi bi-info"></i>
<div class="alert alert-info">
<i class="bi bi-info-circle"></i>
<?php if($producer->option_newsletter_description): ?> <?php if($producer->option_newsletter_description): ?>
<?= nl2br(Html::encode($producer->option_newsletter_description)); ?> <?= nl2br(Html::encode($producer->option_newsletter_description)); ?>
<?php else: ?> <?php else: ?>

+ 1
- 2
producer/views/order/_form.php View File

?> ?>
<div id="bar-fixed" class="<?php if($producer->credit): ?>credit<?php else: ?>no-credit<?php endif; ?>"> <div id="bar-fixed" class="<?php if($producer->credit): ?>credit<?php else: ?>no-credit<?php endif; ?>">
<div class="container"> <div class="container">
<?php if (isset($model->id) && !$model->date_delete): ?>
<?php if (isset($model->id) && $orderModule->getSolver()->isOrderStatusValid($model)): ?>
<a href="<?php echo \Yii::$app->urlManager->createUrl(['order/cancel', 'id' => $model->id]); ?>" class="btn btn-danger cancel-order">Annuler ma commande</a> <a href="<?php echo \Yii::$app->urlManager->createUrl(['order/cancel', 'id' => $model->id]); ?>" class="btn btn-danger cancel-order">Annuler ma commande</a>
<?php endif; ?> <?php endif; ?>
<span id="total-order-bottom"><span></span> €</span> <span id="total-order-bottom"><span></span> €</span>
<?= Html::submitButton('<span class="glyphicon glyphicon-comment"></span> Commentaire', ['class' => 'btn btn-default btn-comment', 'data-placement' => 'top', 'data-toggle' => 'tooltip', 'data-original-title' => 'Ajouter un commentaire']) ?> <?= Html::submitButton('<span class="glyphicon glyphicon-comment"></span> Commentaire', ['class' => 'btn btn-default btn-comment', 'data-placement' => 'top', 'data-toggle' => 'tooltip', 'data-original-title' => 'Ajouter un commentaire']) ?>
<?php <?php
if($producer->credit): if($producer->credit):
$linkCredit = '<a class="info-credit" href="'.Yii::$app->urlManager->createUrl(['site/credit']) .'" data-toggle="tooltip" data-placement="bottom" title="En savoir plus sur le Crédit"><span class="glyphicon glyphicon-info-sign"></span></a>' ; ; $linkCredit = '<a class="info-credit" href="'.Yii::$app->urlManager->createUrl(['site/credit']) .'" data-toggle="tooltip" data-placement="bottom" title="En savoir plus sur le Crédit"><span class="glyphicon glyphicon-info-sign"></span></a>' ; ;

+ 5
- 5
producer/views/order/history.php View File

'value' => function($order) use ($orderModule) { 'value' => function($order) use ($orderModule) {
$html = '' ; $html = '' ;
if($order->date_delete) {
if($orderModule->getSolver()->isOrderStatusCanceled($order)) {
$html .= '<span class="badge text-bg-danger">Annulée</span>' ; $html .= '<span class="badge text-bg-danger">Annulée</span>' ;
} }
else { else {
if($orderModule->getState($order) == Order::STATE_DELIVERED) {
if($orderModule->getRepository()->getState($order) == Order::STATE_DELIVERED) {
$html .= '<span class="badge text-bg-success">Livrée</span>' ; $html .= '<span class="badge text-bg-success">Livrée</span>' ;
} }
elseif($orderModule->getState($order) == Order::STATE_PREPARATION) {
elseif($orderModule->getRepository()->getState($order) == Order::STATE_PREPARATION) {
$html .= '<span class="badge text-bg-warning">En préparation</span>' ; $html .= '<span class="badge text-bg-warning">En préparation</span>' ;
} }
elseif($orderModule->getState($order) == Order::STATE_OPEN) {
elseif($orderModule->getRepository()->getState($order) == Order::STATE_OPEN) {
$html .= '<span class="badge text-bg-secondary">À venir</span>' ; $html .= '<span class="badge text-bg-secondary">À venir</span>' ;
} }
} }
} }
else { else {
$html .= '<a data-bs-toggle="tooltip" data-bs-placement="top" title="Modifier" href="'.Yii::$app->urlManager->createUrl(['order/order','id'=>$order->id]).'" class="btn btn-secondary"><i class="bi bi-pencil"></i></a> '. $html .= '<a data-bs-toggle="tooltip" data-bs-placement="top" title="Modifier" href="'.Yii::$app->urlManager->createUrl(['order/order','id'=>$order->id]).'" class="btn btn-secondary"><i class="bi bi-pencil"></i></a> '.
'<a data-bs-toggle="tooltip" data-bs-placement="top" title="Annuler" href="'.Yii::$app->urlManager->createUrl(['order/cancel','id'=>$order->id]).'" class="btn btn-secondary"><i class="bi bi-trash"></i></a> '.
'<a data-bs-toggle="tooltip" data-bs-placement="top" title="'.$orderModule->getSolver()->getLabelDeleteAction($order).'" href="'.Yii::$app->urlManager->createUrl(['order/cancel','id'=>$order->id]).'" class="btn btn-secondary"><i class="bi bi-trash"></i></a> '.
(($order->id_subscription) ? '<a data-bs-toggle="tooltip" data-bs-placement="top" title="Modifier l\'abonnement associé" href="'.Yii::$app->urlManagerProducer->createUrl(['subscription/form','id'=>$order->id_subscription]).'" class="btn btn-secondary"><i class="bi bi-arrow-repeat"></i></a>' : '') ; (($order->id_subscription) ? '<a data-bs-toggle="tooltip" data-bs-placement="top" title="Modifier l\'abonnement associé" href="'.Yii::$app->urlManagerProducer->createUrl(['subscription/form','id'=>$order->id_subscription]).'" class="btn btn-secondary"><i class="bi bi-arrow-repeat"></i></a>' : '') ;
} }
} }

+ 6
- 2
producer/web/css/screen.css View File

.order-order #main #app-order-order #content-step-payment .comment { .order-order #main #app-order-order #content-step-payment .comment {
margin-bottom: 20px; margin-bottom: 20px;
} }
/* line 456, ../sass/order/_order.scss */
/* line 455, ../sass/order/_order.scss */
.order-order #main #app-order-order #content-step-payment #payment-methods {
margin-bottom: 20px;
}
/* line 460, ../sass/order/_order.scss */
.order-order #main #app-order-order #content-step-payment .credit .info { .order-order #main #app-order-order #content-step-payment .credit .info {
margin-left: 20px; margin-left: 20px;
color: gray; color: gray;
} }


/* line 469, ../sass/order/_order.scss */
/* line 473, ../sass/order/_order.scss */
#main #content .panel h3 { #main #content .panel h3 {
font-family: "worksans_bold"; font-family: "worksans_bold";
margin: 0px; margin: 0px;

+ 4
- 0
producer/web/sass/order/_order.scss View File

margin-bottom: 20px ; margin-bottom: 20px ;
} }


#payment-methods {
margin-bottom: 20px ;
}

.credit { .credit {
.info { .info {
margin-left: 20px ; margin-left: 20px ;

Loading…
Cancel
Save