Quellcode durchsuchen

Merge branch 'develop'

master
Guillaume Bourgeois vor 5 Monaten
Ursprung
Commit
98b3992fd8
73 geänderte Dateien mit 1739 neuen und 372 gelöschten Zeilen
  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 Datei anzeigen

@@ -41,6 +41,8 @@ namespace backend\controllers;
use common\helpers\MeanPayment;
use domain\Distribution\Distribution\ExportManager;
use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\User\User\User;
use Yii;
use yii\filters\AccessControl;
@@ -149,9 +151,9 @@ class CronController extends BackendController
*/
$arrayOrders = Order::searchAll([
'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');
@@ -176,7 +178,7 @@ class CronController extends BackendController
'distribution.date' => $date,
'distribution.id_producer' => $producer->id
], [
'conditions' => 'date_delete IS NULL'
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]);

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

+ 7
- 6
backend/controllers/DistributionController.php Datei anzeigen

@@ -293,7 +293,7 @@ class DistributionController extends BackendController
if ($ordersArray) {
foreach ($ordersArray as $order) {
$orderModule->initOrder($order);
if (is_null($order->date_delete)) {
if($orderModule->getSolver()->isOrderStatusValid($order)) {
$revenues += $orderModule->getOrderAmount($order);
$revenuesWithTax += $orderModule->getOrderAmountWithTax($order);
$weight += $order->weight;
@@ -318,8 +318,6 @@ class DistributionController extends BackendController
$productOrderModule = $this->getProductOrderModule();
$userProducerModule = $this->getUserProducerModule();



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

@@ -407,7 +405,10 @@ class DistributionController extends BackendController
'isCreditFunctioningMandatory' => $orderModule->getRepository()->isOrderCreditFunctioningMandatory($order),
'isCreditFunctioningUser' => $orderModule->getRepository()->isOrderCreditFunctioningUser($order),
'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"),
]);
}
}
@@ -705,8 +706,8 @@ class DistributionController extends BackendController
*/
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)) {
return Ajax::responseSuccess('Les abonnements ont bien été importés.');

+ 5
- 1
backend/controllers/DocumentController.php Datei anzeigen

@@ -48,6 +48,7 @@ use domain\Document\Document\Document;
use domain\Document\Invoice\Invoice;
use domain\Document\Quotation\Quotation;
use domain\Order\Order\Order;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrder;
use domain\Payment\Payment;
use kartik\mpdf\Pdf;
@@ -650,8 +651,10 @@ class DocumentController extends BackendController

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

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

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

+ 12
- 8
backend/controllers/OrderController.php Datei anzeigen

@@ -46,6 +46,7 @@ use domain\Distribution\Distribution\Distribution;
use domain\Distribution\PointSaleDistribution\PointSaleDistribution;
use domain\Distribution\ProductDistribution\ProductDistribution;
use domain\Order\Order\Order;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrder;
use domain\Payment\Payment;
use domain\PointSale\PointSale\PointSale;
@@ -82,7 +83,7 @@ class OrderController extends BackendController
/**
* Traite le formulaire d'ajout/modification de commande.
*/
public function processOrderForm(
/*public function processOrderForm(
Distribution $distribution,
string $date,
array $pointsSale,
@@ -163,12 +164,12 @@ class OrderController extends BackendController
}
}
}
}
}*/

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

/**
* Génère un fichier d'export des commandes au format CSV.
@@ -735,7 +736,7 @@ class OrderController extends BackendController

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

return ['success'];
@@ -750,7 +751,7 @@ class OrderController extends BackendController
$orderModule = $this->getOrderModule();
$order = $orderModule->findOneOrderById($idOrder);
if ($order) {
$orderModule->deleteOrder($order);
$orderModule->getManager()->deleteOrder($order, $this->getUserCurrent());
}

$this->redirect(['index', 'date' => $date]);
@@ -784,6 +785,7 @@ class OrderController extends BackendController
$pointSale = $pointSaleModule->findOnePointSaleById($idPointSale);
$distribution = $distributionModule->findOneDistribution($date);
$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)
&& ($idUser || strlen($username))
@@ -798,7 +800,6 @@ class OrderController extends BackendController
$order->id_distribution = $distribution->id;
$order->origin = Order::ORIGIN_ADMIN;
$order->comment = $comment;
$order->status = 'tmp-order';

if ($idUser) {
$order->id_user = $idUser;
@@ -816,6 +817,8 @@ class OrderController extends BackendController

$order->save();

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

$user = false;
$userProducer = false;
if (isset($order->user) && $order->user) {
@@ -996,12 +999,13 @@ class OrderController extends BackendController
}

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

$order->save();

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

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

+ 7
- 2
backend/controllers/PointSaleController.php Datei anzeigen

@@ -41,6 +41,8 @@ namespace backend\controllers;
use common\helpers\GlobalParam;
use domain\Distribution\PointSaleDistribution\PointSaleDistribution;
use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\PointSale\PointSale\PointSale;
use domain\PointSale\PointSale\PointSaleSearch;
use domain\PointSale\UserPointSale\UserPointSale;
@@ -194,14 +196,17 @@ class PointSaleController extends BackendController
'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')]
]
);

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


+ 6
- 2
backend/controllers/ProducerAdminController.php Datei anzeigen

@@ -41,6 +41,8 @@ namespace backend\controllers;
use common\helpers\Ajax;
use common\helpers\Alwaysdata;
use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\Producer\Producer\Producer;
use domain\Product\Product\Product;
use Yii;
@@ -190,8 +192,10 @@ class ProducerAdminController extends BackendController
if ($withOrders) {
$countOrders = Order::searchCount([
'id_user' => $idUser,
'distribution.id_producer' => $fromProducerId
], ['conditions' => 'date_delete IS NULL']);
'distribution.id_producer' => $fromProducerId,
], [
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]);
}

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

+ 24
- 7
backend/controllers/ReportController.php Datei anzeigen

@@ -42,6 +42,8 @@ use common\helpers\CSV;
use common\helpers\GlobalParam;
use common\helpers\MeanPayment;
use common\helpers\Price;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use Yii;
use yii\filters\AccessControl;

@@ -121,9 +123,8 @@ class ReportController extends BackendController

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

$posts = Yii::$app->request->post();
$isDownload = $posts['isDownload'] == 1;
$resArray = [];
$conditionUsers = $this->_generateConditionSqlReport($posts, 'users', 'id_user');
$conditionPointsSale = $this->_generateConditionSqlReport($posts, 'pointsSale', 'id_point_sale');
@@ -134,7 +135,7 @@ class ReportController extends BackendController
WHERE `order`.id = product_order.id_order
AND product.id_producer = " . ((int)GlobalParam::getCurrentProducerId()) . "
AND product_order.id_product = product.id
AND `order`.date_delete IS NULL
AND ".OrderRepositoryQuery::getSqlFilterIsValid()."
" . $conditionUsers . "
" . $conditionPointsSale . "
" . $conditionDistributions . "
@@ -145,24 +146,40 @@ class ReportController extends BackendController

$totalGlobal = 0;
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) {
$resArray[] = [
'name' => $line['name'],
'quantity' => $line['quantity'],
'quantity' => $quantity,
'total' => $total,
];
$totalGlobal += $line['total'];
}
}

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

$resArray[] = [
'name' => '',
'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)

+ 9
- 6
backend/controllers/SubscriptionController.php Datei anzeigen

@@ -151,6 +151,7 @@ class SubscriptionController extends BackendController
*/
public function actionUpdate($id)
{
$orderModule = $this->getOrderModule();
$subscriptionModule = $this->getSubscriptionModule();
$productSubscriptionModule = $this->getProductSubscriptionModule();
$productModule = $this->getProductModule();
@@ -208,8 +209,8 @@ class SubscriptionController extends BackendController
$messageOrdersDeleted = '';

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

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

if($subscription) {
$subscriptionModule->getOrderManager()->deleteOrdersIncomingDistributionsFromSubscription($subscription);
$orderModule->getManager()->deleteOrdersIncomingDistributionsFromSubscription($subscription, $this->getUserCurrent());
$subscriptionModule->deleteSubscription($subscription);
$this->setFlash('success', 'Abonnement supprimé');
}
@@ -255,6 +257,7 @@ class SubscriptionController extends BackendController

public function actionUpdateDistributions(int $idSubscription, bool $generate = false, bool $update = false)
{
$orderModule = $this->getOrderModule();
$subscriptionModule = $this->getSubscriptionModule();
$distributionModule = $this-> getDistributionModule();
$subscription = $subscriptionModule->findOneSubscriptionById($idSubscription);
@@ -263,11 +266,11 @@ class SubscriptionController extends BackendController

if ($generate) {
if ($update) {
$subscriptionModule->getOrderManager()
->deleteOrdersIncomingDistributionsFromSubscription($subscription);
$orderModule->getManager()
->deleteOrdersIncomingDistributionsFromSubscription($subscription, $this->getUserCurrent());
}
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.');
return $this->redirect(['subscription/index']);

+ 14
- 4
backend/views/dashboard/index.php Datei anzeigen

@@ -238,13 +238,13 @@ $this->setTitle('Tableau de bord');
<table class="table table-condensed table-bordered">
<thead>
<tr>
<th></th>
<th>Statut</th>
<th>Origine</th>
<th>Date</th>
<th>Client</th>
<th>Produits</th>
<th>Point de vente</th>
<th>Montant</th>
<th>Historique</th>
</tr>
</thead>
<tbody>
@@ -252,7 +252,18 @@ $this->setTitle('Tableau de bord');
<?php $orderModule->initOrder($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">
<div class="block-date">
<div class="day"><?= strftime('%A', strtotime($order->distribution->date)) ?></div>
@@ -276,7 +287,6 @@ $this->setTitle('Tableau de bord');
<td><?= $orderModule->getCartSummary($order); ?></td>
<td><?= $orderModule->getPointSaleSummary($order) ; ?></td>
<td><?= $orderModule->getOrderAmountWithTax($order, Order::AMOUNT_TOTAL, true) ; ?></td>
<td class="history"><?= $orderModule->getHistorySummary($order) ; ?></td>
</tr>
<?php endforeach; ?>
</tbody>

+ 7
- 11
backend/views/distribution/index.php Datei anzeigen

@@ -356,8 +356,8 @@ $this->setPageTitle('Distributions') ;
<th class="column-checkbox" v-if="idActivePointSale > 0">
<input type="checkbox" v-model="checkboxSelectAllOrders" @change="selectAllOrdersEvent" />
</th>
<th class="column-state">Statut</th>
<th class="column-origin">Origine</th>
<th class="column-state">État</th>
<th class="column-user">Utilisateur</th>
<th class="column-point-sale" v-if="idActivePointSale == 0">Point de vente</th>
<th class="column-amount">Montant</th>
@@ -373,16 +373,12 @@ $this->setPageTitle('Distributions') ;
<td class="column-checkbox" v-if="idActivePointSale > 0">
<input type="checkbox" v-model="order.selected" />
</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">
<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 class="column-origin" v-html="order.labelOrigin"></td>
<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 : ''">
<template v-if="order.user.name_legal_person && order.user.name_legal_person.length">
@@ -413,7 +409,7 @@ $this->setPageTitle('Distributions') ;
</div>
</td>
<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">
<order-state-payment :order="order" :producer="producer"></order-state-payment>
</a>
@@ -516,7 +512,7 @@ $this->setPageTitle('Distributions') ;
<span class="caret"></span>
</button>
<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-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>

+ 5
- 1
backend/views/producer/update.php Datei anzeigen

@@ -311,7 +311,7 @@ $this->addBreadcrumb($this->getTitle());
<?= $form->field($model, 'option_behavior_cancel_order')
->dropDownList([
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>
@@ -379,6 +379,10 @@ $this->addBreadcrumb($this->getTitle());
<?= $form->field($model, 'option_check_by_default_prevent_user_credit')
->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)): ?>
<h4>Paiement en ligne</h4>
<?php if($userModule->getAuthorizationChecker()->isGrantedAsAdministrator($userCurrent)): ?>

+ 3
- 2
backend/views/report/index.php Datei anzeigen

@@ -141,7 +141,7 @@ $this->addBreadcrumb('Rapports') ;
<tr>
<th>Produit</th>
<th>Quantité</th>
<th>Total</th>
<th>Total HT</th>
</tr>
</thead>
<tbody>
@@ -156,7 +156,8 @@ $this->addBreadcrumb('Rapports') ;
Aucune donnée disponible pour ces critères.
</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>

+ 6
- 2
backend/views/user/index.php Datei anzeigen

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

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

+ 16
- 2
backend/views/user/orders.php Datei anzeigen

@@ -62,11 +62,25 @@ $this->addBreadcrumb('Commandes') ;
//'filterModel' => $searchModel,
'dataProvider' => $dataProvider,
'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',
'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 Datei anzeigen

@@ -1547,50 +1547,74 @@ body.skin-black .badge-environment-beta {
font-size: 11px;
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 {
white-space: pre-wrap;
}
/* line 16, ../sass/_adminlte.scss */
/* line 43, ../sass/_adminlte.scss */
body.skin-black .user-without-account {
color: gray;
font-style: italic;
}
/* line 22, ../sass/_adminlte.scss */
/* line 49, ../sass/_adminlte.scss */
body.skin-black .main-header .logo {
background-color: white;
font-family: 'highvoltageregular';
font-size: 23px;
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 {
background-color: white;
text-decoration: none;
}
/* line 33, ../sass/_adminlte.scss */
/* line 60, ../sass/_adminlte.scss */
body.skin-black .main-header .logo img {
position: relative;
max-width: 300px;
max-height: 300px;
height: auto;
}
/* line 41, ../sass/_adminlte.scss */
/* line 68, ../sass/_adminlte.scss */
body.skin-black .main-header .logo .logo-lg img {
width: 90px;
top: -2px;
}
/* line 47, ../sass/_adminlte.scss */
/* line 74, ../sass/_adminlte.scss */
body.skin-black .main-header .logo .logo-mini img {
width: 50px;
}
/* line 52, ../sass/_adminlte.scss */
/* line 79, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar {
display: block;
background-color: white;
padding: 0px;
}
/* line 57, ../sass/_adminlte.scss */
/* line 84, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel {
position: relative;
float: left;
@@ -1598,11 +1622,11 @@ body.skin-black .main-header .navbar .producer-panel {
padding-left: 50px;
margin-left: 7px;
}
/* line 64, ../sass/_adminlte.scss */
/* line 91, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel.without-logo {
padding-left: 10px;
}
/* line 68, ../sass/_adminlte.scss */
/* line 95, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .logo {
position: absolute;
top: 5px;
@@ -1617,7 +1641,7 @@ body.skin-black .main-header .navbar .producer-panel .logo {
text-align: center;
overflow: hidden;
}
/* line 80, ../sass/_adminlte.scss */
/* line 107, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .logo .img-logo {
position: absolute;
top: 50%;
@@ -1626,131 +1650,131 @@ body.skin-black .main-header .navbar .producer-panel .logo .img-logo {
max-width: 35px;
max-height: 35px;
}
/* line 90, ../sass/_adminlte.scss */
/* line 117, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .title {
position: relative;
top: 2px;
text-transform: uppercase;
}
/* line 95, ../sass/_adminlte.scss */
/* line 122, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .title a {
color: #333;
}
/* line 98, ../sass/_adminlte.scss */
/* line 125, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .title a:hover {
text-decoration: underline;
}
/* line 103, ../sass/_adminlte.scss */
/* line 130, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .producer-panel .title .producer-id {
color: gray;
font-size: 13px;
}
/* line 110, ../sass/_adminlte.scss */
/* line 137, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .sidebar-toggle {
color: #333;
}
/* line 114, ../sass/_adminlte.scss */
/* line 141, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .link-support {
float: left;
padding: 15px 15px;
border-right: solid 1px #e0e0e0;
color: #333;
}
/* line 120, ../sass/_adminlte.scss */
/* line 147, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .link-support:hover {
text-decoration: none;
color: #F39C12;
}
/* line 126, ../sass/_adminlte.scss */
/* line 153, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .navbar-custom-menu .nav {
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-right > li > a {
border-left: solid 1px #e0e0e0;
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 .open > a, body.skin-black .main-header .navbar .nav .open > a:hover, body.skin-black .main-header .navbar .nav .open > a:focus,
body.skin-black .main-header .navbar .nav > .active > a {
color: #F39C12;
}
/* line 142, ../sass/_adminlte.scss */
/* line 169, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .dropdown-menu {
-moz-box-shadow: 0px 0px 4px gray;
-webkit-box-shadow: 0px 0px 4px gray;
box-shadow: 0px 0px 4px gray;
}
/* line 147, ../sass/_adminlte.scss */
/* line 174, ../sass/_adminlte.scss */
body.skin-black .main-header .logo, body.skin-black .main-header .navbar .sidebar-toggle {
border-right: solid 1px #e0e0e0;
}
/* line 151, ../sass/_adminlte.scss */
/* line 178, ../sass/_adminlte.scss */
body.skin-black .main-header .link-control-sidebar {
display: none;
}
/* line 156, ../sass/_adminlte.scss */
/* line 183, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu {
max-height: 300px;
}
/* line 159, ../sass/_adminlte.scss */
/* line 186, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a {
padding-top: 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 {
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 {
float: right;
}
/* line 171, ../sass/_adminlte.scss */
/* line 198, ../sass/_adminlte.scss */
body.skin-black .main-header .notifications-menu ul.menu li a p {
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 {
width: 400px;
}
/* line 186, ../sass/_adminlte.scss */
/* line 213, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .search-producer {
margin: 10px;
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 {
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 {
margin-bottom: 0px;
margin-left: 10px;
margin-right: 10px;
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 {
position: relative;
top: -2px;
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 {
color: #F39C12;
}
/* line 212, ../sass/_adminlte.scss */
/* line 239, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .offline {
display: none;
}
/* line 216, ../sass/_adminlte.scss */
/* line 243, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu a {
color: #333;
}
/* line 220, ../sass/_adminlte.scss */
/* line 247, ../sass/_adminlte.scss */
body.skin-black .main-header .navbar .nav li.producer-menu .producer-id {
position: relative;
top: 4px;
@@ -1758,100 +1782,100 @@ body.skin-black .main-header .navbar .nav li.producer-menu .producer-id {
font-size: 12px;
float: right;
}
/* line 231, ../sass/_adminlte.scss */
/* line 258, ../sass/_adminlte.scss */
body.skin-black .sidebar .sidebar-menu > li.header {
color: #899397;
}
/* line 235, ../sass/_adminlte.scss */
/* line 262, ../sass/_adminlte.scss */
body.skin-black .sidebar .label {
padding-top: 5px;
position: relative;
top: -3px;
}
/* line 242, ../sass/_adminlte.scss */
/* line 269, ../sass/_adminlte.scss */
body.skin-black .sidebar-menu > li.active > a {
border-color: #F39C12;
}
/* line 247, ../sass/_adminlte.scss */
/* line 274, ../sass/_adminlte.scss */
body.skin-black section.sidebar .user-panel {
text-align: center;
}
/* line 250, ../sass/_adminlte.scss */
/* line 277, ../sass/_adminlte.scss */
body.skin-black section.sidebar .user-panel .image {
margin-bottom: 3px;
}
/* line 254, ../sass/_adminlte.scss */
/* line 281, ../sass/_adminlte.scss */
body.skin-black section.sidebar .user-panel .title {
font-weight: bold;
color: white;
}
/* line 261, ../sass/_adminlte.scss */
/* line 288, ../sass/_adminlte.scss */
body.skin-black .content-wrapper {
background-color: #f5f5f5;
}
/* line 264, ../sass/_adminlte.scss */
/* line 291, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header {
background-color: #F5F5F5;
padding-bottom: 15px;
border-bottom: solid 1px #e0e0e0;
border-top: solid 1px #e0e0e0;
}
/* line 270, ../sass/_adminlte.scss */
/* line 297, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header .btn {
padding: 3px 6px;
font-size: 10px;
font-family: Arial;
text-transform: uppercase;
}
/* line 277, ../sass/_adminlte.scss */
/* line 304, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .content-header h1 {
font-family: 'myriadpro-light';
font-size: 20px;
}
/* line 283, ../sass/_adminlte.scss */
/* line 310, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .col-no-padding-left {
padding-left: 0px;
}
/* line 287, ../sass/_adminlte.scss */
/* line 314, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .col-no-padding-right {
padding-right: 0px;
}
/* line 291, ../sass/_adminlte.scss */
/* line 318, ../sass/_adminlte.scss */
body.skin-black .content-wrapper a {
color: #e08e0b;
}
/* line 294, ../sass/_adminlte.scss */
/* line 321, ../sass/_adminlte.scss */
body.skin-black .content-wrapper a.disable {
pointer-events: none;
cursor: default;
}
/* line 300, ../sass/_adminlte.scss */
/* line 327, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .label {
padding-top: 4px;
padding-bottom: 1px;
}
/* line 305, ../sass/_adminlte.scss */
/* line 332, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn {
color: white;
}
/* line 309, ../sass/_adminlte.scss */
/* line 336, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn-default {
color: #333;
background-color: white;
}
/* line 314, ../sass/_adminlte.scss */
/* line 341, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .btn-primary {
background-color: #F39C12;
color: white;
border-color: #F39C12;
}
/* line 321, ../sass/_adminlte.scss */
/* line 348, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .nav.nav-tabs .badge {
margin-left: 4px;
background-color: #e0e0e0;
color: #444;
}
/* line 328, ../sass/_adminlte.scss */
/* line 355, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .tab-content {
border-left: solid 1px #ddd;
border-bottom: solid 1px #ddd;
@@ -1859,20 +1883,20 @@ body.skin-black .content-wrapper .tab-content {
padding: 30px 15px 15px 15px;
background-color: white;
}
/* line 336, ../sass/_adminlte.scss */
/* line 363, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert {
position: relative;
}
/* line 339, ../sass/_adminlte.scss */
/* line 366, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert a {
color: white;
}
/* line 342, ../sass/_adminlte.scss */
/* line 369, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert a.btn {
color: #333;
text-decoration: none;
}
/* line 347, ../sass/_adminlte.scss */
/* line 374, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert .close {
font-size: 30px;
position: absolute;
@@ -1882,83 +1906,83 @@ body.skin-black .content-wrapper .alert .close {
color: white;
opacity: 0.6;
}
/* line 356, ../sass/_adminlte.scss */
/* line 383, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert .close:hover {
opacity: 1;
}
/* line 361, ../sass/_adminlte.scss */
/* line 388, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .alert.alert-dark {
background-color: #ece4d8;
color: black;
}
/* line 368, ../sass/_adminlte.scss */
/* line 395, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .small-box h3 {
font-size: 28px;
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 {
top: -2px;
}
/* line 377, ../sass/_adminlte.scss */
/* line 404, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .small-box .small-box-footer {
color: white;
padding-top: 6px;
padding-bottom: 2px;
}
/* line 386, ../sass/_adminlte.scss */
/* line 413, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout h4 .fa {
margin-right: 7px;
}
/* line 389, ../sass/_adminlte.scss */
/* line 416, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout a {
color: white;
}
/* line 392, ../sass/_adminlte.scss */
/* line 419, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .callout .btn {
color: #333;
text-decoration: none;
}
/* line 399, ../sass/_adminlte.scss */
/* line 426, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table th {
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 {
width: 172px;
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 {
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 {
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 {
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 {
background-color: #F39C12;
border: solid 1px #F39C12;
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 {
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 {
color: #c87f0a;
}
/* line 438, ../sass/_adminlte.scss */
/* line 465, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .submenu {
margin-bottom: 25px;
}
/* line 442, ../sass/_adminlte.scss */
/* line 469, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-actions {
position: fixed;
bottom: 0;
@@ -1972,71 +1996,71 @@ body.skin-black .content-wrapper .form-actions {
z-index: 10;
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 {
margin-left: 10px;
}
/* line 460, ../sass/_adminlte.scss */
/* line 487, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .form-buttons {
margin-top: 25px;
text-align: right;
}
/* line 467, ../sass/_adminlte.scss */
/* line 494, ../sass/_adminlte.scss */
body.skin-black .main-footer a {
color: #F39C12;
}
/* line 472, ../sass/_adminlte.scss */
/* line 499, ../sass/_adminlte.scss */
body.skin-black .gridview-pagesize {
float: right;
margin-bottom: 8px;
}
/* line 477, ../sass/_adminlte.scss */
/* line 504, ../sass/_adminlte.scss */
body.skin-black #yii-debug-toolbar {
bottom: 64px;
}

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

+ 12
- 0
backend/web/js/backend.js Datei anzeigen

@@ -61,6 +61,18 @@ $(document).ready(function () {
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 = {
getBaseUrl: function () {
return $('meta[name=baseurl]').attr('content') + '/';

+ 1
- 1
backend/web/js/vuejs/distribution-index.js Datei anzeigen

@@ -178,7 +178,7 @@ if($(selector).length) {
app.ordersUpdate = JSON.parse(JSON.stringify(response.data.orders));

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++;
}
}

+ 11
- 3
backend/web/js/vuejs/report-index.js Datei anzeigen

@@ -99,7 +99,7 @@ if($(selector).length) {
}
this.reportChange();
},
generateReport: function () {
generateReport: function (isDownload) {
var app = this;
app.showLoading = true;

@@ -110,6 +110,7 @@ if($(selector).length) {
idsUsersArray.push(app.usersArray[i].user_id);
}
}

var idsPointsSaleArray = [];
for (var i = 0; i < app.pointsSaleArray.length; i++) {
if (app.pointsSaleArray[i].checked) {
@@ -126,15 +127,22 @@ if($(selector).length) {
}
}

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

axios.post("ajax-report", data)
.then(function (response) {
app.tableReport = response.data;
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 Datei anzeigen

@@ -7,6 +7,33 @@ body.skin-black {
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)
.ui-tooltip {
white-space: pre-wrap;

+ 3
- 0
common/components/BusinessLogic.php Datei anzeigen

@@ -36,8 +36,11 @@ class BusinessLogic
$this->getTicketMessageModule(),
$this->getTicketModule(),
$this->getPointSaleModule(),
$this->getSharedPointSaleModule(),
$this->getProductModule(),
$this->getProductOrderModule(),
$this->getOrderStatusModule(),
$this->getOrderStatusHistoryModule(),
$this->getQuotationModule(),
$this->getInvoiceModule(),
$this->getDeliveryNoteModule(),

+ 18
- 0
common/components/BusinessLogicTrait.php Datei anzeigen

@@ -15,9 +15,12 @@ use domain\Feature\Feature\FeatureModule;
use domain\Feature\FeatureProducer\FeatureProducerModule;
use domain\Opinion\OpinionModule;
use domain\Order\Order\OrderModule;
use domain\Order\OrderStatus\OrderStatusModule;
use domain\Order\OrderStatusHistory\OrderStatusHistoryModule;
use domain\Order\ProductOrder\ProductOrderModule;
use domain\Payment\PaymentModule;
use domain\PointSale\PointSale\PointSaleModule;
use domain\PointSale\SharedPointSale\SharedPointSaleModule;
use domain\PointSale\UserPointSale\UserPointSaleModule;
use domain\Producer\Producer\ProducerModule;
use domain\Producer\ProducerPriceRange\ProducerPriceRangeModule;
@@ -38,6 +41,16 @@ use domain\User\UserUserGroup\UserUserGroupModule;

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

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

public function getUnitModule(): UnitModule
{
return UnitModule::getInstance();
@@ -108,6 +121,11 @@ trait BusinessLogicTrait
return PointSaleModule::getInstance();
}

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

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

+ 5
- 0
common/config/main.php Datei anzeigen

@@ -43,6 +43,7 @@ use domain\Distribution\Distribution\Distribution;
use domain\Document\DeliveryNote\DeliveryNote;
use domain\Order\Order\Order;
use domain\Payment\Payment;
use domain\Producer\Producer\Producer;
use domain\Product\Product\Product;
use domain\Ticket\Ticket\Ticket;
use domain\Ticket\TicketMessage\TicketMessage;
@@ -223,6 +224,10 @@ return [
TicketMessage::class => [
// Envoi email nouveau message ticket à l'administrateur
\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 Datei anzeigen

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

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

+ 45
- 0
common/mail/newProducerTestimony-html.php Datei anzeigen

@@ -0,0 +1,45 @@
<?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 Datei anzeigen

@@ -0,0 +1,45 @@
<?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 Datei anzeigen

@@ -0,0 +1,26 @@
<?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 Datei anzeigen

@@ -50,7 +50,7 @@ class ClosingOrdersController extends Controller

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

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

+ 65
- 0
console/commands/InitOrderStatusHistoryController.php Datei anzeigen

@@ -0,0 +1,65 @@
<?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 Datei anzeigen

@@ -0,0 +1,46 @@
<?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 Datei anzeigen

@@ -0,0 +1,26 @@
<?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 Datei anzeigen

@@ -2,6 +2,7 @@

namespace domain\Distribution\Distribution;

use common\helpers\GlobalParam;
use domain\Distribution\Distribution\Event\DistributionActiveEvent;
use domain\Distribution\PointSaleDistribution\PointSaleDistribution;
use domain\Distribution\PointSaleDistribution\PointSaleDistributionBuilder;
@@ -16,6 +17,7 @@ use domain\PointSale\PointSale\PointSaleRepository;
use domain\Product\Product\Product;
use domain\Product\Product\ProductRepository;
use domain\Product\Product\ProductSolver;
use domain\User\User\User;
use domain\User\UserProducer\UserProducerRepository;
use domain\_\AbstractBuilder;

@@ -196,6 +198,7 @@ class DistributionBuilder extends AbstractBuilder
if ($active) {
$distributionActiveEvent = new DistributionActiveEvent();
$distributionActiveEvent->distribution = $distribution;
$distributionActiveEvent->userAction = GlobalParam::getCurrentUser();
$distribution->trigger(Distribution::EVENT_ACTIVE, $distributionActiveEvent);
}
}

+ 2
- 0
domain/Distribution/Distribution/Event/DistributionActiveEvent.php Datei anzeigen

@@ -3,9 +3,11 @@
namespace domain\Distribution\Distribution\Event;

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

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

+ 42
- 3
domain/Order/Order/Order.php Datei anzeigen

@@ -43,6 +43,8 @@ use domain\Distribution\Distribution\Distribution;
use domain\Document\DeliveryNote\DeliveryNote;
use domain\Document\Invoice\Invoice;
use domain\Document\Quotation\Quotation;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\OrderStatusHistory\OrderStatusHistory;
use domain\Order\ProductOrder\ProductOrder;
use domain\Payment\Payment;
use domain\PointSale\PointSale\PointSale;
@@ -51,6 +53,8 @@ use domain\User\User\User;

class Order extends ActiveRecordCommon
{
protected OrderStatus $orderStatusObject;

const EVENT_DELETE = 'order.event.delete';

var $amount = 0;
@@ -80,6 +84,35 @@ class Order extends ActiveRecordCommon
const STATE_PREPARATION = 'preparation';
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
*/
@@ -94,7 +127,7 @@ class Order extends ActiveRecordCommon
public function rules()
{
return [
[['id_user', 'date', 'status'], 'required', 'message' => ''],
[['id_user', 'date'], 'required', 'message' => ''],
[
[
'id_user',
@@ -108,7 +141,7 @@ class Order extends ActiveRecordCommon
'integer'
],
[['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']
];
}
@@ -123,10 +156,10 @@ class Order extends ActiveRecordCommon
'id_user' => 'Id User',
'date' => 'Date',
'date_update' => 'Date de modification',
'order_status_alias' => 'Statut',
'id_point_sale' => 'Point de vente',
'id_distribution' => 'Date de distribution',
'id_subscription' => 'Abonnement',
'status' => 'Statut',
'id_invoice' => 'Facture',
'id_quotation' => 'Devis',
'id_delivery_note' => 'Bon de livraison',
@@ -228,4 +261,10 @@ class Order extends ActiveRecordCommon
{
$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 Datei anzeigen

@@ -16,6 +16,8 @@ use domain\Document\Document\DocumentInterface;
use domain\Document\Document\DocumentSolver;
use domain\Document\Invoice\Invoice;
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\ProductOrderBuilder;
use domain\Order\ProductOrder\ProductOrderSolver;
@@ -64,6 +66,7 @@ class OrderBuilder extends AbstractBuilder
protected DeliveryNoteBuilder $deliveryNoteBuilder;
protected DocumentSolver $documentSolver;
protected ProducerSolver $producerSolver;
protected OrderStatusRepository $orderStatusRepository;

public function loadDependencies(): void
{
@@ -89,6 +92,7 @@ class OrderBuilder extends AbstractBuilder
$this->deliveryNoteBuilder = $this->loadService(DeliveryNoteBuilder::class);
$this->documentSolver = $this->loadService(DocumentSolver::class);
$this->producerSolver = $this->loadService(ProducerSolver::class);
$this->orderStatusRepository = $this->loadService(OrderStatusRepository::class);
}

public function instanciateOrder(Distribution $distribution): Order
@@ -96,7 +100,6 @@ class OrderBuilder extends AbstractBuilder
$order = new Order();
$order->populateDistribution($distribution);
$order->date = date('Y-m-d H:i:s');
$order->status = 'tmp-order';
$order->id_user = 0;

return $order;
@@ -115,6 +118,11 @@ class OrderBuilder extends AbstractBuilder
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
{
$productsAdd = false;
@@ -134,10 +142,6 @@ class OrderBuilder extends AbstractBuilder
$productsAdd = true;
}

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

return $productsAdd;
}

@@ -226,6 +230,14 @@ class OrderBuilder extends AbstractBuilder
$taxCalculationMethod = $this->getProducerContext()->option_tax_calculation_method;
$this->initOrderAmount($order, $taxCalculationMethod);
$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);
}

/**
@@ -310,35 +322,6 @@ class OrderBuilder extends AbstractBuilder
}
}

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.
*/
@@ -388,36 +371,6 @@ class OrderBuilder extends AbstractBuilder
$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
// generateReference
public function generateOrderReference(Order $order): void
@@ -471,7 +424,7 @@ class OrderBuilder extends AbstractBuilder
if ($pointSale->id == $order->id_point_sale) {
$pointSale->orders[] = $order;

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

+ 165
- 1
domain/Order/Order/OrderManager.php Datei anzeigen

@@ -4,8 +4,172 @@ namespace domain\Order\Order;

use domain\_\AbstractService;
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
{
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 Datei anzeigen

@@ -11,6 +11,7 @@ use domain\Document\DeliveryNote\DeliveryNote;
use domain\Document\Invoice\Invoice;
use domain\Document\Invoice\InvoiceRepository;
use domain\Document\Invoice\InvoiceSolver;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrderRepository;
use domain\Payment\Payment;
use domain\Payment\PaymentSolver;
@@ -26,6 +27,7 @@ use domain\Subscription\Subscription\Subscription;
use domain\User\User\User;
use domain\User\UserProducer\UserProducerRepository;
use domain\_\AbstractRepository;
use phpDocumentor\Reflection\Types\Parent_;
use yii\helpers\Html;

class OrderRepository extends AbstractRepository
@@ -90,6 +92,23 @@ 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)
{
return $this->createDefaultQuery()
@@ -100,6 +119,7 @@ class OrderRepository extends AbstractRepository
public function countGlobalOrdersByDateAndOrigin(\DateTime $date, string $origin = Order::ORIGIN_USER)
{
return $this->createQuery()
->filterIsOrderStatusNotDeleted()
->filterByDate($date)
->filterByOrigin($origin)
->count();
@@ -522,7 +542,8 @@ class OrderRepository extends AbstractRepository
->where('distribution.id_producer = :id_producer')
->andWhere('distribution.date >= :date_today')
->andWhere('distribution.date ' . $comparatorDateStart . ' :date_start')
->andWhere('order.id_subscription = :id_subscription');
->andWhere('order.id_subscription = :id_subscription')
->andWhere(OrderRepositoryQuery::getSqlFilterIsValid());

$orders->params($params);

@@ -720,9 +741,11 @@ class OrderRepository extends AbstractRepository
$paramsOrders[':date_start'] = date('Y-m-d 00:00:00');
}

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

$ordersArray = Order::searchAll([], [
'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,
]);

@@ -733,7 +756,9 @@ class OrderRepository extends AbstractRepository
{
return Order::searchCount([
'id_user' => $user->id,
], ['conditions' => 'date_delete IS NULL']);
], [
'conditions' => OrderRepositoryQuery::getSqlFilterIsValid()
]);
}

public function getTotalAmountSpent(User $user): float

+ 30
- 5
domain/Order/Order/OrderRepositoryQuery.php Datei anzeigen

@@ -4,6 +4,7 @@ namespace domain\Order\Order;

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

@@ -55,13 +56,37 @@ class OrderRepositoryQuery extends AbstractRepositoryQuery
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
{
$this->andWhere('date_delete IS NULL');
$this->andWhere(self::getSqlFilterIsValid());

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
{
$this->andWhere(['order.id_user' => $user->id]);
@@ -72,7 +97,7 @@ class OrderRepositoryQuery extends AbstractRepositoryQuery
public function filterIsIncoming(): self
{
$this->andWhere('distribution.date >= :date_today')
->params([':date_today' => date('Y-m-d')]);
->addParams([':date_today' => date('Y-m-d')]);

return $this;
}
@@ -80,7 +105,7 @@ class OrderRepositoryQuery extends AbstractRepositoryQuery
public function filterIsPassed(): self
{
$this->andWhere('distribution.date < :date_today')
->params([':date_today' => date('Y-m-d')]);
->addParams([':date_today' => date('Y-m-d')]);

return $this;
}
@@ -88,7 +113,7 @@ class OrderRepositoryQuery extends AbstractRepositoryQuery
public function filterIsInvoiced(Invoice $invoice): self
{
$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;
}
@@ -96,7 +121,7 @@ class OrderRepositoryQuery extends AbstractRepositoryQuery
public function filterIsLinkedDeliveryNote(DeliveryNote $deliveryNote): self
{
$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;
}

+ 132
- 11
domain/Order/Order/OrderSolver.php Datei anzeigen

@@ -5,9 +5,14 @@ namespace domain\Order\Order;
use common\helpers\Price;
use domain\Document\Document\Document;
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\Payment\Payment;
use domain\Payment\PaymentSolver;
use domain\Producer\Producer\Producer;
use domain\Producer\Producer\ProducerSolver;
use domain\Product\Product\Product;
use domain\User\User\User;
@@ -23,6 +28,8 @@ class OrderSolver extends AbstractService implements SolverInterface
protected PaymentSolver $paymentSolver;
protected ProducerSolver $producerSolver;
protected ProductOrderSolver $productOrderSolver;
protected OrderStatusHistorySolver $orderStatusHistorySolver;
protected OrderStatusSolver $orderStatusSolver;

public function loadDependencies(): void
{
@@ -31,6 +38,8 @@ class OrderSolver extends AbstractService implements SolverInterface
$this->paymentSolver = $this->loadService(PaymentSolver::class);
$this->producerSolver = $this->loadService(ProducerSolver::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
@@ -204,7 +213,7 @@ class OrderSolver extends AbstractService implements SolverInterface

if (count($ordersArray)) {
foreach ($ordersArray as $order) {
if (is_null($order->date_delete)) {
if($this->isOrderStatusValid($order)) {
foreach ($order->productOrder as $productOrder) {
if ($productOrder->id_product == $product->id) {
$quantity += $this->productOrderSolver->getQuantityPieces($productOrder);
@@ -226,7 +235,7 @@ class OrderSolver extends AbstractService implements SolverInterface

if (count($ordersArray)) {
foreach ($ordersArray as $order) {
if (is_null($order->date_delete) || $ignoreCancel) {
if ($this->isOrderStatusValid($order) || $ignoreCancel) {
foreach ($order->productOrder as $productOrder) {
if ($productOrder->id_product == $product->id &&
((is_null($unit) && $productOrder->product->unit == $productOrder->unit)
@@ -248,7 +257,7 @@ class OrderSolver extends AbstractService implements SolverInterface
// getClassHistory
public function getHistoryClass(Order $order): string
{
if (!is_null($order->date_delete)) {
if($this->isOrderStatusCanceled($order)) {
return 'commande-delete';
}

@@ -280,12 +289,13 @@ class OrderSolver extends AbstractService implements SolverInterface
'date' => $order->date_update
];
}
if (!is_null($order->date_delete)) {
if ($this->isOrderStatusCanceled($order)) {
$arr = [
'class' => 'delete',
'glyphicon' => 'remove',
'str' => 'Annulée',
'date' => $order->date_delete
'date' => $this->getOrderStatusHistoryByOrderStatusAlias($order,OrderStatus::ALIAS_CANCELED)
->getDate()->format('Y-m-d H:i:s')
];
}

@@ -321,10 +331,17 @@ class OrderSolver extends AbstractService implements SolverInterface
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.
*/
// getStrOrigin
public function getLabelOrigin(Order $order, bool $withLabel = false): string
{
$classLabel = '';
@@ -332,18 +349,17 @@ class OrderSolver extends AbstractService implements SolverInterface

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

if ($withLabel) {
return '<span class="label label-' . $classLabel . '">'
. $str . '</span>';
return '<span class="label label-' . $classLabel . ' outline">' . $str . '</span>';
} else {
return $str;
}
@@ -546,4 +562,109 @@ class OrderSolver extends AbstractService implements SolverInterface

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 Datei anzeigen

@@ -6,6 +6,7 @@ use common\components\Tiller\TillerClientInterface;
use common\components\Tiller\TillerClientV2;
use common\components\Tiller\TillerClientV3;
use common\helpers\MeanPayment;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrderSolver;
use domain\Producer\Producer\ProducerSolver;
use domain\_\AbstractManager;
@@ -74,9 +75,9 @@ class TillerManager extends AbstractManager
if (!$isSynchro) {
$orders = Order::searchAll([
'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);
@@ -212,9 +213,9 @@ class TillerManager extends AbstractManager

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

$ordersOpendistribSynchro = [];

+ 36
- 0
domain/Order/OrderStatus/OrderStatus.php Datei anzeigen

@@ -0,0 +1,36 @@
<?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 Datei anzeigen

@@ -0,0 +1,18 @@
<?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 Datei anzeigen

@@ -0,0 +1,31 @@
<?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 Datei anzeigen

@@ -0,0 +1,38 @@
<?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 Datei anzeigen

@@ -0,0 +1,36 @@
<?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 Datei anzeigen

@@ -0,0 +1,27 @@
<?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 Datei anzeigen

@@ -0,0 +1,107 @@
<?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 Datei anzeigen

@@ -0,0 +1,28 @@
<?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 Datei anzeigen

@@ -0,0 +1,13 @@
<?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 Datei anzeigen

@@ -0,0 +1,30 @@
<?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 Datei anzeigen

@@ -0,0 +1,38 @@
<?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 Datei anzeigen

@@ -0,0 +1,21 @@
<?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 Datei anzeigen

@@ -0,0 +1,97 @@
<?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 Datei anzeigen

@@ -0,0 +1,22 @@
<?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 Datei anzeigen

@@ -0,0 +1,13 @@
<?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 Datei anzeigen

@@ -0,0 +1,23 @@
<?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 Datei anzeigen

@@ -0,0 +1,32 @@
<?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 Datei anzeigen

@@ -0,0 +1,20 @@
<?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 Datei anzeigen

@@ -259,7 +259,8 @@ class Producer extends ActiveRecordCommon
'option_main_color',
'option_newsletter_description',
'option_leave_period_message_title',
'option_leave_period_message'
'option_leave_period_message',
'option_credit_description',
],
'string'
],
@@ -540,6 +541,7 @@ class Producer extends ActiveRecordCommon
'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' => 'Message des congés',
'option_credit_description' => "Description Cagnotte",
];
}


+ 6
- 0
domain/Producer/Producer/ProducerModule.php Datei anzeigen

@@ -13,6 +13,7 @@ class ProducerModule extends AbstractModule
ProducerSolver::class,
ProducerRepository::class,
ProducerBuilder::class,
ProducerNotifier::class,
ProducerManager::class,
ProducerPageSizer::class,
DolibarrProducerUtils::class,
@@ -40,6 +41,11 @@ class ProducerModule extends AbstractModule
return ProducerBuilder::getInstance();
}

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

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

+ 19
- 0
domain/Producer/Producer/ProducerNotifier.php Datei anzeigen

@@ -0,0 +1,19 @@
<?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 Datei anzeigen

@@ -6,6 +6,8 @@ use common\helpers\Departments;
use common\helpers\Price;
use domain\Document\Document\DocumentInterface;
use domain\Document\Document\DocumentSolver;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\PointSale\PointSale\PointSale;
use domain\Producer\ProducerPriceRange\ProducerPriceRangeRepository;
use domain\User\User\User;
@@ -181,7 +183,7 @@ class ProducerRepository extends AbstractRepository
SELECT SUM('.$selectSum.') AS turnover
FROM `order`, product_order, distribution, tax_rate
WHERE `order`.id = product_order.id_order
AND `order`.date_delete IS NULL
AND '.OrderRepositoryQuery::getSqlFilterIsValid().'
AND distribution.id_producer = :id_producer
AND `order`.id_distribution = distribution.id
AND distribution.date > :date_start

+ 3
- 2
domain/Subscription/Subscription/Event/DistributionObserver.php Datei anzeigen

@@ -4,6 +4,7 @@ namespace domain\Subscription\Subscription\Event;

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

@@ -19,8 +20,8 @@ class DistributionObserver extends Observer
public static function onDistributionActive(DistributionActiveEvent $event): void
{
$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 Datei anzeigen

@@ -27,89 +27,4 @@ class OrderManager extends AbstractManager
$this->subscriptionRepository = $this->loadService(SubscriptionRepository::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 Datei anzeigen

@@ -7,6 +7,7 @@ use domain\PointSale\PointSale\PointSale;
use domain\Producer\Producer\Producer;
use domain\User\UserProducer\UserProducerRepository;
use domain\_\AbstractRepository;
use yii\base\ErrorException;
use yii\db\Query;

class UserRepository extends AbstractRepository
@@ -300,4 +301,15 @@ class UserRepository extends AbstractRepository
{
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 Datei anzeigen

@@ -44,6 +44,8 @@ use common\helpers\Password;
use domain\Config\Unit\UnitDefinition;
use domain\Distribution\Distribution\Distribution;
use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\Order\OrderStatus\OrderStatus;
use domain\Order\ProductOrder\ProductOrder;
use domain\PointSale\PointSale\PointSale;
use domain\Producer\Producer\Producer;
@@ -174,6 +176,7 @@ class OrderController extends ProducerBaseController
->where('id_distribution = :id_distribution')
->andWhere('id_user = :id_user')
->andWhere('id_point_sale = :id_point_sale')
->andWhere(OrderRepositoryQuery::getSqlFilterIsValid())
->params([
':id_distribution' => $posts['Order']['id_distribution'],
':id_point_sale' => $posts['Order']['id_point_sale'],
@@ -184,7 +187,6 @@ class OrderController extends ProducerBaseController
if ($order && !$order->online_payment_url) {
if ($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 {
// gestion user : option_allow_order_guest
@@ -228,7 +230,6 @@ class OrderController extends ProducerBaseController
$order = new Order;
$order->load(\Yii::$app->request->post());
$order->id_user = $user ? $user->id : null;
$order->status = 'tmp-order';
$order->date = date('Y-m-d H:i:s');
$order->origin = Order::ORIGIN_USER;
}
@@ -389,7 +390,12 @@ class OrderController extends ProducerBaseController

$order->comment_point_sale = ($pointSale && strlen($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_address = (isset($posts['Order']['delivery_address']) && $order->delivery_home) ? $posts['Order']['delivery_address'] : null;

@@ -400,13 +406,15 @@ class OrderController extends ProducerBaseController
}

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

$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);

// suppression de tous les enregistrements ProductOrder
@@ -547,14 +555,14 @@ class OrderController extends ProducerBaseController
throw new \yii\web\NotFoundHttpException('Commande introuvable');
}

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

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

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.');
}

@@ -730,9 +738,7 @@ class OrderController extends ProducerBaseController

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

$dateMini = date('Y-m-d');
$ordersUserArray = [];
if (GlobalParam::getCurrentUserId()) {
@@ -749,6 +755,8 @@ class OrderController extends ProducerBaseController
$paramsOrdersUser[':id_point_sale'] = $pointSaleCurrent->id;
}

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

$ordersUserArray = Order::searchAll([
'id_user' => GlobalParam::getCurrentUserId()
], [
@@ -1006,14 +1014,14 @@ class OrderController extends ProducerBaseController
if (GlobalParam::getCurrentUserId()) {
$conditionOrderUser = [
'distribution.date' => $date,
'id_user' => GlobalParam::getCurrentUserId(),
'id_user' => GlobalParam::getCurrentUserId()
];

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) {
$orderUser = null;

+ 5
- 4
producer/controllers/SubscriptionController.php Datei anzeigen

@@ -89,6 +89,7 @@ class SubscriptionController extends ProducerBaseController

public function actionAjaxProcess()
{
$orderModule = $this->getOrderModule();
$subscriptionModule = $this->getSubscriptionModule();
$model = new SubscriptionForm();
$model->id_producer = GlobalParam::getCurrentProducerId();
@@ -110,8 +111,8 @@ class SubscriptionController extends ProducerBaseController
if ($model->load($posts) && $model->validate() && $model->save()) {

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

if ($isUpdate) {
$this->setFlash('success', "L'abonnement a bien été modifié");
@@ -240,8 +241,8 @@ class SubscriptionController extends ProducerBaseController
if($subscription) {
$subscriptionModule->getBuilder()->deleteSubscription($subscription);
// @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é");
}

+ 12
- 2
producer/views/credit/history.php Datei anzeigen

@@ -39,8 +39,10 @@
use domain\Feature\Feature\Feature;
use domain\Feature\Feature\FeatureModule;
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();
$featureChecker = FeatureModule::getInstance()->getChecker();
$producer = $this->context->getProducerCurrent();
@@ -56,9 +58,17 @@ if ($featureChecker->isEnabled(Feature::ALIAS_ONLINE_PAYMENT) && $this->context-
]
);
}

?>

<?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">
<?= GridView::widget([
'summary' => '',

+ 2
- 0
producer/views/layouts/main.php Datei anzeigen

@@ -42,6 +42,7 @@ use common\helpers\Image;
use domain\Feature\Feature\Feature;
use domain\Feature\Feature\FeatureModule;
use domain\Order\Order\Order;
use domain\Order\Order\OrderRepositoryQuery;
use domain\PointSale\PointSale\PointSaleModule;
use domain\Producer\Producer\ProducerModule;
use domain\Product\Product\ProductModule;
@@ -214,6 +215,7 @@ $mainColor = $producer->option_main_color ?: '#ee6f42' ;
])
->params([':date_today' => date('Y-m-d')])
->andWhere('distribution.date >= :date_today')
->andWhere(OrderRepositoryQuery::getSqlFilterIsValid())
->count();
$labelOrders = $countOrders > 0 ? 'success' : 'default';


+ 2
- 2
producer/views/newsletter/index.php Datei anzeigen

@@ -66,8 +66,8 @@ else {
?>
<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): ?>
<?= nl2br(Html::encode($producer->option_newsletter_description)); ?>
<?php else: ?>

+ 1
- 2
producer/views/order/_form.php Datei anzeigen

@@ -269,12 +269,11 @@ $orderModule = OrderModule::getInstance();
?>
<div id="bar-fixed" class="<?php if($producer->credit): ?>credit<?php else: ?>no-credit<?php endif; ?>">
<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>
<?php endif; ?>
<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']) ?>
<?php
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>' ; ;

+ 5
- 5
producer/views/order/history.php Datei anzeigen

@@ -121,17 +121,17 @@ $this->setTitle('Mes commandes') ;
'value' => function($order) use ($orderModule) {
$html = '' ;
if($order->date_delete) {
if($orderModule->getSolver()->isOrderStatusCanceled($order)) {
$html .= '<span class="badge text-bg-danger">Annulée</span>' ;
}
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>' ;
}
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>' ;
}
elseif($orderModule->getState($order) == Order::STATE_OPEN) {
elseif($orderModule->getRepository()->getState($order) == Order::STATE_OPEN) {
$html .= '<span class="badge text-bg-secondary">À venir</span>' ;
}
}
@@ -151,7 +151,7 @@ $this->setTitle('Mes commandes') ;
}
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> '.
'<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>' : '') ;
}
}

+ 6
- 2
producer/web/css/screen.css Datei anzeigen

@@ -1625,13 +1625,17 @@ termes.
.order-order #main #app-order-order #content-step-payment .comment {
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 {
margin-left: 20px;
color: gray;
}

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

+ 4
- 0
producer/web/sass/order/_order.scss Datei anzeigen

@@ -452,6 +452,10 @@
margin-bottom: 20px ;
}

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

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

Laden…
Abbrechen
Speichern