Browse Source

Merge branch 'feature/payment' into develop

feature/souke
Guillaume Bourgeois 1 year ago
parent
commit
9367e9fe74
66 changed files with 1372 additions and 766 deletions
  1. +2
    -4
      backend/controllers/CronController.php
  2. +52
    -40
      backend/controllers/DistributionController.php
  3. +40
    -5
      backend/controllers/DocumentController.php
  4. +13
    -14
      backend/controllers/OrderController.php
  5. +1
    -1
      backend/controllers/ProducerController.php
  6. +4
    -5
      backend/controllers/UserController.php
  7. +3
    -10
      backend/models/CreditForm.php
  8. +178
    -123
      backend/views/distribution/index.php
  9. +69
    -3
      backend/views/document/_form.php
  10. +1
    -0
      backend/views/document/update.php
  11. +19
    -2
      backend/views/invoice/index.php
  12. +12
    -12
      backend/views/user/credit.php
  13. +68
    -43
      backend/web/css/screen.css
  14. +53
    -1
      backend/web/js/vuejs/distribution-index.js
  15. +1
    -1
      backend/web/sass/_adminlte.scss
  16. +29
    -3
      backend/web/sass/distribution/_index.scss
  17. +1
    -1
      common/components/BusinessLogic.php
  18. +6
    -6
      common/components/BusinessLogicTrait.php
  19. +5
    -5
      common/config/main.php
  20. +3
    -1
      common/helpers/GlobalParam.php
  21. +1
    -1
      common/helpers/MeanPayment.php
  22. +15
    -0
      common/logic/Document/Document/Service/DocumentSolver.php
  23. +7
    -0
      common/logic/Document/Invoice/Model/Invoice.php
  24. +1
    -1
      common/logic/Document/Invoice/Repository/InvoiceRepository.php
  25. +26
    -0
      common/logic/Document/Invoice/Service/InvoiceSolver.php
  26. +4
    -4
      common/logic/Document/Invoice/Wrapper/InvoiceContainer.php
  27. +2
    -0
      common/logic/Document/Invoice/Wrapper/InvoiceManager.php
  28. +4
    -3
      common/logic/Order/Order/Model/Order.php
  29. +90
    -8
      common/logic/Order/Order/Repository/OrderRepository.php
  30. +16
    -25
      common/logic/Order/Order/Service/OrderBuilder.php
  31. +36
    -10
      common/logic/Order/Order/Service/OrderSolver.php
  32. +2
    -1
      common/logic/Order/ProductOrder/Model/ProductOrder.php
  33. +4
    -4
      common/logic/Payment/Event/OrderObserver.php
  34. +12
    -8
      common/logic/Payment/Model/CreditHistorySearch.php
  35. +23
    -5
      common/logic/Payment/Model/Payment.php
  36. +36
    -0
      common/logic/Payment/Repository/PaymentRepository.php
  37. +23
    -0
      common/logic/Payment/Repository/PaymentRepositoryQuery.php
  38. +85
    -0
      common/logic/Payment/Service/PaymentBuilder.php
  39. +14
    -0
      common/logic/Payment/Service/PaymentDefinition.php
  40. +127
    -0
      common/logic/Payment/Service/PaymentSolver.php
  41. +61
    -24
      common/logic/Payment/Service/PaymentUtils.php
  42. +49
    -0
      common/logic/Payment/Wrapper/PaymentContainer.php
  43. +25
    -0
      common/logic/Payment/Wrapper/PaymentManager.php
  44. +4
    -2
      common/logic/Producer/Producer/Repository/ProducerRepository.php
  45. +1
    -1
      common/logic/Producer/Producer/Service/ProducerBuilder.php
  46. +9
    -3
      common/logic/Product/Product/Model/Product.php
  47. +1
    -1
      common/logic/Product/Product/Repository/ProductRepository.php
  48. +0
    -34
      common/logic/User/CreditHistory/Repository/CreditHistoryRepository.php
  49. +0
    -23
      common/logic/User/CreditHistory/Repository/CreditHistoryRepositoryQuery.php
  50. +0
    -74
      common/logic/User/CreditHistory/Service/CreditHistoryBuilder.php
  51. +0
    -14
      common/logic/User/CreditHistory/Service/CreditHistoryDefinition.php
  52. +0
    -100
      common/logic/User/CreditHistory/Service/CreditHistorySolver.php
  53. +0
    -49
      common/logic/User/CreditHistory/Wrapper/CreditHistoryContainer.php
  54. +0
    -25
      common/logic/User/CreditHistory/Wrapper/CreditHistoryManager.php
  55. +13
    -1
      common/logic/User/User/Repository/UserRepository.php
  56. +3
    -3
      common/logic/User/UserProducer/Event/PaymentObserver.php
  57. +27
    -24
      common/logic/User/UserProducer/Service/UserProducerBuilder.php
  58. +2
    -2
      common/mail/creditUser-html.php
  59. +2
    -2
      common/mail/creditUser-text.php
  60. +1
    -1
      composer.json
  61. +6
    -6
      composer.lock
  62. +28
    -0
      console/migrations/m230913_071815_alter_table_credit_history_rename_payment.php
  63. +26
    -0
      console/migrations/m230920_081923_add_column_payment_date_transaction.php
  64. +7
    -8
      producer/controllers/CreditController.php
  65. +3
    -3
      producer/controllers/OrderController.php
  66. +16
    -16
      producer/views/credit/history.php

+ 2
- 4
backend/controllers/CronController.php View File



use common\helpers\MeanPayment; use common\helpers\MeanPayment;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use Yii; use Yii;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
$producerManager = $this->getProducerManager(); $producerManager = $this->getProducerManager();
$distributionManager = $this->getDistributionManager(); $distributionManager = $this->getDistributionManager();
$orderManager = $this->getOrderManager(); $orderManager = $this->getOrderManager();
$creditHistoryManager = $this->getCreditHistoryManager();
$paymentManager = $this->getPaymentManager();
$userManager = $this->getUserManager(); $userManager = $this->getUserManager();


if ($key == '64ac0bdab7e9f5e48c4d991ec5201d57') { if ($key == '64ac0bdab7e9f5e48c4d991ec5201d57') {
$orderManager->initOrder($order); $orderManager->initOrder($order);
if ($order->auto_payment && $configCredit) { if ($order->auto_payment && $configCredit) {
if ($orderManager->getOrderAmount($order, Order::AMOUNT_REMAINING) > 0) { if ($orderManager->getOrderAmount($order, Order::AMOUNT_REMAINING) > 0) {
$creditHistoryManager->payOrder($order, $userManager->findOneUserById(User::ID_USER_SYSTEM), false);
$paymentManager->payOrder($order, MeanPayment::CREDIT, $userManager->findOneUserById(User::ID_USER_SYSTEM), false);
$countOrders++; $countOrders++;
} }
} }

+ 52
- 40
backend/controllers/DistributionController.php View File

$distribution = $distributionManager->createDistributionIfNotExist($date); $distribution = $distributionManager->createDistributionIfNotExist($date);
$ordersArray = $orderManager->findOrdersByDistribution($distribution); $ordersArray = $orderManager->findOrdersByDistribution($distribution);
$ordersArrayObject = $ordersArray; $ordersArrayObject = $ordersArray;
$productsArray = $productManager->findProductsByDistributionAsArray($distribution);
$productsArray = $productManager->findProductsByDistribution($distribution);


$json['products'] = $this->buildAjaxInfosResponseProducts($producer, $distribution, $productsArray, $ordersArray);
$json['products'] = $this->buildAjaxInfosResponseProducts($distribution, $productsArray, $ordersArray);
$json['distribution'] = $this->buildAjaxInfosResponseDistribution($distribution, $ordersArrayObject, $productsArray); $json['distribution'] = $this->buildAjaxInfosResponseDistribution($distribution, $ordersArrayObject, $productsArray);
$json['orders'] = $this->buildAjaxInfosResponseOrders($ordersArray, $productsArray); $json['orders'] = $this->buildAjaxInfosResponseOrders($ordersArray, $productsArray);
$json['points_sale'] = $this->buildAjaxInfosResponsePointsSale($distribution); $json['points_sale'] = $this->buildAjaxInfosResponsePointsSale($distribution);


public function buildAjaxInfosResponsePointsSale(Distribution $distribution) public function buildAjaxInfosResponsePointsSale(Distribution $distribution)
{ {
$producerManager = $this->getProducerManager();
$pointSaleManager = $this->getPointSaleManager(); $pointSaleManager = $this->getPointSaleManager();
$pointSaleDistributionManager = $this->getPointSaleDistributionManager(); $pointSaleDistributionManager = $this->getPointSaleDistributionManager();


] ]
]; ];
} }

$pointSaleArray['credit_functioning'] = $producerManager->getPointSaleCreditFunctioning($pointSale);
} }


return $pointsSaleArray; return $pointsSaleArray;
} }


public function buildAjaxInfosResponseProducts(Producer $producer, Distribution $distribution, array &$productsArray, array $ordersArray)
public function buildAjaxInfosResponseProducts(Distribution $distribution, array $productsArray, array $ordersArray)
{ {
$distributionManager = $this->getDistributionManager(); $distributionManager = $this->getDistributionManager();
$orderManager = $this->getOrderManager(); $orderManager = $this->getOrderManager();
$productManager = $this->getProductManager();

foreach ($productsArray as &$theProduct) {
$productObject = $productManager->findOneProductById($theProduct['id']);
$quantityOrder = $orderManager->getProductQuantity($productObject, $ordersArray);
$theProduct['quantity_ordered'] = $quantityOrder;
$jsonProductsArray = [];


if (!isset($theProduct['productDistribution'][0])) {
$theProduct['productDistribution'][0] = $distributionManager->addProduct($distribution, $productObject);
foreach ($productsArray as $product) {
$jsonProduct = $product->getAttributes();
$quantityOrder = $orderManager->getProductQuantity($product, $ordersArray);
$jsonProduct['quantity_ordered'] = $quantityOrder;

if (!isset($product->productDistribution[0])) {
$productDistributionAdd = $distributionManager->addProduct($distribution, $product);
$jsonProduct['productDistribution'][0] = $productDistributionAdd->getAttributes();
$product->populateRelation('productDistribution', [$productDistributionAdd]);
}
else {
foreach($product->productDistribution as $key => $productDistribution) {
$jsonProduct['productDistribution'][$key] = $productDistribution->getAttributes();
}
} }


if (!is_numeric($theProduct['productDistribution'][0]['quantity_max'])) {
$theProduct['quantity_remaining'] = null;
if (!is_numeric($product->productDistribution[0]->quantity_max)) {
$jsonProduct['quantity_remaining'] = null;
} else { } else {
$theProduct['quantity_remaining'] = $theProduct['productDistribution'][0]['quantity_max'] - $quantityOrder;
$jsonProduct['quantity_remaining'] = $product->productDistribution[0]->quantity_max - $quantityOrder;
} }


$theProduct['quantity_form'] = 0;
$jsonProduct['quantity_form'] = 0;


if (!isset($theProduct['taxRate'])) {
$theProduct['taxRate'] = $producer->taxRate;
if (!$product->taxRate) {
$jsonProduct['taxRate'] = $this->getProducerCurrent()->taxRate;
} }

$jsonProductsArray[] = $jsonProduct;
} }


return $productsArray;
return $jsonProductsArray;
} }


public function buildAjaxInfosResponseProducer($producer) public function buildAjaxInfosResponseProducer($producer)
{ {
$userManager = $this->getUserManager(); $userManager = $this->getUserManager();
$orderManager = $this->getOrderManager(); $orderManager = $this->getOrderManager();
$creditHistoryManager = $this->getCreditHistoryManager();
$paymentManager = $this->getPaymentManager();


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


$creditHistoryArray = [];

foreach ($order->creditHistory as $creditHistory) {
$creditHistoryArray[] = [
'date' => date('d/m/Y H:i:s', strtotime($creditHistory->date)),
'user' => $userManager->getUsername($creditHistory->getUserObject()),
'user_action' => $creditHistoryManager->getStrUserAction($creditHistory),
'wording' => $creditHistoryManager->getStrWording($creditHistory),
'debit' => ($creditHistoryManager->isTypeDebit($creditHistory) ? '- ' . $creditHistoryManager->getAmount(
$creditHistory,
Order::AMOUNT_TOTAL,
true
) : ''),
'credit' => ($creditHistoryManager->isTypeCredit($creditHistory) ? '+ ' . $creditHistoryManager->getAmount(
$creditHistory,
Order::AMOUNT_TOTAL,
true
) : '')
$paymentArray = [];

foreach ($order->payment as $payment) {
$paymentArray[] = [
'type' => $payment->type,
'wording_type' => $paymentManager->getStrType($payment),
'mean_payment' => $payment->mean_payment,
'wording_mean_payment' => $paymentManager->getStrMeanPayment($payment),
'date' => date('d/m/Y H:i:s', strtotime($payment->date)),
'user' => $payment->getUserObject() ? $userManager->getUsername($payment->getUserObject()) : '',
'user_action' => $paymentManager->getStrUserAction($payment),
'wording' => $paymentManager->getStrWording($payment, $order),
'amount' => $paymentManager->getAmount($payment, Order::AMOUNT_TOTAL, true),
]; ];
} }


$arrayCreditUser = []; $arrayCreditUser = [];
if (isset($order->user) && isset($order->user->userProducer) && isset($order->user->userProducer[0])) {
$arrayCreditUser['credit'] = $order->user->userProducer[0]->credit;
if(isset($order->user)) {
$arrayCreditUser['credit'] = $userManager->getCredit($order->user);
} }


$oneProductUnactivated = false; $oneProductUnactivated = false;
) : null, ) : null,
'pointSale' => $order->pointSale ? ['id' => $order->pointSale->id, 'name' => $order->pointSale->name] : null, 'pointSale' => $order->pointSale ? ['id' => $order->pointSale->id, 'name' => $order->pointSale->name] : null,
'productOrder' => $productOrderArray, 'productOrder' => $productOrderArray,
'creditHistory' => $creditHistoryArray,
'paymentsArray' => $paymentArray,
'oneProductUnactivated' => $oneProductUnactivated, 'oneProductUnactivated' => $oneProductUnactivated,
'isLinkedToValidDocument' => $orderManager->isLinkedToValidDocument($order), 'isLinkedToValidDocument' => $orderManager->isLinkedToValidDocument($order),
'isCreditAutoPayment' => $orderManager->isCreditAutoPayment($order),
'isCreditContext' => $orderManager->isCreditContext($order),
'isPaid' => $orderManager->isOrderPaid($order),
'isPaidViaInvoice' => $orderManager->isOrderPaidViaInvoice($order),
'paymentLabelShort' => $orderManager->getPaymentLabelShort($order)
]); ]);
} }
} }

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

use common\helpers\Ajax; use common\helpers\Ajax;
use common\helpers\CSV; use common\helpers\CSV;
use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\MeanPayment;
use common\helpers\Price; use common\helpers\Price;
use common\logic\Document\DeliveryNote\Model\DeliveryNote; use common\logic\Document\DeliveryNote\Model\DeliveryNote;
use common\logic\Document\Document\Model\Document; use common\logic\Document\Document\Model\Document;
use yii\filters\AccessControl; use yii\filters\AccessControl;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\helpers\Html; use yii\helpers\Html;
use common\logic\Payment\Model\Payment;


class DocumentController extends BackendController class DocumentController extends BackendController
{ {


public function actionUpdate($id) public function actionUpdate($id)
{ {
$model = $this->findModel($id);
$documentManager = $this->getDocumentManager();
$paymentManager = $this->getPaymentManager();
$document = $this->findModel($id);


if (!$model) {
if (!$document) {
throw new yii\web\NotFoundHttpException('Le document n\'a pas été trouvé.'); throw new yii\web\NotFoundHttpException('Le document n\'a pas été trouvé.');
} }


if ($model && $model->load(\Yii::$app->request->post()) && $model->save()) {
$this->setFlash('success', $this->getFlashMessage('update', $model));
if ($document && $document->load(\Yii::$app->request->post()) && $document->save()) {
$this->setFlash('success', $this->getFlashMessage('update', $document));
}

$payment = null;
if($documentManager->isDocumentInvoice($document) && $documentManager->isStatusValid($document)) {
$payment = $paymentManager->instanciatePayment(
Payment::TYPE_PAYMENT,
number_format($documentManager->getAmountWithTax($document), 3),
$this->getProducerCurrent(),
null,
null,
MeanPayment::TRANSFER,
null,
$document
);
$payment->amount = number_format($payment->amount, 2);

$posts = \Yii::$app->request->post();
if(isset($posts['Payment']['date_transaction'])) {
$posts['Payment']['date_transaction'] = date('Y-m-d', strtotime(str_replace('/', '-', $posts['Payment']['date_transaction'])));
}

if ($payment->load($posts) && $payment->save()) {
$this->setFlash('success', 'Le règlement a bien été ajouté.');
return $this->redirect(['invoice/update', 'id' => $document->id]);
}
else {
if($payment->date_transaction) {
$payment->date_transaction = date('d/m/Y', strtotime($payment->date_transaction));
}
}
} }


return $this->render('/document/update', [ return $this->render('/document/update', [
'title' => $this->getTitle('Modifier'), 'title' => $this->getTitle('Modifier'),
'typeDocument' => $this->getDocumentType(), 'typeDocument' => $this->getDocumentType(),
'model' => $model,
'model' => $document,
'payment' => $payment
]); ]);
} }



+ 13
- 14
backend/controllers/OrderController.php View File

use common\forms\SubscriptionForm; use common\forms\SubscriptionForm;
use common\helpers\CSV; use common\helpers\CSV;
use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\MeanPayment;
use common\helpers\Price; use common\helpers\Price;
use common\logic\Distribution\Distribution\Model\Distribution; use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Distribution\PointSaleDistribution\Model\PointSaleDistribution; use common\logic\Distribution\PointSaleDistribution\Model\PointSaleDistribution;
use common\logic\Order\ProductOrder\Model\ProductOrder; use common\logic\Order\ProductOrder\Model\ProductOrder;
use common\logic\PointSale\PointSale\Model\PointSale; use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\Product\Product\Model\Product; use common\logic\Product\Product\Model\Product;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\Payment\Model\Payment;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use common\logic\User\UserProducer\Model\UserProducer; use common\logic\User\UserProducer\Model\UserProducer;
use yii\filters\AccessControl; use yii\filters\AccessControl;
$userManager = $this->getUserManager(); $userManager = $this->getUserManager();
$pointSaleManager = $this->getPointSaleManager(); $pointSaleManager = $this->getPointSaleManager();
$userPointSaleManager = $this->getUserPointSaleManager(); $userPointSaleManager = $this->getUserPointSaleManager();
$creditHistoryManager = $this->getCreditHistoryManager();
$paymentManager = $this->getPaymentManager();
$productManager = $this->getProductManager(); $productManager = $this->getProductManager();


$request = \Yii::$app->request; $request = \Yii::$app->request;
$oldIdUser = $order->id_user; $oldIdUser = $order->id_user;
$amountPaid = $orderManager->getOrderAmountWithTax($order, Order::AMOUNT_PAID); $amountPaid = $orderManager->getOrderAmountWithTax($order, Order::AMOUNT_PAID);
if ($oldIdUser != $idUser && $amountPaid > 0) { if ($oldIdUser != $idUser && $amountPaid > 0) {
$creditHistoryManager->refundOrder($order, $this->getUserCurrent());
$paymentManager->refundOrder($order, $this->getUserCurrent());
$order = $orderManager->findOneOrderById($idOrder); $order = $orderManager->findOneOrderById($idOrder);
$orderManager->initOrder($order); $orderManager->initOrder($order);
} }
public function actionPaymentStatus(int $idOrder) public function actionPaymentStatus(int $idOrder)
{ {
$orderManager = $this->getOrderManager(); $orderManager = $this->getOrderManager();
$creditHistoryManager = $this->getCreditHistoryManager();
$paymentManager = $this->getPaymentManager();


$order = $orderManager->findOneOrderById($idOrder); $order = $orderManager->findOneOrderById($idOrder);


. '</span>'; . '</span>';


// historique // historique
$history = CreditHistory::find()
$history = Payment::find()
->with('userAction') ->with('userAction')
->where(['id_order' => $idOrder]) ->where(['id_order' => $idOrder])
->all(); ->all();
if ($history && is_array($history) && count($history)) { if ($history && is_array($history) && count($history)) {
foreach ($history as $creditHistory) { foreach ($history as $creditHistory) {
$html .= '<tr>' $html .= '<tr>'
. '<td>' . date('d/m/Y H:i:s', strtotime($creditHistoryManager->getDate($creditHistory))) . '</td>'
. '<td>' . Html::encode($creditHistoryManager->getStrUserAction($creditHistory)) . '</td>'
. '<td>' . $creditHistoryManager->getStrWording($creditHistory) . '</td>'
. '<td>' . ($creditHistoryManager->isTypeDebit($creditHistory) ? '- ' . Price::getPriceWithTax($creditHistory->amount) : '') . '</td>'
. '<td>' . ($creditHistoryManager->isTypeCredit($creditHistory) ? '+ ' . Price::getPriceWithTax($creditHistory->amount) : '') . '</td>'
. '<td>' . date('d/m/Y H:i:s', strtotime($paymentManager->getDate($creditHistory))) . '</td>'
. '<td>' . Html::encode($paymentManager->getStrUserAction($creditHistory)) . '</td>'
. '<td>' . $paymentManager->getStrWording($creditHistory) . '</td>'
. '<td>' . ($paymentManager->isTypeDebit($creditHistory) ? '- ' . Price::getPriceWithTax($creditHistory->amount) : '') . '</td>'
. '<td>' . ($paymentManager->isTypeCredit($creditHistory) ? '+ ' . Price::getPriceWithTax($creditHistory->amount) : '') . '</td>'
. '</tr>'; . '</tr>';
} }
} else { } else {
/** /**
* Effectue le paiement/remboursement d'une commande. * Effectue le paiement/remboursement d'une commande.
*/ */
public function actionAjaxPayment(int $idOrder, string $type, float $amount): array
public function actionAjaxPayment(int $idOrder, string $type, string $meanPayment): array
{ {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;


$orderManager = $this->getOrderManager(); $orderManager = $this->getOrderManager();
$creditHistoryManager = $this->getCreditHistoryManager();
$paymentManager = $this->getPaymentManager();
$order = $orderManager->findOneOrderById($idOrder); $order = $orderManager->findOneOrderById($idOrder);
$orderManager->initOrder($order); $orderManager->initOrder($order);


if ($order) { if ($order) {
$creditHistoryManager->payOrRefundOrder($type, $order, $this->getUserCurrent());
$paymentManager->payOrRefundOrder($type, $order, $meanPayment, $this->getUserCurrent());
} }


return ['success']; return ['success'];

+ 1
- 1
backend/controllers/ProducerController.php View File

public function actionUpdateOpendistribVersion() public function actionUpdateOpendistribVersion()
{ {
$producerManager = $this->getProducerManager(); $producerManager = $this->getProducerManager();
$producerManager->updateOpendistribVersion(GlobalParam::getCurrentProducer());
$producerManager->updateOpendistribVersion($this->getProducerCurrent());


return $this->redirect(\Yii::$app->request->referrer); return $this->redirect(\Yii::$app->request->referrer);
} }

+ 4
- 5
backend/controllers/UserController.php View File



use backend\models\CreditForm; use backend\models\CreditForm;
use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\Mailjet;
use backend\models\MailForm; use backend\models\MailForm;
use common\helpers\MeanPayment;
use common\helpers\Password; use common\helpers\Password;
use common\logic\Order\Order\Model\OrderSearch; use common\logic\Order\Order\Model\OrderSearch;
use common\logic\PointSale\PointSale\Model\PointSale; use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\PointSale\UserPointSale\Model\UserPointSale; use common\logic\PointSale\UserPointSale\Model\UserPointSale;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\Payment\Model\Payment;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use common\logic\User\User\Model\UserSearch; use common\logic\User\User\Model\UserSearch;
use common\logic\User\UserProducer\Model\UserProducer; use common\logic\User\UserProducer\Model\UserProducer;
use common\logic\User\UserUserGroup\Model\UserUserGroup; use common\logic\User\UserUserGroup\Model\UserUserGroup;
use Faker\Provider\HtmlLorem;
use yii\base\UserException; use yii\base\UserException;
use yii\filters\AccessControl; use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use \Yii; use \Yii;
use yii\helpers\Html; use yii\helpers\Html;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
$creditForm = new CreditForm; $creditForm = new CreditForm;
} }


$history = CreditHistory::find()
$history = Payment::find()
->with(['order', 'userAction']) ->with(['order', 'userAction'])
->where([ ->where([
'id_user' => $user->id, 'id_user' => $user->id,
'id_producer' => GlobalParam::getCurrentProducerId(), 'id_producer' => GlobalParam::getCurrentProducerId(),
'mean_payment' => MeanPayment::CREDIT
]) ])
->orderBy('date DESC') ->orderBy('date DESC')
->all(); ->all();

+ 3
- 10
backend/models/CreditForm.php View File

namespace backend\models; namespace backend\models;


use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\Mailjet;
use common\logic\Producer\Producer\Wrapper\ProducerManager;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\CreditHistory\Wrapper\CreditHistoryManager;
use common\logic\User\User\Model\User;
use common\logic\Payment\Wrapper\PaymentManager;
use common\logic\User\User\Wrapper\UserManager; use common\logic\User\User\Wrapper\UserManager;
use common\logic\User\UserProducer\Model\UserProducer;
use common\logic\User\UserProducer\Wrapper\UserProducerManager; use common\logic\User\UserProducer\Wrapper\UserProducerManager;
use Yii;
use yii\base\Model; use yii\base\Model;


/** /**
{ {
$userManager = UserManager::getInstance(); $userManager = UserManager::getInstance();
$userProducerManager = UserProducerManager::getInstance(); $userProducerManager = UserProducerManager::getInstance();
$creditHistoryManager = CreditHistoryManager::getInstance();
$producerManager = ProducerManager::getInstance();
$paymentManager = PaymentManager::getInstance();


if ($this->validate()) { if ($this->validate()) {
$user = $userManager->findOneUserById($this->id_user); $user = $userManager->findOneUserById($this->id_user);
$creditHistoryManager->creditOrDebitUser($this->type, $user, $this->amount, $this->mean_payment, $userManager->getCurrent());
$paymentManager->creditOrDebitUser($this->type, $user, $this->amount, $this->mean_payment, $userManager->getCurrent());
// on prévient l'utilisateur que son compte vient d'être crédité // on prévient l'utilisateur que son compte vient d'être crédité
if($this->send_mail) { if($this->send_mail) {

+ 178
- 123
backend/views/distribution/index.php View File

</div> </div>


<div v-if="idActivePointSale > 0 && (totalActivePointSale() > 0 || weightActivePointSale() > 0)" class="point-sale-totals"> <div v-if="idActivePointSale > 0 && (totalActivePointSale() > 0 || weightActivePointSale() > 0)" class="point-sale-totals">
<span class="title">Totaux</span>
CA TTC : <strong>{{ totalActivePointSale() }} €</strong> / Poids : <strong>{{ weightActivePointSale() }} kg</strong>
<div>
<span class="title">Totaux</span>
CA TTC : <strong>{{ totalActivePointSale() }} €</strong> / Poids : <strong>{{ weightActivePointSale() }} kg</strong>
</div>
<div v-if="producer.credit && pointSaleActive">
<span class="title">Crédit</span>
<template v-if="pointSaleActive.credit && pointSaleActive.credit == 1">
<template v-if="pointSaleActive.credit_functioning == 'mandatory'">Obligatoire</template>
<template v-else-if="pointSaleActive.credit_functioning == 'user'">Basé sur l'utilisateur</template>
<template v-else-if="pointSaleActive.credit_functioning == 'optional'">Optionnel</template>
</template>
<template v-else>Désactivé</template>
</div>
</div> </div>


<table class="table table-condensed table-bordered table-hover" v-if="countOrdersByPointSale[idActivePointSale] > 0 || (idActivePointSale == 0 && orders.length > 0)"> <table class="table table-condensed table-bordered table-hover" v-if="countOrdersByPointSale[idActivePointSale] > 0 || (idActivePointSale == 0 && orders.length > 0)">
<th class="column-user">Utilisateur</th> <th class="column-user">Utilisateur</th>
<th class="column-point-sale" v-if="idActivePointSale == 0">Point de vente</th> <th class="column-point-sale" v-if="idActivePointSale == 0">Point de vente</th>
<th class="column-amount">Montant</th> <th class="column-amount">Montant</th>
<th class="column-state-payment">Crédit</th>
<th class="column-payment"></th>
<th class="column-state-payment">Paiement</th>
<th class="column-credit" v-if="!pointSaleActive || (pointSaleActive && pointSaleActive.credit == 1)">Crédit</th>
<th class="column-actions">Actions</th>
<th class="column-tiller" v-if="producer && producer.tiller">Tiller</th> <th class="column-tiller" v-if="producer && producer.tiller">Tiller</th>
<th class="column-actions"></th>
<th class="column-delivery-note"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<a class="btn btn-default btn-sm" :href="baseUrl+'/user/orders?id='+order.id_user" data-toggle="popover" data-trigger="hover" data-placement="bottom" data-content="Voir les commandes"><span class="glyphicon glyphicon-eye-open"></span></a> <a class="btn btn-default btn-sm" :href="baseUrl+'/user/orders?id='+order.id_user" data-toggle="popover" data-trigger="hover" data-placement="bottom" data-content="Voir les commandes"><span class="glyphicon glyphicon-eye-open"></span></a>
</span> </span>
</span> </span>
<span v-else>{{ order.username }}</span>
<span v-else class="no-user">{{ order.username }}</span>
<span v-if="order.comment && order.comment.length > 0" class="glyphicon glyphicon-comment"></span> <span v-if="order.comment && order.comment.length > 0" class="glyphicon glyphicon-comment"></span>
<span v-if="order.delivery_home && order.delivery_address && order.delivery_address.length > 0" class="glyphicon glyphicon-home"></span> <span v-if="order.delivery_home && order.delivery_address && order.delivery_address.length > 0" class="glyphicon glyphicon-home"></span>
</td> </td>
</td> </td>
<td class="column-amount"> <td class="column-amount">
{{ order.amount.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+'&nbsp;€' }} {{ order.amount.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+'&nbsp;€' }}

<div class="state-payment-mobile"> <div class="state-payment-mobile">
<order-state-payment :order="order" :producer="producer"></order-state-payment> <order-state-payment :order="order" :producer="producer"></order-state-payment>
</div> </div>
</td> </td>
<td class="column-state-payment"> <td class="column-state-payment">
<order-state-payment :order="order" :producer="producer"></order-state-payment> <order-state-payment :order="order" :producer="producer"></order-state-payment>
<span class="glyphicon glyphicon-time" title="Débit automatique du crédit la veille de la distribution" v-if="order.auto_payment && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
</td>
<td class="column-credit" v-if="!pointSaleActive || (pointSaleActive && pointSaleActive.credit == 1)">
<template v-if="order.isCreditContext">
<a :href="baseUrl+'/user/credit?id='+order.id_user" :class="order.user.credit >= 0 ? 'positive' : 'negative'">
{{ order.user.credit.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+'&nbsp;€' }}
</a>
</template>
</td> </td>
<td class="column-payment" v-if="producer && producer.credit">
<div class="btn-group" v-if="order.user && !order.date_delete">
<td class="column-payment" v-if="false && producer && producer.credit">
<!--<div class="btn-group" v-if="order.user && !order.date_delete">
<button class="btn btn-xs btn-default" v-if="order.amount_paid == order.amount" @click="orderPaymentClick" :data-id-order="order.id" data-type="refund" :data-amount="order.amount"> <button class="btn btn-xs btn-default" v-if="order.amount_paid == order.amount" @click="orderPaymentClick" :data-id-order="order.id" data-type="refund" :data-amount="order.amount">
<span class="glyphicon glyphicon-euro"></span> Recréditer <span class="glyphicon glyphicon-euro"></span> Recréditer
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">Historique</a></li> <li><a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">Historique</a></li>
</ul> </ul>
</div>
</td>
<td v-if="producer && producer.tiller" class="tiller column-tiller">
<input v-if="order.tiller_synchronization == true" type="checkbox" checked="checked" :id="'checkbox-tiller-synchronization-'+order.id" :data-id-order="order.id" @change="changeSynchroTiller" />
<input v-else type="checkbox" :id="'checkbox-tiller-synchronization-'+order.id" :data-id-order="order.id" @change="changeSynchroTiller" />
<label :for="'checkbox-tiller-synchronization-'+order.id">Tiller</label>
</div>-->
</td> </td>

<td class="column-actions"> <td class="column-actions">
<span v-if="order.oneProductUnactivated" class="glyphicon glyphicon-warning-sign" title="Contient un produit non activé"></span>
<span v-if="false && order.oneProductUnactivated" class="glyphicon glyphicon-warning-sign" title="Contient un produit non activé"></span>

<a href="javascript:void(0);" class="btn btn-default btn-xs" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span></a>
<a href="javascript:void(0);" class="btn btn-default btn-xs" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span></a>

<div class="wrapper-button-dropdown">
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
€ <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<template v-if="!order.isPaidViaInvoice">
<li v-if="order.isCreditContext">
<a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="credit">
<span class="glyphicon glyphicon-piggy-bank"></span> {{ getLabelPaymentRefund(order, 'Débiter', 'Recréditer', 'le crédit') }}
</a>
</li>
<li>
<a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="money">
<span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'en espèce') }}
</a>
</li>
<li>
<a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="cheque">
<span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par chèque') }}
</a>
</li>
<li>
<a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="transfer">
<span class="glyphicon glyphicon-euro"></span> {{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par virement') }}
</a>
</li>
</template>
<!--<li>
<a href="javascript:void(0);" @click="orderPaymentClick" :data-id-order="order.id" :data-type="getTypePayment(order)" data-mean-payment="credit-card">
{{ getLabelPaymentRefund(order, 'Payer', 'Rembourser', 'par carte bancaire') }}
</a>
</li>-->
<li>
<a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">
<span class="glyphicon glyphicon-th-list"></span> Historique
</a>
</li>
</ul>
</div>

<div class="wrapper-button-dropdown">
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-file"></span> <template v-if="countDocuments(order)">{{ countDocuments(order) }}</template> <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li v-if="!order.id_delivery_note">
<a href="javascript:void(0);" class="" :data-id-order="order.id" @click="generateDeliveryNote">
<span class="glyphicon glyphicon-plus"></span> Générer un bon de livraison
</a>
</li>
<li v-if="order.id_quotation">
<a :href="UrlManager.getBaseUrl()+'quotation/update?id='+order.id_quotation">
<span class="glyphicon glyphicon-file"></span> Devis
</a>
</li>
<li v-if="order.id_delivery_note">
<a :href="UrlManager.getBaseUrl()+'delivery-note/update?id='+order.id_delivery_note">
<span class="glyphicon glyphicon-file"></span> Bon de livraison
</a>
</li>
<li v-if="order.id_invoice">
<a :href="UrlManager.getBaseUrl()+'invoice/update?id='+order.id_invoice">
<span class="glyphicon glyphicon-file"></span> Facture
</a>
</li>
</ul>
</div>


<div class="wrapper-button-dropdown">
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action <span class="caret"></span>
<span class="caret"></span>
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span> Voir</a></li>
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span> Modifier</a></li>
<!--<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span> Voir</a></li>
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span> Modifier</a></li>-->
<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> Supprimer</a></li>
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="generateDeliveryNote"><span class="glyphicon glyphicon-file"></span> Générer un bon de livraison</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 associé</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 sur cette base</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> </ul>
</div>


<order-form <order-form
v-if="showModalFormOrderUpdate && idOrderUpdate == order.id" v-if="showModalFormOrderUpdate && idOrderUpdate == order.id"
<span v-else>{{ order.username }}</span></strong> <span v-else>{{ order.username }}</span></strong>
</h3> </h3>
<div slot="body"> <div slot="body">
<div class="col-md-4">
<div class="info-box">
<span :class="'info-box-icon ' +((order.amount_paid == order.amount) ? 'bg-green' : 'bg-red')"><i class="fa fa-check"></i></span>
<div class="info-box-content">
<span class="info-box-text">Montant</span>
<span class="info-box-number">{{ order.amount.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}</span>
<span class="info-box-text">
Statut<br />
<span class="label label-success" v-if="order.amount_paid == order.amount">débité</span>
<span class="label label-default" v-else-if="order.amount_paid == 0">non débité</span>
<span class="label label-default" v-else-if="order.amount_paid > order.amount">surplus</span>
<span class="label label-warning" v-else-if="order.amount_paid < order.amount">reste à débiter</span>
<div class="row">
<div class="col-md-6">
<div class="info-box">
<span :class="'info-box-icon ' +((order.isPaid) ? 'bg-green' : 'bg-red')"><i class="fa fa-check"></i></span>
<div class="info-box-content">
<span class="info-box-text">Montant</span>
<span class="info-box-number">
{{ order.amount.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</span> </span>
</div>
</div> </div>
</div> </div>

<div class="info-box">
<span :class="'info-box-icon ' +((order.user.credit > 0) ? 'bg-green' : 'bg-red')"><i class="fa fa-user"></i></span>
<div class="info-box-content">
<span class="info-box-text">Crédit utilisateur</span>
<span class="info-box-number">{{ order.user.credit.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}</span>
<div class="col-md-6" v-if="order.isCreditContext">
<div class="info-box">
<span :class="'info-box-icon ' +((order.user.credit > 0) ? 'bg-green' : 'bg-red')"><i class="fa fa-user"></i></span>
<div class="info-box-content">
<span class="info-box-text">Crédit utilisateur</span>
<span class="info-box-number">
{{ order.user.credit.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</span>
</div>
</div> </div>
</div> </div>

<button v-if="order.amount_paid == order.amount"
class="btn btn-default"
:data-amount="order.amount"
data-type="refund"
@click="orderPaymentClick" >
<span class="glyphicon glyphicon-chevron-right"></span>
Recréditer {{ order.amount.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>

<button v-else-if="order.amount_paid == 0"
class="btn btn-default"
:data-amount="order.amount"
data-type="payment"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
Débiter {{ order.amount.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>

<button v-else-if="order.amount_paid > order.amount"
class="btn btn-default"
:data-amount="order.amount_surplus"
data-type="refund"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
Recréditer {{ order.amount_surplus.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>

<button v-else-if="order.amount_paid < order.amount"
class="btn btn-default"
:data-amount="order.amount_remaining"
data-type="payment"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
Débiter le restant {{ order.amount_remaining.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
</div> </div>


<div class="col-md-8">
<h4>Historique paiement</h4>
<table class="table table-condensed table-bordered table-hover">
<thead>
<tr>
<td>Date</td>
<td>Utilisateur</td>
<td>Action</td>
<td>Origine action</td>
<td>- Débit</td>
<td>+ Crédit</td>
</tr>
</thead>
<tbody>
<tr v-for="creditHistory in order.creditHistory">
<td>{{ creditHistory.date }}</td>
<td>{{ creditHistory.user }}</td>
<td v-html="creditHistory.wording"></td>
<td>{{ creditHistory.user_action }}</td>
<td v-html="creditHistory.debit"></td>
<td v-html="creditHistory.credit"></td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-md-12">
<h4>Historique paiements</h4>
<table class="table table-condensed table-bordered table-hover" v-if="order.paymentsArray && order.paymentsArray.length > 0">
<thead>
<tr>
<!--<td>Utilisateur</td>
<td>Action</td>
<td>Origine action</td>-->
<td>Date</td>
<td>Type</td>
<td>Moyen</td>
<td>Montant</td>
</tr>
</thead>
<tbody>
<tr v-for="payment in order.paymentsArray">
<!--<td>{{ payment.user }}</td>
<td v-html="payment.wording"></td>
<td>{{ payment.user_action }}</td>-->
<td>{{ payment.date }}</td>
<td>{{ payment.wording_type }}</td>
<td>{{ payment.wording_mean_payment }}</td>
<td v-html="payment.amount"></td>
</tr>
</tbody>
</table>
<div class="alert alert-info" v-else>
Aucun paiement rattaché à commande.
</div>
<div class="alert alert-success" v-if="order.isPaidViaInvoice">
La commande est payée via la <a :href="UrlManager.getBaseUrl()+'invoice/update?id='+order.id_invoice">facture</a> à laquelle elle est rattachée.
</div>
</div>
</div> </div>


</div> </div>
</modal> </modal>

</td> </td>
<td class="column-delivery-note">
<a v-if="order.id_delivery_note" class="btn btn-default btn-xs" :href="UrlManager.getBaseUrl()+'delivery-note/update?id='+order.id_delivery_note">
<span class="glyphicon glyphicon-file"></span> BL #{{ order.id_delivery_note }}
</a>
<td v-if="producer && producer.tiller" class="tiller column-tiller">
<input v-if="order.tiller_synchronization == true" type="checkbox" checked="checked" :id="'checkbox-tiller-synchronization-'+order.id" :data-id-order="order.id" @change="changeSynchroTiller" />
<input v-else type="checkbox" :id="'checkbox-tiller-synchronization-'+order.id" :data-id-order="order.id" @change="changeSynchroTiller" />
<label :for="'checkbox-tiller-synchronization-'+order.id">Tiller</label>
</td> </td>
</tr> </tr>
<tr class="view" v-if="showViewProduct && idOrderView == order.id"> <tr class="view" v-if="showViewProduct && idOrderView == order.id">
</td> </td>
</tr> </tr>
</template> </template>
<!--<tr v-if="idActivePointSale > 0">
<td colspan="4"><strong>Total (TTC)</strong></td>
<td><strong>{{ totalActivePointSale() }}</strong></td>
<td colspan="3"></td>
</tr>-->
</tbody> </tbody>
</table> </table>
<div class="alert alert-warning" v-else> <div class="alert alert-warning" v-else>
</div> </div>


<script type="text/x-template" id="order-state-payment"> <script type="text/x-template" id="order-state-payment">
<div class="input-group">
<span class="label label-success input-group-addon" v-if="order.amount_paid == order.amount">débité</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid == 0">non débité</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid > order.amount">surplus</span>
<span class="label label-warning input-group-addon" v-else-if="order.amount_paid < order.amount">reste à débiter</span>


<span class="glyphicon glyphicon-time" title="Débit automatique du crédit" v-if="order.auto_payment && producer && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
</div>
<span v-html="order.paymentLabelShort"></span>

<!--<span class="glyphicon glyphicon-signal" title="Paiement partiel ou surplus" v-if="order.amount_paid > order.amount || order.amount_paid < order.amount"></span>-->

<!--<span class="label label-success" v-if="order.amount_paid == order.amount">&nbsp;</span>
<span class="label label-default" v-else-if="order.amount_paid == 0">&nbsp;</span>-->

<!--<span class="label label-success input-group-addon" v-if="order.amount_paid == order.amount">débité</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid == 0">non débité</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid > order.amount">surplus</span>
<span class="label label-warning input-group-addon" v-else-if="order.amount_paid < order.amount">reste à débiter</span>-->
</script> </script>


<!-- template for the order-form component --> <!-- template for the order-form component -->
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label" for="select-mean-payment">Moyen de paiement</label>
<!--<label class="control-label" for="select-mean-payment">Moyen de paiement</label>
<select class="form-control" id="select-mean-payment" v-model="order.mean_payment"> <select class="form-control" id="select-mean-payment" v-model="order.mean_payment">
<option value="0">--</option> <option value="0">--</option>
<option v-for="(wordingMeanPayment, keyMeanPayment) in meansPayment" :value="keyMeanPayment">{{ wordingMeanPayment }}</option> <option v-for="(wordingMeanPayment, keyMeanPayment) in meansPayment" :value="keyMeanPayment">{{ wordingMeanPayment }}</option>
</select>
</select>-->
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label" for="textarea-comment">Commentaire</label> <label class="control-label" for="textarea-comment">Commentaire</label>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid == 0">non réglé</span> <span class="label label-default input-group-addon" v-else-if="order.amount_paid == 0">non réglé</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid > order.amount">surplus</span> <span class="label label-default input-group-addon" v-else-if="order.amount_paid > order.amount">surplus</span>
<span class="label label-warning input-group-addon" v-else-if="order.amount_paid < order.amount">reste à débiter</span> <span class="label label-warning input-group-addon" v-else-if="order.amount_paid < order.amount">reste à débiter</span>

<span class="glyphicon glyphicon-time" title="Débit automatique du crédit" v-if="order.auto_payment && producer && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
</div>
</div>
</script> </script>


<!-- template for the modal component --> <!-- template for the modal component -->

+ 69
- 3
backend/views/document/_form.php View File

* termes. * termes.
*/ */


use common\logic\Document\Document\Wrapper\DocumentManager;
use common\logic\Producer\Producer\Wrapper\ProducerManager;
use common\helpers\MeanPayment;use common\helpers\Price;use common\logic\Document\Document\Wrapper\DocumentManager;
use common\logic\Document\Invoice\Wrapper\InvoiceManager;use common\logic\Payment\Wrapper\PaymentManager;use common\logic\Producer\Producer\Wrapper\ProducerManager;
use common\logic\User\User\Wrapper\UserManager; use common\logic\User\User\Wrapper\UserManager;
use yii\helpers\Html; use yii\helpers\Html;
use yii\widgets\ActiveForm; use yii\widgets\ActiveForm;


$producerManager = ProducerManager::getInstance(); $producerManager = ProducerManager::getInstance();
$documentManager = DocumentManager::getInstance(); $documentManager = DocumentManager::getInstance();
$invoiceManager = InvoiceManager::getInstance();
$userManager = UserManager::getInstance(); $userManager = UserManager::getInstance();
$paymentManager = PaymentManager::getInstance();


$documentClass = $documentManager->getClass($model); $documentClass = $documentManager->getClass($model);


<div id="" class="info-box"> <div id="" class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span> <span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span>
<div class="info-box-content"> <div class="info-box-content">
<span class="info-box-text">Total<span v-if="taxRateProducer != 0"> (TTC)</span></span>
<span class="info-box-text">
Total<span v-if="taxRateProducer != 0"> (TTC)</span>
<?php if($invoiceManager->isDocumentInvoice($model) && $invoiceManager->isInvoicePaid($model)): ?>
<span class="label label-success">PAYÉE</span>
<?php endif; ?>
</span>
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span> <span class="info-box-number">{{ formatPrice(total_with_tax) }}</span>
<p v-if="invoiceUrl"> <p v-if="invoiceUrl">
<a class="btn btn-sm btn-default" :href="invoiceUrl"> <a class="btn btn-sm btn-default" :href="invoiceUrl">
<div class="clr"></div> <div class="clr"></div>


<?php if ($action == 'update' && $documentClass == 'Invoice'): ?> <?php if ($action == 'update' && $documentClass == 'Invoice'): ?>

<?php if($documentManager->isStatusValid($model)): ?>
<div>
<div class="panel panel-default">
<div class="panel-heading">
Règlement
</div>
<div class="panel-body">
<?php if($model->payments && count($model->payments) > 0): ?>
<table class="table table-bordered">
<thead>
<tr>
<th>Moyen de paiement</th>
<th>Date transaction</th>
<th>Montant</th>
</tr>
</thead>
<tbody>
<?php foreach($model->payments as $payment): ?>
<tr>
<td><?= $paymentManager->getStrMeanPayment($payment); ?></td>
<td><?= $payment->date_transaction ? date('d/m/Y', strtotime($payment->date_transaction)) : '' ?></td>
<td><?= Price::format($payment->amount); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>

<?php if($invoiceManager->isDocumentInvoice($model) && !$invoiceManager->isInvoicePaid($model)): ?>
<div class="row">
<?php $form = ActiveForm::begin(); ?>
<div class="col-md-3">
<?= $form->field($payment, 'mean_payment')->dropDownList(MeanPayment::getAll()); ?>
</div>
<div class="col-md-3">
<?= $form->field($payment, 'date_transaction')->textInput([
'class' => 'datepicker form-control'
]); ?>
</div>
<div class="col-md-3">
<?= $form->field($payment, 'amount', [
'template' => '{label}<div class="input-group">{input}<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span></div>{hint}',
])->textInput(); ?>
</div>
<div class="col-md-3">
<div class="form-group">
<br>
<?= Html::submitButton('Ajouter', ['class' => 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endif; ?>

<div v-if="(deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0) || (deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0)"> <div v-if="(deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0) || (deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0)">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">

+ 1
- 0
backend/views/document/update.php View File

'action' => 'update', 'action' => 'update',
'model' => $model, 'model' => $model,
'typeDocument' => $typeDocument, 'typeDocument' => $typeDocument,
'payment' => $payment
]) ?> ]) ?>
</div> </div>

+ 19
- 2
backend/views/invoice/index.php View File

[ [
'attribute' => 'amount', 'attribute' => 'amount',
'header' => 'Montant', 'header' => 'Montant',
'format' => 'raw',
'value' => function ($invoice) use ($invoiceManager) { 'value' => function ($invoice) use ($invoiceManager) {
$amountWithTax = $invoiceManager->getAmountWithTax($invoice, Order::INVOICE_AMOUNT_TOTAL);
return $invoiceManager->getAmountWithTax($invoice, Order::INVOICE_AMOUNT_TOTAL, true); return $invoiceManager->getAmountWithTax($invoice, Order::INVOICE_AMOUNT_TOTAL, true);
} }
], ],
[
'header' => 'Payée',
'format' => 'raw',
'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-hide-on-mobile'],
'value' => function ($invoice) use ($invoiceManager) {
$amountWithTax = $invoiceManager->getAmountWithTax($invoice, Order::INVOICE_AMOUNT_TOTAL);
if($amountWithTax && $invoiceManager->isInvoicePaid($invoice)) {
return '<span class="label label-success">Oui</span>';
}

return '<span class="label label-default">Non</span>';
}
],
[ [
'attribute' => 'is_sent', 'attribute' => 'is_sent',
'header' => 'Envoyé',
'header' => 'Envoyée',
'format' => 'raw', 'format' => 'raw',
'headerOptions' => ['class' => 'column-hide-on-mobile'], 'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'], 'filterOptions' => ['class' => 'column-hide-on-mobile'],
if ($model->is_sent) { if ($model->is_sent) {
return '<span class="label label-success">Oui</span>'; return '<span class="label label-success">Oui</span>';
} else { } else {
return '<span class="label label-danger">Non</span>';
return '<span class="label label-default">Non</span>';
} }
} }
], ],

+ 12
- 12
backend/views/user/credit.php View File

use yii\helpers\Html; use yii\helpers\Html;
use yii\widgets\ActiveForm; use yii\widgets\ActiveForm;
use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\Payment\Model\Payment;
use common\helpers\MeanPayment; use common\helpers\MeanPayment;


$creditHistoryManager = $this->getCreditHistoryManager();
$paymentManager = $this->getPaymentManager();
$producerManager = $this->getProducerManager(); $producerManager = $this->getProducerManager();
$userManager = $this->getUserManager(); $userManager = $this->getUserManager();


<div class="panel-body"> <div class="panel-body">
<?php $form = ActiveForm::begin(); ?> <?php $form = ActiveForm::begin(); ?>
<?= $form->field($creditForm, 'type')->dropDownList([ <?= $form->field($creditForm, 'type')->dropDownList([
CreditHistory::TYPE_CREDIT => 'Crédit',
CreditHistory::TYPE_DEBIT => 'Débit',
Payment::TYPE_CREDIT => 'Crédit',
Payment::TYPE_DEBIT => 'Débit',
]) ?> ]) ?>
<?= $form->field($creditForm, 'amount')->textInput() ?> <?= $form->field($creditForm, 'amount')->textInput() ?>
<?= $form->field($creditForm, 'mean_payment')->dropDownList([ <?= $form->field($creditForm, 'mean_payment')->dropDownList([
<?php foreach($history as $creditHistory): ?> <?php foreach($history as $creditHistory): ?>


<tr> <tr>
<td><?= $creditHistoryManager->getDate($creditHistory, true) ; ?></td>
<td><?= Html::encode($creditHistoryManager->getStrUserAction($creditHistory)); ?></td>
<td><?= $creditHistoryManager->getStrWording($creditHistory); ?></td>
<td><?= $paymentManager->getDate($creditHistory, true) ; ?></td>
<td><?= Html::encode($paymentManager->getStrUserAction($creditHistory)); ?></td>
<td><?= $paymentManager->getStrWording($creditHistory); ?></td>
<td> <td>
<?php if($creditHistoryManager->isTypeDebit($creditHistory)): ?>
- <?= $creditHistoryManager->getAmount($creditHistory, true); ?>
<?php if($paymentManager->isTypeDebit($creditHistory)): ?>
- <?= $paymentManager->getAmount($creditHistory, true); ?>
<?php endif; ?> <?php endif; ?>
</td> </td>
<td> <td>
<?php if($creditHistoryManager->isTypeCredit($creditHistory)): ?>
+ <?= $creditHistoryManager->getAmount($creditHistory, true); ?>
<?php if($paymentManager->isTypeCredit($creditHistory)): ?>
+ <?= $paymentManager->getAmount($creditHistory, true); ?>
<?php endif; ?> <?php endif; ?>
</td> </td>
<td> <td>
<?= $creditHistoryManager->getStrMeanPayment($creditHistory) ?>
<?= $paymentManager->getStrMeanPayment($creditHistory) ?>
</td> </td>
<td> <td>
<?php if(strlen($creditHistory->getComment())): ?> <?php if(strlen($creditHistory->getComment())): ?>

+ 68
- 43
backend/web/css/screen.css View File

} }
/* line 279, ../sass/_adminlte.scss */ /* line 279, ../sass/_adminlte.scss */
body.skin-black .content-wrapper .table th.column-actions, body.skin-black .content-wrapper .table td.column-actions { body.skin-black .content-wrapper .table th.column-actions, body.skin-black .content-wrapper .table td.column-actions {
width: 150px;
width: 172px;
text-align: right; text-align: right;
} }
/* line 283, ../sass/_adminlte.scss */ /* line 283, ../sass/_adminlte.scss */
top: 1px; top: 1px;
right: 1px; right: 1px;
} }
/* line 273, ../sass/distribution/_index.scss */
/* line 272, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-user .no-user {
color: gray;
font-style: italic;
}
/* line 278, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-delivery-note {
position: relative;
}
/* line 282, ../sass/distribution/_index.scss */
.distribution-index #orders table td.tiller { .distribution-index #orders table td.tiller {
width: 60px; width: 60px;
} }
/* line 276, ../sass/distribution/_index.scss */
/* line 285, ../sass/distribution/_index.scss */
.distribution-index #orders table td.tiller label { .distribution-index #orders table td.tiller label {
font-size: 12px; font-size: 12px;
cursor: pointer; cursor: pointer;
top: -2px; top: -2px;
font-weight: normal; font-weight: normal;
} }
/* line 285, ../sass/distribution/_index.scss */
/* line 294, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions { .distribution-index #orders table td.column-actions {
position: relative; position: relative;
text-align: right; text-align: right;
} }
/* line 289, ../sass/distribution/_index.scss */
/* line 298, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .wrapper-button-dropdown {
display: inline-block;
}
/* line 302, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .dropdown-menu { .distribution-index #orders table td.column-actions .dropdown-menu {
top: 0px;
right: 0px;
left: -70px;
width: 227px;
} }
/* line 294, ../sass/distribution/_index.scss */
/* line 307, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .modal-form-order, .distribution-index #orders table td.column-actions .modal-form-order,
.distribution-index #orders table td.column-actions .modal-payment { .distribution-index #orders table td.column-actions .modal-payment {
text-align: left; text-align: left;
} }
/* line 299, ../sass/distribution/_index.scss */
/* line 312, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .add-subscription { .distribution-index #orders table td.column-actions .add-subscription {
position: relative; position: relative;
} }
/* line 302, ../sass/distribution/_index.scss */
/* line 315, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .add-subscription .glyphicon-plus { .distribution-index #orders table td.column-actions .add-subscription .glyphicon-plus {
position: absolute; position: absolute;
top: 4px; top: 4px;
right: 4px; right: 4px;
font-size: 7px; font-size: 7px;
} }
/* line 311, ../sass/distribution/_index.scss */
/* line 324, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-state-payment { .distribution-index #orders table td.column-state-payment {
width: 120px;
width: 133px;
} }
/* line 315, ../sass/distribution/_index.scss */
/* line 330, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-credit a.positive {
color: green;
}
/* line 333, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-credit a.negative {
color: red;
}
/* line 339, ../sass/distribution/_index.scss */
.distribution-index #orders table .state-payment-mobile { .distribution-index #orders table .state-payment-mobile {
display: none; display: none;
} }
/* line 320, ../sass/distribution/_index.scss */
/* line 343, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-payment {
position: relative;
}
/* line 346, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-payment div.btn-group { .distribution-index #orders table td.column-payment div.btn-group {
width: 125px; width: 125px;
} }
/* line 326, ../sass/distribution/_index.scss */
/* line 352, ../sass/distribution/_index.scss */
.distribution-index #orders table tr.view ul { .distribution-index #orders table tr.view ul {
list-style-type: none; list-style-type: none;
margin-left: 0px; margin-left: 0px;
padding-left: 15px; padding-left: 15px;
} }
/* line 336, ../sass/distribution/_index.scss */
/* line 362, ../sass/distribution/_index.scss */
.distribution-index #orders table tr.view .comment { .distribution-index #orders table tr.view .comment {
margin-top: 20px; margin-top: 20px;
} }
/* line 340, ../sass/distribution/_index.scss */
/* line 366, ../sass/distribution/_index.scss */
.distribution-index #orders table tr.view .delivery { .distribution-index #orders table tr.view .delivery {
margin-top: 20px; margin-top: 20px;
} }
/* line 349, ../sass/distribution/_index.scss */
/* line 375, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .modal-container { .distribution-index .modal-form-order .modal-container {
width: 100%; width: 100%;
padding: 0px; padding: 0px;
} }
/* line 353, ../sass/distribution/_index.scss */
/* line 379, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .modal-container .modal-body { .distribution-index .modal-form-order .modal-container .modal-body {
padding-right: 15px; padding-right: 15px;
} }
/* line 356, ../sass/distribution/_index.scss */
/* line 382, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .modal-container .modal-body table { .distribution-index .modal-form-order .modal-container .modal-body table {
margin-bottom: 150px; margin-bottom: 150px;
} }
/* line 361, ../sass/distribution/_index.scss */
/* line 387, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .modal-container .modal-footer { .distribution-index .modal-form-order .modal-container .modal-footer {
border-top-color: #f4f4f4; border-top-color: #f4f4f4;
position: fixed; position: fixed;
text-align: center; text-align: center;
border-top: solid 1px #e0e0e0; border-top: solid 1px #e0e0e0;
} }
/* line 373, ../sass/distribution/_index.scss */
/* line 399, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .modal-container .modal-footer .actions-form button { .distribution-index .modal-form-order .modal-container .modal-footer .actions-form button {
float: none; float: none;
} }
/* line 377, ../sass/distribution/_index.scss */
/* line 403, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .modal-container .modal-footer .actions-form div.right { .distribution-index .modal-form-order .modal-container .modal-footer .actions-form div.right {
float: right; float: right;
} }
/* line 384, ../sass/distribution/_index.scss */
/* line 410, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .btn-credit { .distribution-index .modal-form-order .btn-credit {
float: right; float: right;
} }
/* line 390, ../sass/distribution/_index.scss */
/* line 416, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products .product-ordered td { .distribution-index .modal-form-order table.table-products .product-ordered td {
background-color: #e9e9e9; background-color: #e9e9e9;
} }
/* line 394, ../sass/distribution/_index.scss */
/* line 420, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products .product-ordered input.input-quantity { .distribution-index .modal-form-order table.table-products .product-ordered input.input-quantity {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
} }
/* line 400, ../sass/distribution/_index.scss */
/* line 426, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.price { .distribution-index .modal-form-order table.table-products td.price {
width: 150px; width: 150px;
} }
/* line 403, ../sass/distribution/_index.scss */
/* line 429, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.price input { .distribution-index .modal-form-order table.table-products td.price input {
text-align: center; text-align: center;
} }
/* line 407, ../sass/distribution/_index.scss */
/* line 433, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.price .input-group-addon { .distribution-index .modal-form-order table.table-products td.price .input-group-addon {
background-color: #eee; background-color: #eee;
} }
/* line 411, ../sass/distribution/_index.scss */
/* line 437, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.price .invoice-price { .distribution-index .modal-form-order table.table-products td.price .invoice-price {
margin-top: 8px; margin-top: 8px;
} }
/* line 413, ../sass/distribution/_index.scss */
/* line 439, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.price .invoice-price .label-invoice-price { .distribution-index .modal-form-order table.table-products td.price .invoice-price .label-invoice-price {
font-size: 11px; font-size: 11px;
font-weight: bold; font-weight: bold;
color: gray; color: gray;
} }
/* line 421, ../sass/distribution/_index.scss */
/* line 447, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity { .distribution-index .modal-form-order table.table-products td.quantity {
width: 165px; width: 165px;
} }
/* line 424, ../sass/distribution/_index.scss */
/* line 450, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity input { .distribution-index .modal-form-order table.table-products td.quantity input {
text-align: center; text-align: center;
color: black; color: black;
} }
/* line 429, ../sass/distribution/_index.scss */
/* line 455, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity .form-control { .distribution-index .modal-form-order table.table-products td.quantity .form-control {
border-right: 0px none; border-right: 0px none;
padding-right: 4px; padding-right: 4px;
} }
/* line 434, ../sass/distribution/_index.scss */
/* line 460, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity .input-group-addon { .distribution-index .modal-form-order table.table-products td.quantity .input-group-addon {
padding: 5px; padding: 5px;
padding-left: 0px; padding-left: 0px;
border-left: 0px none; border-left: 0px none;
border-right: 0px none; border-right: 0px none;
} }
/* line 443, ../sass/distribution/_index.scss */
/* line 469, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining { .distribution-index .modal-form-order table.table-products td.quantity-remaining {
text-align: right; text-align: right;
} }
/* line 446, ../sass/distribution/_index.scss */
/* line 472, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining.quantity-remaining, .distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite { .distribution-index .modal-form-order table.table-products td.quantity-remaining.quantity-remaining, .distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite {
color: #00A65A; color: #00A65A;
} }
/* line 450, ../sass/distribution/_index.scss */
/* line 476, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining.negative { .distribution-index .modal-form-order table.table-products td.quantity-remaining.negative {
color: #DD4B39; color: #DD4B39;
} }
/* line 454, ../sass/distribution/_index.scss */
/* line 480, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite, .distribution-index .modal-form-order table.table-products td.quantity-remaining.empty { .distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite, .distribution-index .modal-form-order table.table-products td.quantity-remaining.empty {
font-size: 18px; font-size: 18px;
} }
/* line 461, ../sass/distribution/_index.scss */
/* line 487, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .actions-form button { .distribution-index .modal-form-order .actions-form button {
margin-left: 15px; margin-left: 15px;
} }
/* line 469, ../sass/distribution/_index.scss */
/* line 495, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-icon { .distribution-index .modal-payment .info-box .info-box-icon {
width: 50px; width: 50px;
} }
/* line 472, ../sass/distribution/_index.scss */
/* line 498, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-icon i { .distribution-index .modal-payment .info-box .info-box-icon i {
font-size: 30px; font-size: 30px;
} }
/* line 477, ../sass/distribution/_index.scss */
/* line 503, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-content { .distribution-index .modal-payment .info-box .info-box-content {
margin-left: 50px; margin-left: 50px;
} }

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

pointsSale: [], pointsSale: [],
meansPayment: [], meansPayment: [],
idActivePointSale: 0, idActivePointSale: 0,
pointSaleActive: null,
idDefaultPointSale: 0, idDefaultPointSale: 0,
countActivePointsSale: 0, countActivePointsSale: 0,
countOrdersByPointSale: [], countOrdersByPointSale: [],
}, },
setIdActivePointSale: function (id) { setIdActivePointSale: function (id) {
this.idActivePointSale = id; this.idActivePointSale = id;

for(key in this.pointsSale) {
if(this.pointsSale[key].id == id) {
this.pointSaleActive = this.pointsSale[key];
}
}

if (!id) { if (!id) {
this.orderCreate.id_point_sale = this.idDefaultPointSale; this.orderCreate.id_point_sale = this.idDefaultPointSale;
} else { } else {
this.orderCreate.id_point_sale = id; this.orderCreate.id_point_sale = id;
} }
setTimeout("opendistrib_popover(); opendistrib_dropdown_tooltip();", 500);
}, },
orderCreatedUpdated: function () { orderCreatedUpdated: function () {
this.showModalFormOrderCreate = false; this.showModalFormOrderCreate = false;
this.idOrderPayment = idOrder; this.idOrderPayment = idOrder;
this.showModalPayment = true; this.showModalPayment = true;
}, },
getTypePayment: function(order) {
if(order.amount_paid < order.amount) {
return 'payment';
}
else {
return 'refund';
}
},
isTypePayment: function(order) {
return this.getTypePayment(order) == 'payment';
},
getLabelPaymentRefund: function(order, labelPay, labelRefund, labelMeanPayment) {
var str = '';

if(this.isTypePayment(order)) {
str += labelPay;
}
else {
str += labelRefund;
}

str += ' '+labelMeanPayment;

return str;
},
orderPaymentClick: function (event) { orderPaymentClick: function (event) {
var app = this; var app = this;
var idOrder = event.currentTarget.getAttribute('data-id-order'); var idOrder = event.currentTarget.getAttribute('data-id-order');
params: { params: {
idOrder: idOrder, idOrder: idOrder,
type: event.currentTarget.getAttribute('data-type'), type: event.currentTarget.getAttribute('data-type'),
amount: event.currentTarget.getAttribute('data-amount')
meanPayment: event.currentTarget.getAttribute('data-mean-payment')
//amount: event.currentTarget.getAttribute('data-amount')
} }
}) })
.then(function (response) { .then(function (response) {


return false; return false;
}, },
countDocuments: function(order) {
var count = 0;

if(order.id_delivery_note) {
count ++;
}

if(order.id_quotation) {
count ++;
}

if(order.id_invoice) {
count ++;
}

return count;
}
}, },
}); });



+ 1
- 1
backend/web/sass/_adminlte.scss View File

font-size: 13px ; font-size: 13px ;
} }
th.column-actions, td.column-actions { th.column-actions, td.column-actions {
width: 150px ;
width: 172px;
text-align: right ; text-align: right ;
} }
td.text-small, th.text-small { td.text-small, th.text-small {

+ 29
- 3
backend/web/sass/distribution/_index.scss View File

top: 1px; top: 1px;
right: 1px; right: 1px;
} }

.no-user {
color: gray;
font-style: italic;
}
}

td.column-delivery-note {
position: relative;
} }


td.tiller { td.tiller {
position: relative; position: relative;
text-align: right; text-align: right;


.wrapper-button-dropdown {
display: inline-block;
}

.dropdown-menu { .dropdown-menu {
top: 0px;
right: 0px;
left: -70px;
width: 227px;
} }


.modal-form-order, .modal-form-order,
} }


td.column-state-payment { td.column-state-payment {
width: 120px;
width: 133px;
}

td.column-credit {
a {
&.positive {
color: green;
}
&.negative {
color: red;
}
}
} }


.state-payment-mobile { .state-payment-mobile {
} }


td.column-payment { td.column-payment {
position: relative;

div.btn-group { div.btn-group {
width: 125px; width: 125px;
} }

+ 1
- 1
common/components/BusinessLogic.php View File

$this->getTaxRateContainer(), $this->getTaxRateContainer(),
$this->getUserUserGroupContainer(), $this->getUserUserGroupContainer(),
$this->getUserGroupContainer(), $this->getUserGroupContainer(),
$this->getCreditHistoryContainer(),
$this->getPaymentContainer(),
$this->getProducerPriceRangeContainer(), $this->getProducerPriceRangeContainer(),
$this->getUserProducerContainer(), $this->getUserProducerContainer(),
$this->getUserPointSaleContainer(), $this->getUserPointSaleContainer(),

+ 6
- 6
common/components/BusinessLogicTrait.php View File

use common\logic\Order\Order\Wrapper\OrderManager; use common\logic\Order\Order\Wrapper\OrderManager;
use common\logic\Order\ProductOrder\Wrapper\ProductOrderContainer; use common\logic\Order\ProductOrder\Wrapper\ProductOrderContainer;
use common\logic\Order\ProductOrder\Wrapper\ProductOrderManager; use common\logic\Order\ProductOrder\Wrapper\ProductOrderManager;
use common\logic\Payment\Wrapper\PaymentContainer;
use common\logic\Payment\Wrapper\PaymentManager;
use common\logic\PointSale\PointSale\Wrapper\PointSaleContainer; use common\logic\PointSale\PointSale\Wrapper\PointSaleContainer;
use common\logic\PointSale\PointSale\Wrapper\PointSaleManager; use common\logic\PointSale\PointSale\Wrapper\PointSaleManager;
use common\logic\PointSale\UserPointSale\Wrapper\UserPointSaleContainer; use common\logic\PointSale\UserPointSale\Wrapper\UserPointSaleContainer;
use common\logic\Ticket\TicketMessage\Wrapper\TicketMessageManager; use common\logic\Ticket\TicketMessage\Wrapper\TicketMessageManager;
use common\logic\Ticket\TicketUser\Wrapper\TicketUserContainer; use common\logic\Ticket\TicketUser\Wrapper\TicketUserContainer;
use common\logic\Ticket\TicketUser\Wrapper\TicketUserManager; use common\logic\Ticket\TicketUser\Wrapper\TicketUserManager;
use common\logic\User\CreditHistory\Wrapper\CreditHistoryContainer;
use common\logic\User\CreditHistory\Wrapper\CreditHistoryManager;
use common\logic\User\User\Wrapper\UserContainer; use common\logic\User\User\Wrapper\UserContainer;
use common\logic\User\User\Wrapper\UserManager; use common\logic\User\User\Wrapper\UserManager;
use common\logic\User\UserGroup\Wrapper\UserGroupContainer; use common\logic\User\UserGroup\Wrapper\UserGroupContainer;
return SubscriptionManager::getInstance(); return SubscriptionManager::getInstance();
} }


public function getCreditHistoryManager(): CreditHistoryManager
public function getPaymentManager(): PaymentManager
{ {
return CreditHistoryManager::getInstance();
return PaymentManager::getInstance();
} }


public function getUserManager(): UserManager public function getUserManager(): UserManager
return UserProducerContainer::getInstance(); return UserProducerContainer::getInstance();
} }


public function getCreditHistoryContainer(): CreditHistoryContainer
public function getPaymentContainer(): PaymentContainer
{ {
return CreditHistoryContainer::getInstance();
return PaymentContainer::getInstance();
} }


public function getDocumentContainer(): DocumentContainer public function getDocumentContainer(): DocumentContainer

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

use common\logic\Document\DeliveryNote\Model\DeliveryNote; use common\logic\Document\DeliveryNote\Model\DeliveryNote;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\Ticket\Ticket\Model\Ticket; use common\logic\Ticket\Ticket\Model\Ticket;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\Payment\Model\Payment;


$serverName = isset($_SERVER['SERVER_NAME']) ?? ''; $serverName = isset($_SERVER['SERVER_NAME']) ?? '';


'listeners' => [], 'listeners' => [],
'observers' => [ 'observers' => [
Order::class => [ Order::class => [
// CreditHistory : remboursement commande
common\logic\User\CreditHistory\Event\OrderObserver::class
// Payment : remboursement commande
common\logic\Payment\Event\OrderObserver::class
], ],
CreditHistory::class => [
Payment::class => [
// UserProducer : mise à jour du crédit // UserProducer : mise à jour du crédit
common\logic\User\UserProducer\Event\CreditHistoryObserver::class
common\logic\User\UserProducer\Event\PaymentObserver::class
], ],
Distribution::class => [ Distribution::class => [
// Subscription : génération des commandes sur base des abonnements // Subscription : génération des commandes sur base des abonnements

+ 3
- 1
common/helpers/GlobalParam.php View File

namespace common\helpers; namespace common\helpers;


use common\logic\Producer\Producer\Model\Producer; use common\logic\Producer\Producer\Model\Producer;
use common\logic\Producer\Producer\Wrapper\ProducerManager;
use common\logic\User\User\Service\UserSolver; use common\logic\User\User\Service\UserSolver;


class GlobalParam class GlobalParam


public static function getCurrentProducer() public static function getCurrentProducer()
{ {
$producerManager = ProducerManager::getInstance();
if(!\Yii::$app->parameterBag->has('producer') || !\Yii::$app->parameterBag->get('producer')) { if(!\Yii::$app->parameterBag->has('producer') || !\Yii::$app->parameterBag->get('producer')) {
\Yii::$app->parameterBag->set('producer', Producer::searchOne());
\Yii::$app->parameterBag->set('producer', $producerManager->findOneProducerById(self::getCurrentProducerId()));
} }


return \Yii::$app->parameterBag->get('producer'); return \Yii::$app->parameterBag->get('producer');

+ 1
- 1
common/helpers/MeanPayment.php View File

public static function getStrBy($meanPayment) public static function getStrBy($meanPayment)
{ {
switch($meanPayment) { switch($meanPayment) {
case self::CREDIT_CARD : return 'Paiement en ligne' ;
case self::CREDIT_CARD : return 'Carte bancaire' ;
case self::MONEY : return 'Espèces' ; case self::MONEY : return 'Espèces' ;
case self::CHEQUE : return 'Chèque' ; case self::CHEQUE : return 'Chèque' ;
case self::TRANSFER : return 'Virement' ; case self::TRANSFER : return 'Virement' ;

+ 15
- 0
common/logic/Document/Document/Service/DocumentSolver.php View File

return null; return null;
} }


public function isDocumentDeliveryNote(DocumentInterface $document): bool
{
return $this->getClass($document) == 'DeliveryNote';
}

public function isDocumentInvoice(DocumentInterface $document): bool
{
return $this->getClass($document) == 'Invoice';
}

public function isDocumentQuotation(DocumentInterface $document): bool
{
return $this->getClass($document) == 'Quotation';
}

public function getClass(DocumentInterface $document, bool $pathComplete = false): string public function getClass(DocumentInterface $document, bool $pathComplete = false): string
{ {
$classDocument = get_class($document); $classDocument = get_class($document);

+ 7
- 0
common/logic/Document/Invoice/Model/Invoice.php View File

namespace common\logic\Document\Invoice\Model; namespace common\logic\Document\Invoice\Model;


use common\logic\Document\Document\Model\Document; use common\logic\Document\Document\Model\Document;
use common\logic\Payment\Model\Payment;


/** /**
* This is the model class for table "invoice". * This is the model class for table "invoice".
{ {
return $this->relationOrders('id_invoice'); return $this->relationOrders('id_invoice');
} }

public function getPayments()
{
return $this->hasMany(Payment::class, ['id_invoice' => 'id'])
->orderBy(['payment.id' => SORT_DESC]);
}
} }

+ 1
- 1
common/logic/Document/Invoice/Repository/InvoiceRepository.php View File

public function getDefaultOptionsSearch(): array public function getDefaultOptionsSearch(): array
{ {
return [ return [
self::WITH => [],
self::WITH => ['payments'],
self::JOIN_WITH => ['user AS user_invoice', 'producer'], self::JOIN_WITH => ['user AS user_invoice', 'producer'],
self::ORDER_BY => 'date ASC', self::ORDER_BY => 'date ASC',
self::ATTRIBUTE_ID_PRODUCER => 'invoice.id_producer' self::ATTRIBUTE_ID_PRODUCER => 'invoice.id_producer'

+ 26
- 0
common/logic/Document/Invoice/Service/InvoiceSolver.php View File

<?php

namespace common\logic\Document\Invoice\Service;

use common\helpers\Price;
use common\logic\Document\Document\Service\DocumentSolver;
use common\logic\Document\Invoice\Model\Invoice;

class InvoiceSolver extends DocumentSolver
{
public function getInvoiceAmountPaid(Invoice $invoice): float
{
$amountPaid = 0;

foreach($invoice->payments as $payment) {
$amountPaid += $payment->amount;
}

return $amountPaid;
}

public function isInvoicePaid(Invoice $invoice): bool
{
return $this->getInvoiceAmountPaid($invoice) >= Price::numberTwoDecimals($this->getAmountWithTax($invoice));
}
}

+ 4
- 4
common/logic/Document/Invoice/Wrapper/InvoiceContainer.php View File

namespace common\logic\Document\Invoice\Wrapper; namespace common\logic\Document\Invoice\Wrapper;


use common\logic\AbstractContainer; use common\logic\AbstractContainer;
use common\logic\Document\Document\Service\DocumentSolver;
use common\logic\Document\Invoice\Repository\InvoiceRepository; use common\logic\Document\Invoice\Repository\InvoiceRepository;
use common\logic\Document\Invoice\Service\InvoiceBuilder; use common\logic\Document\Invoice\Service\InvoiceBuilder;
use common\logic\Document\Invoice\Service\InvoiceDefinition; use common\logic\Document\Invoice\Service\InvoiceDefinition;
use common\logic\Document\Invoice\Service\InvoiceSolver;


class InvoiceContainer extends AbstractContainer class InvoiceContainer extends AbstractContainer
{ {
{ {
return [ return [
InvoiceDefinition::class, InvoiceDefinition::class,
DocumentSolver::class,
InvoiceSolver::class,
InvoiceRepository::class, InvoiceRepository::class,
InvoiceBuilder::class, InvoiceBuilder::class,
]; ];
return InvoiceDefinition::getInstance(); return InvoiceDefinition::getInstance();
} }


public function getSolver(): DocumentSolver
public function getSolver(): InvoiceSolver
{ {
return DocumentSolver::getInstance();
return InvoiceSolver::getInstance();
} }


public function getRepository(): InvoiceRepository public function getRepository(): InvoiceRepository

+ 2
- 0
common/logic/Document/Invoice/Wrapper/InvoiceManager.php View File

use common\logic\Document\Invoice\Repository\InvoiceRepository; use common\logic\Document\Invoice\Repository\InvoiceRepository;
use common\logic\Document\Invoice\Service\InvoiceBuilder; use common\logic\Document\Invoice\Service\InvoiceBuilder;
use common\logic\Document\Invoice\Service\InvoiceDefinition; use common\logic\Document\Invoice\Service\InvoiceDefinition;
use common\logic\Document\Invoice\Service\InvoiceSolver;


/** /**
* @mixin InvoiceDefinition * @mixin InvoiceDefinition
* @mixin InvoiceSolver
* @mixin InvoiceRepository * @mixin InvoiceRepository
* @mixin InvoiceBuilder * @mixin InvoiceBuilder
*/ */

+ 4
- 3
common/logic/Order/Order/Model/Order.php View File

use common\logic\Document\Invoice\Model\Invoice; use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Document\Quotation\Model\Quotation; use common\logic\Document\Quotation\Model\Quotation;
use common\logic\Order\ProductOrder\Model\ProductOrder; use common\logic\Order\ProductOrder\Model\ProductOrder;
use common\logic\Payment\Model\Payment;
use common\logic\PointSale\PointSale\Model\PointSale; use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\Subscription\Subscription\Model\Subscription; use common\logic\Subscription\Subscription\Model\Subscription;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;


$this->populateFieldObject('id_point_sale', 'point_sale', $pointSale); $this->populateFieldObject('id_point_sale', 'point_sale', $pointSale);
} }


public function getCreditHistory()
public function getPayment()
{ {
return $this->hasMany(CreditHistory::class, ['id_order' => 'id']);
return $this->hasMany(Payment::class, ['id_order' => 'id'])
->orderBy(['payment.id' => SORT_DESC]);
} }


public function getSubscription() public function getSubscription()

+ 90
- 8
common/logic/Order/Order/Repository/OrderRepository.php View File

use common\logic\Distribution\Distribution\Repository\DistributionRepository; use common\logic\Distribution\Distribution\Repository\DistributionRepository;
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository; use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository;
use common\logic\Document\Invoice\Model\Invoice; use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Document\Invoice\Repository\InvoiceRepository;
use common\logic\Document\Invoice\Service\InvoiceSolver;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Service\OrderSolver; use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Order\ProductOrder\Repository\ProductOrderRepository; use common\logic\Order\ProductOrder\Repository\ProductOrderRepository;
use common\logic\Payment\Model\Payment;
use common\logic\Payment\Service\PaymentSolver;
use common\logic\PointSale\PointSale\Model\PointSale; use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\PointSale\PointSale\Repository\PointSaleRepository; use common\logic\PointSale\PointSale\Repository\PointSaleRepository;
use common\logic\PointSale\UserPointSale\Repository\UserPointSaleRepository; use common\logic\PointSale\UserPointSale\Repository\UserPointSaleRepository;
protected DistributionRepository $distributionRepository; protected DistributionRepository $distributionRepository;
protected PointSaleRepository $pointSaleRepository; protected PointSaleRepository $pointSaleRepository;
protected UserPointSaleRepository $userPointSaleRepository; protected UserPointSaleRepository $userPointSaleRepository;
protected InvoiceRepository $invoiceRepository;
protected InvoiceSolver $invoiceSolver;
protected PaymentSolver $paymentSolver;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->distributionRepository = $this->loadService(DistributionRepository::class); $this->distributionRepository = $this->loadService(DistributionRepository::class);
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class); $this->pointSaleRepository = $this->loadService(PointSaleRepository::class);
$this->userPointSaleRepository = $this->loadService(UserPointSaleRepository::class); $this->userPointSaleRepository = $this->loadService(UserPointSaleRepository::class);
$this->invoiceRepository = $this->loadService(InvoiceRepository::class);
$this->invoiceSolver = $this->loadService(InvoiceSolver::class);
$this->paymentSolver = $this->loadService(PaymentSolver::class);
} }


public function getDefaultOptionsSearch(): array public function getDefaultOptionsSearch(): array
self::WITH => [ self::WITH => [
'productOrder', 'productOrder',
'productOrder.product', 'productOrder.product',
'creditHistory',
'creditHistory.userAction',
'productOrder.taxRate',
'pointSale', 'pointSale',
'payment',
'payment.user',
'payment.userAction',
'deliveryNote',
'invoice',
'quotation'
], ],
self::JOIN_WITH => [ self::JOIN_WITH => [
'distribution', 'distribution',
'user', 'user',
'user.userProducer'
'user.userProducer',
], ],
self::ORDER_BY => 'order.date ASC', self::ORDER_BY => 'order.date ASC',
self::ATTRIBUTE_ID_PRODUCER => 'distribution.id_producer' self::ATTRIBUTE_ID_PRODUCER => 'distribution.id_producer'


public function isCreditAutoPayment(Order $order) public function isCreditAutoPayment(Order $order)
{ {
$pointSale = $this->pointSaleRepository->findOnePointSaleById($order->id_point_sale);
$distribution = $this->distributionRepository->findOneDistributionById($order->id_distribution);
//$pointSale = $this->pointSaleRepository->findOnePointSaleById($order->id_point_sale);
$pointSale = $order->pointSale;


if($pointSale) { if($pointSale) {
$creditFunctioning = $this->producerRepository->getPointSaleCreditFunctioning($pointSale); $creditFunctioning = $this->producerRepository->getPointSaleCreditFunctioning($pointSale);


if ($order->id_user && $this->producerRepository->getConfig('credit') && $pointSale->credit) { if ($order->id_user && $this->producerRepository->getConfig('credit') && $pointSale->credit) {
if($order->mean_payment == MeanPayment::CREDIT || $creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) { if($order->mean_payment == MeanPayment::CREDIT || $creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) {
return 1;
return true;
} }
elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) { elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) {
return 0;
return false;
} }
elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) { elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) {
$userProducer = $this->userProducerRepository->findOneUserProducer($order->user); $userProducer = $this->userProducerRepository->findOneUserProducer($order->user);
} }
} }


return 0;
return false;
}

public function isCreditContext(Order $order)
{
if(!$this->producerRepository->getConfig('credit')) {
return false;
}

//$pointSale = $this->pointSaleRepository->findOnePointSaleById($order->id_point_sale);
$pointSale = $order->pointSale;

if($pointSale) {
$creditFunctioning = $this->producerRepository->getPointSaleCreditFunctioning($pointSale);
if ($order->id_user && $this->producerRepository->getConfig('credit') && $pointSale->credit) {
if($order->mean_payment == MeanPayment::CREDIT
|| $creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY
|| $creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) {

return true;
}
elseif ($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) {
$userProducer = $this->userProducerRepository->findOneUserProducer($order->user);
if ($userProducer) {
return $userProducer->credit_active;
}
}
}
}

return false;
} }


public function findOneOrderLastByUser(User $user) public function findOneOrderLastByUser(User $user)


return $orders->all(); return $orders->all();
} }


public function isOrderPaid(Order $order): bool
{
$amountPaid = $this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID);
$amountTotal = $this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_TOTAL);

if(abs($amountPaid - $amountTotal) < 0.00001
|| $amountPaid >= $amountTotal) {
return true;
}

return $this->isOrderPaidViaInvoice($order);
}

public function isOrderPaidViaInvoice(Order $order): bool
{
if($order->invoice) {
$invoice = $this->invoiceRepository->findOneInvoiceById($order->id_invoice);
if($invoice && $this->invoiceSolver->isInvoicePaid($invoice)) {
return true;
}
}

return false;
}

public function getMainPayment(Order $order): ?Payment
{
foreach($order->payment as $payment) {
if($this->paymentSolver->isTypeDebit($payment)) {
return $payment;
}
}

return null;
}
} }

+ 16
- 25
common/logic/Order/Order/Service/OrderBuilder.php View File

use common\logic\Order\ProductOrder\Model\ProductOrder; use common\logic\Order\ProductOrder\Model\ProductOrder;
use common\logic\Order\ProductOrder\Service\ProductOrderBuilder; use common\logic\Order\ProductOrder\Service\ProductOrderBuilder;
use common\logic\Order\ProductOrder\Service\ProductOrderSolver; use common\logic\Order\ProductOrder\Service\ProductOrderSolver;
use common\logic\Payment\Model\Payment;
use common\logic\Payment\Repository\PaymentRepository;
use common\logic\Payment\Service\PaymentBuilder;
use common\logic\PointSale\PointSale\Model\PointSale; use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\PointSale\PointSale\Service\PointSaleBuilder; use common\logic\PointSale\PointSale\Service\PointSaleBuilder;
use common\logic\PointSale\PointSale\Repository\PointSaleRepository; use common\logic\PointSale\PointSale\Repository\PointSaleRepository;
use common\logic\Subscription\Subscription\Service\SubscriptionBuilder; use common\logic\Subscription\Subscription\Service\SubscriptionBuilder;
use common\logic\Subscription\Subscription\Repository\SubscriptionRepository; use common\logic\Subscription\Subscription\Repository\SubscriptionRepository;
use common\logic\Subscription\Subscription\Service\SubscriptionSolver; use common\logic\Subscription\Subscription\Service\SubscriptionSolver;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\CreditHistory\Service\CreditHistoryBuilder;
use common\logic\User\CreditHistory\Repository\CreditHistoryRepository;
use common\logic\User\User\Repository\UserRepository; use common\logic\User\User\Repository\UserRepository;
use common\logic\User\User\Service\UserSolver; use common\logic\User\User\Service\UserSolver;
use common\logic\User\UserProducer\Repository\UserProducerRepository; use common\logic\User\UserProducer\Repository\UserProducerRepository;
{ {
protected UserSolver $userSolver; protected UserSolver $userSolver;
protected OrderSolver $orderSolver; protected OrderSolver $orderSolver;
protected CreditHistoryRepository $creditHistoryRepository;
protected PaymentRepository $paymentRepository;
protected ProducerRepository $producerRepository; protected ProducerRepository $producerRepository;
protected CreditHistoryBuilder $creditHistoryBuilder;
protected PaymentBuilder $paymentBuilder;
protected ProductOrderBuilder $productOrderBuilder; protected ProductOrderBuilder $productOrderBuilder;
protected OrderRepository $orderRepository; protected OrderRepository $orderRepository;
protected DistributionRepository $distributionRepository; protected DistributionRepository $distributionRepository;
{ {
$this->userSolver = $this->loadService(UserSolver::class); $this->userSolver = $this->loadService(UserSolver::class);
$this->orderSolver = $this->loadService(OrderSolver::class); $this->orderSolver = $this->loadService(OrderSolver::class);
$this->creditHistoryRepository = $this->loadService(CreditHistoryRepository::class);
$this->paymentRepository = $this->loadService(PaymentRepository::class);
$this->producerRepository = $this->loadService(ProducerRepository::class); $this->producerRepository = $this->loadService(ProducerRepository::class);
$this->creditHistoryBuilder = $this->loadService(CreditHistoryBuilder::class);
$this->paymentBuilder = $this->loadService(PaymentBuilder::class);
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); $this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class);
$this->orderRepository = $this->loadService(OrderRepository::class); $this->orderRepository = $this->loadService(OrderRepository::class);
$this->distributionRepository = $this->loadService(DistributionRepository::class); $this->distributionRepository = $this->loadService(DistributionRepository::class);
public function deleteOrdersIncomingDistributionsFromSubscription(Subscription $subscription, bool $deleteAfterDateEnd = false): int public function deleteOrdersIncomingDistributionsFromSubscription(Subscription $subscription, bool $deleteAfterDateEnd = false): int
{ {
$ordersArray = $this->orderRepository->findOrdersIncomingBySubscription($subscription, !$deleteAfterDateEnd); $ordersArray = $this->orderRepository->findOrdersIncomingBySubscription($subscription, !$deleteAfterDateEnd);


$countOrdersDeleted = 0; $countOrdersDeleted = 0;

if ($ordersArray && count($ordersArray)) { if ($ordersArray && count($ordersArray)) {
foreach ($ordersArray as $order) { foreach ($ordersArray as $order) {
if ($this->distributionSolver->isDistributionAvailable($order->distribution)) { if ($this->distributionSolver->isDistributionAvailable($order->distribution)) {
*/ */
public function initOrderPaidAmount(Order $order): void public function initOrderPaidAmount(Order $order): void
{ {
// Attention : $order->creditHistory pas à jour si un paiement vient d'avoir lieu
/*if (isset($order->creditHistory)) {
$history = $order->creditHistory;
} else {
$history = $this->creditHistoryRepository->getByOrder($order);
}*/

$history = $this->creditHistoryRepository->getByOrder($order);

$history = $order->payment;
$order->paid_amount = 0; $order->paid_amount = 0;


if (count($history)) {
foreach ($history as $ch) {
if ($ch->type == CreditHistory::TYPE_PAYMENT) {
if ($history && count($history)) {
foreach ($order->payment as $ch) {
if ($ch->type == Payment::TYPE_PAYMENT) {
$order->paid_amount += $ch->amount; $order->paid_amount += $ch->amount;
} elseif ($ch->type == CreditHistory::TYPE_REFUND) {
} elseif ($ch->type == Payment::TYPE_REFUND) {
$order->paid_amount -= $ch->amount; $order->paid_amount -= $ch->amount;
} }
} }
if ($paymentStatus == Order::PAYMENT_PAID) { if ($paymentStatus == Order::PAYMENT_PAID) {
return; return;
} elseif ($paymentStatus == Order::PAYMENT_SURPLUS) { } elseif ($paymentStatus == Order::PAYMENT_SURPLUS) {
$type = CreditHistory::TYPE_REFUND;
$type = Payment::TYPE_REFUND;
$amount = $this->orderSolver->getOrderAmount($order, Order::AMOUNT_SURPLUS); $amount = $this->orderSolver->getOrderAmount($order, Order::AMOUNT_SURPLUS);
} elseif ($paymentStatus == Order::PAYMENT_UNPAID) { } elseif ($paymentStatus == Order::PAYMENT_UNPAID) {
$type = CreditHistory::TYPE_PAYMENT;
$type = Payment::TYPE_PAYMENT;
$amount = $this->orderSolver->getOrderAmount($order, Order::AMOUNT_REMAINING); $amount = $this->orderSolver->getOrderAmount($order, Order::AMOUNT_REMAINING);
} }


$this->creditHistoryBuilder->createCreditHistory(
$this->paymentBuilder->createPayment(
$type, $type,
$amount, $amount,
GlobalParam::getCurrentProducer(), GlobalParam::getCurrentProducer(),

+ 36
- 10
common/logic/Order/Order/Service/OrderSolver.php View File

use common\logic\Document\Document\Model\Document; use common\logic\Document\Document\Model\Document;
use common\logic\Document\Document\Service\DocumentSolver; use common\logic\Document\Document\Service\DocumentSolver;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\Payment\Model\Payment;
use common\logic\Payment\Service\PaymentSolver;
use common\logic\Producer\Producer\Service\ProducerSolver; use common\logic\Producer\Producer\Service\ProducerSolver;
use common\logic\Product\Product\Model\Product; use common\logic\Product\Product\Model\Product;
use common\logic\SolverInterface; use common\logic\SolverInterface;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\CreditHistory\Service\CreditHistorySolver;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use common\logic\User\User\Service\UserSolver; use common\logic\User\User\Service\UserSolver;
use yii\helpers\Html; use yii\helpers\Html;
{ {
protected UserSolver $userSolver; protected UserSolver $userSolver;
protected DocumentSolver $documentSolver; protected DocumentSolver $documentSolver;
protected CreditHistorySolver $creditHistorySolver;
protected PaymentSolver $paymentSolver;
protected ProducerSolver $producerSolver; protected ProducerSolver $producerSolver;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->documentSolver = $this->loadService(DocumentSolver::class); $this->documentSolver = $this->loadService(DocumentSolver::class);
$this->userSolver = $this->loadService(UserSolver::class); $this->userSolver = $this->loadService(UserSolver::class);
$this->creditHistorySolver = $this->loadService(CreditHistorySolver::class);
$this->paymentSolver = $this->loadService(PaymentSolver::class);
$this->producerSolver = $this->loadService(ProducerSolver::class); $this->producerSolver = $this->loadService(ProducerSolver::class);
} }


} }
} }


public function getOrderAmountPaidByCredit(Order $order): float
{
$amount = 0;

foreach($order->payment as $payment) {
if($this->paymentSolver->isMeanPaymentCredit($payment)) {
$amount += $payment->amount;
}
}

return $amount;
}

public function getOrderAmountPaid(Order $order): float
{
$amount = 0;

foreach($order->payment as $payment) {
$amount += $payment->amount;
}

return $amount;
}

/** /**
* Retourne le montant de la commande (total, payé, restant, ou en surplus). * Retourne le montant de la commande (total, payé, restant, ou en surplus).
*/ */
$amount = $order->invoice_amount + $this->getOrderTotalVat($order, $type); $amount = $order->invoice_amount + $this->getOrderTotalVat($order, $type);
} }


$amount = round($amount, 2);

return $this->_getAmountGeneric($order, $type, $amount, $format); return $this->_getAmountGeneric($order, $type, $amount, $format);
} }


* (libellé, montant, client, action) au format HTML. * (libellé, montant, client, action) au format HTML.
* *
*/ */
public function getCreditHistoryComment(CreditHistory $creditHistory): string
public function getPaymentComment(Payment $payment): string
{ {
$str = ''; $str = '';
if (strlen($creditHistory->getComment())) {
if (strlen($payment->getComment())) {
$str .= '<br />'; $str .= '<br />';
} }


$str .= $this->creditHistorySolver->getStrWording($creditHistory);
$str .= $this->paymentSolver->getStrWording($payment);


$order = $creditHistory->getOrderObject();
$order = $payment->getOrderObject();
if ($order) { if ($order) {
$str .= '<br />Montant de la commande : ' . $this->getOrderAmountWithTax($order, Order::AMOUNT_TOTAL, true); $str .= '<br />Montant de la commande : ' . $this->getOrderAmountWithTax($order, Order::AMOUNT_TOTAL, true);
} }


$user = $creditHistory->getUserObject();
$user = $payment->getUserObject();
if ($user) { if ($user) {
$str .= '<br />Client : ' . Html::encode($user->getName() . ' ' . $user->getLastname()); $str .= '<br />Client : ' . Html::encode($user->getName() . ' ' . $user->getLastname());
} }


$userAction = $creditHistory->getUserActionObject();
$userAction = $payment->getUserActionObject();
if ($userAction) { if ($userAction) {
$str .= '<br />Action : ' . Html::encode($userAction->getName() . ' ' . $userAction->getLastname()); $str .= '<br />Action : ' . Html::encode($userAction->getName() . ' ' . $userAction->getLastname());
} }

+ 2
- 1
common/logic/Order/ProductOrder/Model/ProductOrder.php View File



public function afterFind() public function afterFind()
{ {
if ($this->taxRate == null) {
if(!$this->id_tax_rate) {
$this->populateRelation('taxRate', GlobalParam::getCurrentProducer()->taxRate); $this->populateRelation('taxRate', GlobalParam::getCurrentProducer()->taxRate);
} }

parent::afterFind(); parent::afterFind();
} }



common/logic/User/CreditHistory/Event/OrderObserver.php → common/logic/Payment/Event/OrderObserver.php View File

<?php <?php


namespace common\logic\User\CreditHistory\Event;
namespace common\logic\Payment\Event;


use common\logic\Order\Order\Event\OrderDeleteEvent; use common\logic\Order\Order\Event\OrderDeleteEvent;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\User\CreditHistory\Wrapper\CreditHistoryManager;
use common\logic\Payment\Wrapper\PaymentManager;
use common\logic\User\User\Wrapper\UserManager; use common\logic\User\User\Wrapper\UserManager;
use justcoded\yii2\eventlistener\observers\Observer; use justcoded\yii2\eventlistener\observers\Observer;


public function onOrderDelete(OrderDeleteEvent $event) public function onOrderDelete(OrderDeleteEvent $event)
{ {
$order = $event->order; $order = $event->order;
$creditHistoryManager = CreditHistoryManager::getInstance();
$paymentManager = PaymentManager::getInstance();
$userManager = UserManager::getInstance(); $userManager = UserManager::getInstance();


$creditHistoryManager->refundOrder($order, $userManager->getCurrent());
$paymentManager->refundOrderCredit($order, $userManager->getCurrent());
} }
} }

common/logic/User/CreditHistory/Model/CreditHistorySearch.php → common/logic/Payment/Model/CreditHistorySearch.php View File

termes. termes.
*/ */


namespace common\logic\User\CreditHistory\Model;
namespace common\logic\Payment\Model;


use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\logic\User\CreditHistory\Repository\CreditHistoryRepository;
use common\helpers\MeanPayment;
use common\logic\Payment\Repository\PaymentRepository;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;


class CreditHistorySearch extends CreditHistory
class CreditHistorySearch extends Payment
{ {
public function rules(): array public function rules(): array
public function search($params) public function search($params)
{ {
$creditHistoryRepository = CreditHistoryRepository::getInstance();
$optionsSearch = $creditHistoryRepository->getDefaultOptionsSearch() ;
$paymentRepository = PaymentRepository::getInstance();
$optionsSearch = $paymentRepository->getDefaultOptionsSearch() ;
$query = CreditHistory::find()
$query = Payment::find()
->with($optionsSearch['with']) ->with($optionsSearch['with'])
->innerJoinWith($optionsSearch['join_with'], true) ->innerJoinWith($optionsSearch['join_with'], true)
->where(['credit_history.id_producer' => GlobalParam::getCurrentProducerId()])
->where([
'payment.id_producer' => GlobalParam::getCurrentProducerId(),
'payment.mean_payment' => MeanPayment::CREDIT
])
->orderBy('id DESC') ->orderBy('id DESC')
; ;
if(isset($this->id_user) && is_numeric($this->id_user)) { if(isset($this->id_user) && is_numeric($this->id_user)) {
$query->andWhere([ $query->andWhere([
'credit_history.id_user' => $this->id_user
'payment.id_user' => $this->id_user
]) ; ]) ;
} }



common/logic/User/CreditHistory/Model/CreditHistory.php → common/logic/Payment/Model/Payment.php View File

* termes. * termes.
*/ */


namespace common\logic\User\CreditHistory\Model;
namespace common\logic\Payment\Model;


use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;
use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\Producer\Producer\Model\Producer; use common\logic\Producer\Producer\Model\Producer;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use common\logic\User\UserProducer\Event\UserProducerEventSubscriber;
use yii\db\ActiveQuery; use yii\db\ActiveQuery;


class CreditHistory extends ActiveRecordCommon
class Payment extends ActiveRecordCommon
{ {
const TYPE_INITIAL_CREDIT = 'initial-credit'; const TYPE_INITIAL_CREDIT = 'initial-credit';
const TYPE_CREDIT = 'credit'; const TYPE_CREDIT = 'credit';
*/ */
public static function tableName(): string public static function tableName(): string
{ {
return 'credit_history';
return 'payment';
} }


/** /**
{ {
return [ return [
[['amount'], 'required'], [['amount'], 'required'],
[['id_user', 'id_user_action', 'id_order', 'id_producer'], 'integer'],
[['id_user', 'id_user_action', 'id_order', 'id_invoice', 'id_producer'], 'integer'],
[['date'], 'safe'], [['date'], 'safe'],
[['amount'], 'double'], [['amount'], 'double'],
[['date_transaction'], 'date', 'format' => 'php:Y-m-d'],
[['type', 'mean_payment'], 'string', 'max' => 255], [['type', 'mean_payment'], 'string', 'max' => 255],
[['comment'], 'string', 'max' => 2048], [['comment'], 'string', 'max' => 2048],
]; ];
'id_user' => 'Utilisateur', 'id_user' => 'Utilisateur',
'id_user_action' => 'Utilisateur', 'id_user_action' => 'Utilisateur',
'id_order' => 'Commande', 'id_order' => 'Commande',
'id_invoice' => 'Facture',
'date' => 'Date', 'date' => 'Date',
'amount' => 'Montant', 'amount' => 'Montant',
'type' => 'Type', 'type' => 'Type',
'id_producer' => 'Producteur', 'id_producer' => 'Producteur',
'mean_payment' => 'Moyen de paiement', 'mean_payment' => 'Moyen de paiement',
'comment' => 'Commentaire', 'comment' => 'Commentaire',
'date_transaction' => 'Date transaction'
]; ];
} }


return $this->order; return $this->order;
} }


public function getInvoice(): ActiveQuery
{
return $this->hasOne(Invoice::class, ['id' => 'id_invoice']);
}

public function populateInvoice(Invoice $invoice): void
{
$this->populateFieldObject('id_invoice', 'invoice', $invoice);
}

public function getInvoiceObject(): ?Invoice
{
return $this->invoice;
}

/* /*
* Getters / setters * Getters / setters
*/ */

+ 36
- 0
common/logic/Payment/Repository/PaymentRepository.php View File

<?php

namespace common\logic\Payment\Repository;

use common\logic\AbstractRepository;
use common\logic\Order\Order\Model\Order;
use common\logic\Payment\Model\Payment;

class PaymentRepository extends AbstractRepository
{
protected PaymentRepositoryQuery $query;

public function loadDependencies(): void
{
$this->loadQuery(PaymentRepositoryQuery::class);
}

public function getDefaultOptionsSearch(): array
{
return [
self::WITH => [
'user'
],
self::JOIN_WITH => [],
self::ORDER_BY => Payment::tableName() . '.date ASc',
self::ATTRIBUTE_ID_PRODUCER => Payment::tableName() . '.id_producer'
];
}

public function getByOrder(Order $order)
{
return $this->createDefaultQuery()
->filterByOrder($order)
->find();
}
}

+ 23
- 0
common/logic/Payment/Repository/PaymentRepositoryQuery.php View File

<?php

namespace common\logic\Payment\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Order\Order\Model\Order;
use common\logic\Payment\Service\PaymentDefinition;

class PaymentRepositoryQuery extends AbstractRepositoryQuery
{
protected PaymentDefinition $definition;

public function loadDependencies(): void
{
$this->loadDefinition(PaymentDefinition::class);
}

public function filterByOrder(Order $order): self
{
$this->andWhere(['id_order' => $order->id]);
return $this;
}
}

+ 85
- 0
common/logic/Payment/Service/PaymentBuilder.php View File

<?php

namespace common\logic\Payment\Service;

use common\logic\AbstractBuilder;
use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Payment\Model\Payment;
use common\logic\Producer\Producer\Model\Producer;
use common\logic\User\User\Model\User;

class PaymentBuilder extends AbstractBuilder
{
protected PaymentSolver $paymentSolver;
protected OrderSolver $orderSolver;

public function loadDependencies(): void
{
$this->paymentSolver = $this->loadService(PaymentSolver::class);
$this->orderSolver = $this->loadService(OrderSolver::class);
}

public function instanciatePayment(
string $type,
float $amount,
Producer $producer,
User $user = null,
User $userAction = null,
string $meanPayment = null,
Order $order = null,
Invoice $invoice = null
): Payment
{
$payment = new Payment;

$payment->type = $type;
$payment->amount = round($amount, 2);
$payment->populateProducer($producer);

if($user) {
$payment->populateUser($user);
}

if($userAction) {
$payment->populateUserAction($userAction);
}

if($order) {
$payment->populateOrder($order);
}

if($invoice) {
$payment->populateInvoice($invoice);
}

if($meanPayment) {
$payment->mean_payment = $meanPayment;
}

return $payment;
}

public function createPayment(
string $type,
float $amount,
Producer $producer,
User $user = null,
User $userAction = null,
string $meanPayment = null,
Order $order = null,
Invoice $invoice = null
): ?Payment
{
if ($amount > -0.01 && $amount < 0.01) {
return null;
}

$payment = $this->instanciatePayment($type, $amount, $producer, $user, $userAction, $meanPayment, $order, $invoice);
$payment->setComment($payment->getComment() . $this->orderSolver->getPaymentComment($payment));
$this->create($payment);

return $payment;
}
}

+ 14
- 0
common/logic/Payment/Service/PaymentDefinition.php View File

<?php

namespace common\logic\Payment\Service;

use common\logic\AbstractDefinition;
use common\logic\Payment\Model\Payment;

class PaymentDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return Payment::class;
}
}

+ 127
- 0
common/logic/Payment/Service/PaymentSolver.php View File

<?php

namespace common\logic\Payment\Service;

use common\helpers\MeanPayment;
use common\logic\AbstractService;
use common\logic\Order\Order\Model\Order;
use common\logic\Payment\Model\Payment;
use common\logic\SolverInterface;

class PaymentSolver extends AbstractService implements SolverInterface
{
public function isTypeDebit(Payment $payment): bool
{
return in_array($payment->getType(), [
Payment::TYPE_DEBIT,
Payment::TYPE_PAYMENT,
]);
}

public function isTypeCredit(Payment $payment): bool
{
return in_array($payment->getType(), [
Payment::TYPE_CREDIT,
Payment::TYPE_INITIAL_CREDIT,
Payment::TYPE_REFUND
]);
}

public function getAmount(Payment $payment, bool $format = false): string
{
if ($format) {
return number_format($payment->getAmount(), 2) . '&nbsp;€';
} else {
return $payment->getAmount();
}
}

/**
* Retourne le libellé du CreditHistory informant de son type et
* éventuellement de la date de sa commande associée.
*
*/
public function getStrWording(Payment $payment, Order $order = null): string
{
$str = '';
$type = $payment->getType();

if (Payment::TYPE_INITIAL_CREDIT == $type) {
$str = 'Crédit initial';
} elseif (Payment::TYPE_CREDIT == $type) {
$str = 'Crédit';
} elseif (Payment::TYPE_PAYMENT == $type) {
$str = 'Débit';
} elseif (Payment::TYPE_REFUND == $type) {
$str = 'Recrédit';
} elseif (Payment::TYPE_DEBIT == $type) {
$str = 'Débit';
}

if (Payment::TYPE_PAYMENT == $type || Payment::TYPE_REFUND == $type) {

// Optimisation
if(!$order) {
$order = $payment->order;
}

if ($order && $order->distribution) {
$str .= '<br />Commande : ' . date('d/m/Y', strtotime($order->distribution->date));
} else {
$str .= '<br />Commande supprimée';
}
}

return $str;
}

public function getDate(Payment $payment, bool $format = false): string
{
$date = $payment->getDate();

if ($format) {
return date('d/m/Y à H:i:s', strtotime($date));
} else {
return $date;
}
}

public function isMeanPaymentCredit(Payment $payment): bool
{
return $payment->mean_payment == MeanPayment::CREDIT;
}

public function getStrMeanPayment(Payment $payment): string
{
return MeanPayment::getStrBy($payment->getMeanPayment());
}

public function getStrType(Payment $payment): string
{
switch($payment->type) {
case Payment::TYPE_PAYMENT:
return 'Paiement';
case Payment::TYPE_DEBIT:
return 'Débit';
case Payment::TYPE_CREDIT:
return 'Crédit';
case Payment::TYPE_REFUND:
return 'Remboursement';
case Payment::TYPE_INITIAL_CREDIT:
return 'Crédit initial';
}

return 'Type de paiement inconnu';
}

public function getStrUserAction(Payment $payment): string
{
$userAction = $payment->getUserActionObject();

if ($userAction) {
return $userAction->getName() . ' ' . $userAction->getlastname();
} else {
return 'Système';
}
}
}

common/logic/User/CreditHistory/Service/CreditUtils.php → common/logic/Payment/Service/PaymentUtils.php View File

<?php <?php


namespace common\logic\User\CreditHistory\Service;
namespace common\logic\Payment\Service;


use common\helpers\MeanPayment; use common\helpers\MeanPayment;
use common\logic\AbstractService; use common\logic\AbstractService;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Service\OrderSolver; use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Payment\Model\Payment;
use common\logic\Producer\Producer\Repository\ProducerRepository; use common\logic\Producer\Producer\Repository\ProducerRepository;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use common\logic\User\User\Repository\UserRepository; use common\logic\User\User\Repository\UserRepository;
use common\logic\UtilsInterface; use common\logic\UtilsInterface;
use yii\base\ErrorException; use yii\base\ErrorException;


class CreditUtils extends AbstractService implements UtilsInterface
class PaymentUtils extends AbstractService implements UtilsInterface
{ {
protected CreditHistoryBuilder $creditHistoryBuilder;
protected PaymentBuilder $paymentBuilder;
protected OrderSolver $orderSolver; protected OrderSolver $orderSolver;
protected ProducerRepository $producerRepository; protected ProducerRepository $producerRepository;
protected UserRepository $userRepository; protected UserRepository $userRepository;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->creditHistoryBuilder = $this->loadService(CreditHistoryBuilder::class);
$this->paymentBuilder = $this->loadService(PaymentBuilder::class);
$this->orderSolver = $this->loadService(OrderSolver::class); $this->orderSolver = $this->loadService(OrderSolver::class);
$this->producerRepository = $this->loadService(ProducerRepository::class); $this->producerRepository = $this->loadService(ProducerRepository::class);
$this->userRepository = $this->loadService(UserRepository::class); $this->userRepository = $this->loadService(UserRepository::class);


public function creditUser(User $user, float $amount, string $meanPayment, User $userAction): void public function creditUser(User $user, float $amount, string $meanPayment, User $userAction): void
{ {
$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_CREDIT,
$this->paymentBuilder->createPayment(
Payment::TYPE_CREDIT,
$amount, $amount,
$this->getProducerContext(), $this->getProducerContext(),
$user, $user,


public function debitUser(User $user, float $amount, string $meanPayment, User $userAction): void public function debitUser(User $user, float $amount, string $meanPayment, User $userAction): void
{ {
$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_DEBIT,
$this->paymentBuilder->createPayment(
Payment::TYPE_DEBIT,
$amount, $amount,
$this->getProducerContext(), $this->getProducerContext(),
$user, $user,


public function creditOrDebitUser(string $type, User $user, float $amount, string $meanPayment, User $userAction): void public function creditOrDebitUser(string $type, User $user, float $amount, string $meanPayment, User $userAction): void
{ {
if($type == CreditHistory::TYPE_CREDIT) {
if($type == Payment::TYPE_CREDIT) {
$this->creditUser($user, $amount, $meanPayment, $userAction); $this->creditUser($user, $amount, $meanPayment, $userAction);
} }
elseif($type == CreditHistory::TYPE_DEBIT) {
elseif($type == Payment::TYPE_DEBIT) {
$this->debitUser($user, $amount, $meanPayment, $userAction); $this->debitUser($user, $amount, $meanPayment, $userAction);
} }
else { else {
} }
} }


public function payOrder(Order $order, User $userAction, bool $checkCreditLimit): void
public function payOrder(Order $order, string $meanPayment, User $userAction, bool $checkCreditLimit)
{
if($meanPayment == MeanPayment::CREDIT) {
$this->payOrderByCredit($order, $userAction, $checkCreditLimit);
}
elseif(key_exists($meanPayment, MeanPayment::getAll())) {
$this->paymentBuilder->createPayment(
Payment::TYPE_PAYMENT,
$this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_REMAINING),
$this->getProducerContext(),
$order->user,
$userAction,
$meanPayment,
$order
);
}
else {
throw new ErrorException('Moyen de paiement inconnu : '.$meanPayment);
}
}

public function payOrderByCredit(Order $order, User $userAction, bool $checkCreditLimit): void
{ {
$amountRemaining = round($this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_REMAINING), 2); $amountRemaining = round($this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_REMAINING), 2);


} }


if($amountRemaining > 0) { if($amountRemaining > 0) {
$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_PAYMENT,
$this->paymentBuilder->createPayment(
Payment::TYPE_PAYMENT,
$amountRemaining, $amountRemaining,
$this->getProducerContext(), $this->getProducerContext(),
$order->user, $order->user,
} }
} }


public function refundOrder(Order $order, User $userAction): void
public function refundOrder(Order $order, string $meanPayment, User $userAction): void
{ {
$amountPaid = round($this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID), 2); $amountPaid = round($this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID), 2);


if ($amountPaid >= 0.01 && $order->id_user) { if ($amountPaid >= 0.01 && $order->id_user) {
$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_REFUND,
$this->paymentBuilder->createPayment(
Payment::TYPE_REFUND,
$this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID), $this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID),
$this->getProducerContext(), $this->getProducerContext(),
$order->user, $order->user,
$userAction, $userAction,
$meanPayment,
$order
);
}
}

public function refundOrderCredit(Order $order, User $userAction): void
{
$amountPaidByCredit = $this->orderSolver->getOrderAmountPaidByCredit($order);
if($amountPaidByCredit >= 0.01 && $order->id_user) {
$this->paymentBuilder->createPayment(
Payment::TYPE_REFUND,
$amountPaidByCredit,
$this->getProducerContext(),
$order->user,
$userAction,
MeanPayment::CREDIT, MeanPayment::CREDIT,
$order $order
); );


public function refundSurplusOrder(Order $order, User $userAction): void public function refundSurplusOrder(Order $order, User $userAction): void
{ {
$this->creditHistoryBuilder->createCreditHistory(
CreditHistory::TYPE_REFUND,
$this->paymentBuilder->createPayment(
Payment::TYPE_REFUND,
$this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_SURPLUS), $this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_SURPLUS),
$this->getProducerContext(), $this->getProducerContext(),
$order->user, $order->user,
); );
} }


public function payOrRefundOrder(string $type, Order $order, User $userAction, bool $checkCreditLimit = false): void
public function payOrRefundOrder(string $type, Order $order, string $meanPayment, User $userAction, bool $checkCreditLimit = false): void
{ {
if($type == CreditHistory::TYPE_PAYMENT) {
$this->payOrder($order, $userAction, $checkCreditLimit);
if($type == Payment::TYPE_PAYMENT) {
$this->payOrder($order, $meanPayment, $userAction, $checkCreditLimit);
} }
elseif($type == CreditHistory::TYPE_REFUND) {
$this->refundOrder($order, $userAction);
elseif($type == Payment::TYPE_REFUND) {
$this->refundOrder($order, $meanPayment, $userAction);
} }
else { else {
throw new ErrorException('$type a une valeur incorrect'); throw new ErrorException('$type a une valeur incorrect');

+ 49
- 0
common/logic/Payment/Wrapper/PaymentContainer.php View File

<?php

namespace common\logic\Payment\Wrapper;

use common\logic\AbstractContainer;
use common\logic\Payment\Repository\PaymentRepository;
use common\logic\Payment\Service\PaymentUtils;
use common\logic\Payment\Service\PaymentBuilder;
use common\logic\Payment\Service\PaymentDefinition;
use common\logic\Payment\Service\PaymentSolver;

class PaymentContainer extends AbstractContainer
{
public function getServices(): array
{
return [
PaymentDefinition::class,
PaymentSolver::class,
PaymentBuilder::class,
PaymentRepository::class,
PaymentUtils::class,
];
}

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

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

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

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

public function getPaymentUtils(): PaymentUtils
{
return PaymentUtils::getInstance();
}
}

+ 25
- 0
common/logic/Payment/Wrapper/PaymentManager.php View File

<?php

namespace common\logic\Payment\Wrapper;

use common\logic\AbstractManager;
use common\logic\Payment\Repository\PaymentRepository;
use common\logic\Payment\Service\PaymentUtils;
use common\logic\Payment\Service\PaymentBuilder;
use common\logic\Payment\Service\PaymentDefinition;
use common\logic\Payment\Service\PaymentSolver;

/**
* @mixin PaymentDefinition
* @mixin PaymentSolver
* @mixin PaymentRepository
* @mixin PaymentBuilder
* @mixin PaymentUtils
*/
class PaymentManager extends AbstractManager
{
public function getContainerFqcn(): string
{
return PaymentContainer::class;
}
}

+ 4
- 2
common/logic/Producer/Producer/Repository/ProducerRepository.php View File

{ {
if (strlen($config)) { if (strlen($config)) {
if (!$idProducer) { if (!$idProducer) {
$idProducer = $this->getProducerContextId();
$producer = $this->getProducerContext();
}
else {
$producer = $this->findOneProducerById($idProducer);
} }


$producer = $this->findOneProducerById($idProducer);
if ($producer) { if ($producer) {
return $producer->$config; return $producer->$config;
} }

+ 1
- 1
common/logic/Producer/Producer/Service/ProducerBuilder.php View File

$versionsArray = Opendistrib::getVersions(); $versionsArray = Opendistrib::getVersions();
$producer->latest_version_opendistrib = reset($versionsArray); $producer->latest_version_opendistrib = reset($versionsArray);


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


public function savePrivateKeyStripe($filename, $value) public function savePrivateKeyStripe($filename, $value)

+ 9
- 3
common/logic/Product/Product/Model/Product.php View File

public function afterFind() public function afterFind()
{ {
if ($this->taxRate == null) { if ($this->taxRate == null) {
$producer = Producer::searchOne(['id' => $this->id_producer]);
if($this->id_producer == GlobalParam::getCurrentProducerId()) {
$producer = GlobalParam::getCurrentProducer();
}
else {
$producer = Producer::searchOne(['id' => $this->id_producer]);
}

if ($producer) { if ($producer) {
$this->populateRelation('taxRate', $producer->taxRate); $this->populateRelation('taxRate', $producer->taxRate);
} }
} }


parent::afterFind();

$productSolver = ProductSolver::getInstance(); $productSolver = ProductSolver::getInstance();
$this->wording_unit = $productSolver->strUnit($this->unit); $this->wording_unit = $productSolver->strUnit($this->unit);
$this->price_with_tax = $productSolver->getPriceWithTax($this); $this->price_with_tax = $productSolver->getPriceWithTax($this);

parent::afterFind();
} }


public function getProductDistribution() public function getProductDistribution()

+ 1
- 1
common/logic/Product/Product/Repository/ProductRepository.php View File

{ {
return [ return [
self::WITH => ['taxRate', 'productPointSale'], self::WITH => ['taxRate', 'productPointSale'],
self::JOIN_WITH => [],
self::JOIN_WITH => ['productPrice'],
self::ORDER_BY => 'product.order ASC', self::ORDER_BY => 'product.order ASC',
self::ATTRIBUTE_ID_PRODUCER => 'product.id_producer' self::ATTRIBUTE_ID_PRODUCER => 'product.id_producer'
]; ];

+ 0
- 34
common/logic/User/CreditHistory/Repository/CreditHistoryRepository.php View File

<?php

namespace common\logic\User\CreditHistory\Repository;

use common\logic\AbstractRepository;
use common\logic\Order\Order\Model\Order;
use common\logic\User\CreditHistory\Model\CreditHistory;

class CreditHistoryRepository extends AbstractRepository
{
protected CreditHistoryRepositoryQuery $query;

public function loadDependencies(): void
{
$this->loadQuery(CreditHistoryRepositoryQuery::class);
}

public function getDefaultOptionsSearch(): array
{
return [
self::WITH => [],
self::JOIN_WITH => [],
self::ORDER_BY => CreditHistory::tableName() . '.date ASc',
self::ATTRIBUTE_ID_PRODUCER => CreditHistory::tableName() . '.id_producer'
];
}

public function getByOrder(Order $order)
{
return $this->createDefaultQuery()
->filterByOrder($order)
->find();
}
}

+ 0
- 23
common/logic/User/CreditHistory/Repository/CreditHistoryRepositoryQuery.php View File

<?php

namespace common\logic\User\CreditHistory\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Order\Order\Model\Order;
use common\logic\User\CreditHistory\Service\CreditHistoryDefinition;

class CreditHistoryRepositoryQuery extends AbstractRepositoryQuery
{
protected CreditHistoryDefinition $definition;

public function loadDependencies(): void
{
$this->loadDefinition(CreditHistoryDefinition::class);
}

public function filterByOrder(Order $order): self
{
$this->andWhere(['id_order' => $order->id]);
return $this;
}
}

+ 0
- 74
common/logic/User/CreditHistory/Service/CreditHistoryBuilder.php View File

<?php

namespace common\logic\User\CreditHistory\Service;

use common\logic\AbstractBuilder;
use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Producer\Producer\Model\Producer;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\User\Model\User;
use yii\base\Event;

class CreditHistoryBuilder extends AbstractBuilder
{
protected CreditHistorySolver $creditHistorySolver;
protected OrderSolver $orderSolver;

public function loadDependencies(): void
{
$this->creditHistorySolver = $this->loadService(CreditHistorySolver::class);
$this->orderSolver = $this->loadService(OrderSolver::class);
}

public function instanciateCreditHistory(
string $type,
float $amount,
Producer $producer,
User $user,
User $userAction,
string $meanPayment = null,
Order $order = null
): CreditHistory
{
$creditHistory = new CreditHistory;

$creditHistory->type = $type;
$creditHistory->amount = round($amount, 2);
$creditHistory->populateProducer($producer);
$creditHistory->populateUser($user);
$creditHistory->populateUserAction($userAction);

if($order) {
$creditHistory->populateOrder($order);
}

if($meanPayment) {
$creditHistory->mean_payment = $meanPayment;
}

return $creditHistory;
}

// saveCreditHistory
public function createCreditHistory(
string $type,
float $amount,
Producer $producer,
User $user,
User $userAction,
string $meanPayment = null,
Order $order = null
): ?CreditHistory
{
if ($amount > -0.01 && $amount < 0.01) {
return null;
}

$creditHistory = $this->instanciateCreditHistory($type, $amount, $producer, $user, $userAction, $meanPayment, $order);
$creditHistory->setComment($creditHistory->getComment() . $this->orderSolver->getCreditHistoryComment($creditHistory));
$this->create($creditHistory);

return $creditHistory;
}
}

+ 0
- 14
common/logic/User/CreditHistory/Service/CreditHistoryDefinition.php View File

<?php

namespace common\logic\User\CreditHistory\Service;

use common\logic\AbstractDefinition;
use common\logic\User\CreditHistory\Model\CreditHistory;

class CreditHistoryDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return CreditHistory::class;
}
}

+ 0
- 100
common/logic/User/CreditHistory/Service/CreditHistorySolver.php View File

<?php

namespace common\logic\User\CreditHistory\Service;

use common\helpers\MeanPayment;
use common\logic\AbstractService;
use common\logic\SolverInterface;
use common\logic\User\CreditHistory\Model\CreditHistory;
use yii\helpers\Html;

class CreditHistorySolver extends AbstractService implements SolverInterface
{
public function isTypeDebit(CreditHistory $creditHistory): bool
{
return in_array($creditHistory->getType(), [
CreditHistory::TYPE_DEBIT,
CreditHistory::TYPE_PAYMENT,
]);
}

public function isTypeCredit(CreditHistory $creditHistory): bool
{
return in_array($creditHistory->getType(), [
CreditHistory::TYPE_CREDIT,
CreditHistory::TYPE_INITIAL_CREDIT,
CreditHistory::TYPE_REFUND
]);
}

public function getAmount(CreditHistory $creditHistory, bool $format = false): string
{
if ($format) {
return number_format($creditHistory->getAmount(), 2) . '&nbsp;€';
} else {
return $creditHistory->getAmount();
}
}

/**
* Retourne le libellé du CreditHistory informant de son type et
* éventuellement de la date de sa commande associée.
*
*/
public function getStrWording(CreditHistory $creditHistory): string
{
$str = '';
$type = $creditHistory->getType();

if (CreditHistory::TYPE_INITIAL_CREDIT == $type) {
$str = 'Crédit initial';
} elseif (CreditHistory::TYPE_CREDIT == $type) {
$str = 'Crédit';
} elseif (CreditHistory::TYPE_PAYMENT == $type) {
$str = 'Débit';
} elseif (CreditHistory::TYPE_REFUND == $type) {
$str = 'Recrédit';
} elseif (CreditHistory::TYPE_DEBIT == $type) {
$str = 'Débit';
}

if (CreditHistory::TYPE_PAYMENT == $type || CreditHistory::TYPE_REFUND == $type) {
$order = $creditHistory->getOrderObject();
if ($order && $order->distribution) {
$str .= '<br />Commande : ' . date('d/m/Y', strtotime($order->distribution->date));
} else {
$str .= '<br />Commande supprimée';
}
}

return $str;
}

public function getDate(CreditHistory $creditHistory, bool $format = false): string
{
$date = $creditHistory->getDate();

if ($format) {
return date('d/m/Y à H:i:s', strtotime($date));
} else {
return $date;
}
}

public function getStrMeanPayment(CreditHistory $creditHistory): string
{
return MeanPayment::getStrBy($creditHistory->getMeanPayment());
}

// strUserAction
public function getStrUserAction(CreditHistory $creditHistory): string
{
$userAction = $creditHistory->getUserActionObject();

if ($userAction) {
return $userAction->getName() . ' ' . $userAction->getlastname();
} else {
return 'Système';
}
}
}

+ 0
- 49
common/logic/User/CreditHistory/Wrapper/CreditHistoryContainer.php View File

<?php

namespace common\logic\User\CreditHistory\Wrapper;

use common\logic\AbstractContainer;
use common\logic\User\CreditHistory\Repository\CreditHistoryRepository;
use common\logic\User\CreditHistory\Service\CreditHistoryBuilder;
use common\logic\User\CreditHistory\Service\CreditHistoryDefinition;
use common\logic\User\CreditHistory\Service\CreditHistorySolver;
use common\logic\User\CreditHistory\Service\CreditUtils;

class CreditHistoryContainer extends AbstractContainer
{
public function getServices(): array
{
return [
CreditHistoryDefinition::class,
CreditHistorySolver::class,
CreditHistoryBuilder::class,
CreditHistoryRepository::class,
CreditUtils::class,
];
}

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

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

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

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

public function getCreditUtils(): CreditUtils
{
return CreditUtils::getInstance();
}
}

+ 0
- 25
common/logic/User/CreditHistory/Wrapper/CreditHistoryManager.php View File

<?php

namespace common\logic\User\CreditHistory\Wrapper;

use common\logic\AbstractManager;
use common\logic\User\CreditHistory\Repository\CreditHistoryRepository;
use common\logic\User\CreditHistory\Service\CreditHistoryBuilder;
use common\logic\User\CreditHistory\Service\CreditHistoryDefinition;
use common\logic\User\CreditHistory\Service\CreditHistorySolver;
use common\logic\User\CreditHistory\Service\CreditUtils;

/**
* @mixin CreditHistoryDefinition
* @mixin CreditHistorySolver
* @mixin CreditHistoryRepository
* @mixin CreditHistoryBuilder
* @mixin CreditUtils
*/
class CreditHistoryManager extends AbstractManager
{
public function getContainerFqcn(): string
{
return CreditHistoryContainer::class;
}
}

+ 13
- 1
common/logic/User/User/Repository/UserRepository.php View File

*/ */
public function getCredit(User $user): float public function getCredit(User $user): float
{ {
$userProducer = $this->userProducerRepository->findOneUserProducer($user);
// @TODO : optimisation à refactorer
$userProducer = null;
$producerId = $this->getProducerContextId();
foreach($user->userProducer as $userProducerRelation) {
if($userProducerRelation->id_producer == $producerId) {
$userProducer = $userProducerRelation;
}
}

if(!$userProducer) {
$userProducer = $this->userProducerRepository->findOneUserProducer($user);
}

return $userProducer ? $userProducer->credit : 0; return $userProducer ? $userProducer->credit : 0;
} }



common/logic/User/UserProducer/Event/CreditHistoryObserver.php → common/logic/User/UserProducer/Event/PaymentObserver.php View File

use justcoded\yii2\eventlistener\observers\ActiveRecordObserver; use justcoded\yii2\eventlistener\observers\ActiveRecordObserver;
use yii\db\AfterSaveEvent; use yii\db\AfterSaveEvent;


class CreditHistoryObserver extends ActiveRecordObserver
class PaymentObserver extends ActiveRecordObserver
{ {
public function inserted(AfterSaveEvent $event) public function inserted(AfterSaveEvent $event)
{ {
$creditHistory = $event->sender;
$payment = $event->sender;
$userProducerManager = UserProducerManager::getInstance(); $userProducerManager = UserProducerManager::getInstance();


$userProducerManager->updateCredit($creditHistory);
$userProducerManager->updateCredit($payment);
} }
} }

+ 27
- 24
common/logic/User/UserProducer/Service/UserProducerBuilder.php View File

use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Repository\OrderRepository; use common\logic\Order\Order\Repository\OrderRepository;
use common\logic\Order\Order\Service\OrderSolver; use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Payment\Model\Payment;
use common\logic\Payment\Service\PaymentSolver;
use common\logic\Producer\Producer\Model\Producer; use common\logic\Producer\Producer\Model\Producer;
use common\logic\Producer\Producer\Repository\ProducerRepository; use common\logic\Producer\Producer\Repository\ProducerRepository;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\CreditHistory\Service\CreditHistorySolver;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use common\logic\User\User\Repository\UserRepository;
use common\logic\User\UserProducer\Model\UserProducer; use common\logic\User\UserProducer\Model\UserProducer;
use common\logic\User\UserProducer\Repository\UserProducerRepository; use common\logic\User\UserProducer\Repository\UserProducerRepository;


class UserProducerBuilder extends AbstractBuilder class UserProducerBuilder extends AbstractBuilder
{ {
protected CreditHistorySolver $creditHistorySolver;
protected PaymentSolver $paymentSolver;
protected UserProducerRepository $userProducerRepository; protected UserProducerRepository $userProducerRepository;
protected OrderRepository $orderRepository; protected OrderRepository $orderRepository;
protected ProducerRepository $producerRepository; protected ProducerRepository $producerRepository;
protected OrderSolver $orderSolver; protected OrderSolver $orderSolver;
protected UserRepository $userRepository;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->creditHistorySolver = $this->loadService(CreditHistorySolver::class);
$this->paymentSolver = $this->loadService(PaymentSolver::class);
$this->userProducerRepository = $this->loadService(UserProducerRepository::class); $this->userProducerRepository = $this->loadService(UserProducerRepository::class);
$this->orderRepository = $this->loadService(OrderRepository::class); $this->orderRepository = $this->loadService(OrderRepository::class);
$this->producerRepository = $this->loadService(ProducerRepository::class); $this->producerRepository = $this->loadService(ProducerRepository::class);
$this->orderSolver = $this->loadService(OrderSolver::class); $this->orderSolver = $this->loadService(OrderSolver::class);
$this->userRepository = $this->loadService(UserRepository::class);
} }


public function instanciateUserProducer(User $user, Producer $producer, bool $bookmark = true, bool $newsletter = true) public function instanciateUserProducer(User $user, Producer $producer, bool $bookmark = true, bool $newsletter = true)
?? $this->createUserProducer($user, $producer, $bookmark, $newsletter); ?? $this->createUserProducer($user, $producer, $bookmark, $newsletter);
} }


public function updateCredit(CreditHistory $creditHistory): void
public function updateCredit(Payment $payment): void
{ {
$userProducer = $this->userProducerRepository->findOneUserProducer($creditHistory->user);
if($this->paymentSolver->isMeanPaymentCredit($payment) && $payment->user) {
$userProducer = $this->userProducerRepository->findOneUserProducer($payment->user);


if ($userProducer) {
$oldCredit = $userProducer->getCredit();
if ($userProducer) {
$oldCredit = $userProducer->getCredit();


$this->deductCredit($userProducer, $creditHistory);
$this->initMeanPaymentOrder($creditHistory);
$this->sendCreditLimitReminder($userProducer, $creditHistory, $oldCredit);
$this->deductCredit($userProducer, $payment);
//$this->initMeanPaymentOrder($payment);
$this->sendCreditLimitReminder($userProducer, $payment, $oldCredit);
}
} }
} }


public function deductCredit(UserProducer $userProducer, CreditHistory $creditHistory)
public function deductCredit(UserProducer $userProducer, Payment $payment)
{ {
if ($this->creditHistorySolver->isTypeCredit($creditHistory)) {
$userProducer->setCredit($userProducer->getCredit() + $creditHistory->getAmount());
} elseif ($this->creditHistorySolver->isTypeDebit($creditHistory)) {
$userProducer->setCredit($userProducer->getCredit() - $creditHistory->getAmount());
if ($this->paymentSolver->isTypeCredit($payment)) {
$userProducer->setCredit($userProducer->getCredit() + $payment->getAmount());
} elseif ($this->paymentSolver->isTypeDebit($payment)) {
$userProducer->setCredit($userProducer->getCredit() - $payment->getAmount());
} }


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


public function initMeanPaymentOrder($creditHistory)
public function initMeanPaymentOrder(Payment $payment)
{ {
if ($creditHistory->id_order && $creditHistory->id_order > 0) {
$order = $this->orderRepository->findOneOrderById((int) $creditHistory->id_order);
if ($payment->id_order && $payment->id_order > 0) {
$order = $this->orderRepository->findOneOrderById((int) $payment->id_order);


if ($order) { if ($order) {
$paymentStatus = $this->orderSolver->getPaymentStatus($order); $paymentStatus = $this->orderSolver->getPaymentStatus($order);
} }
} }


public function sendCreditLimitReminder($userProducer, $creditHistory, $oldCredit)
public function sendCreditLimitReminder($userProducer, $payment, $oldCredit)
{ {
$userRepository = \Yii::$app->logic->getUserContainer()->getRepository();
$producerRepository = \Yii::$app->logic->getProducerContainer()->getRepository();
$newCredit = $userProducer->credit; $newCredit = $userProducer->credit;


if ($this->isCreditLimitCrossed($oldCredit, $newCredit)) { if ($this->isCreditLimitCrossed($oldCredit, $newCredit)) {


$user = $userRepository->findOneUserById($creditHistory->id_user);
$producer = $producerRepository->findOneProducerById($creditHistory->id_producer);
$user = $this->userRepository->findOneUserById($payment->id_user);
$producer = $this->producerRepository->findOneProducerById($payment->id_producer);


if($user && $user->email && strlen($user->email) > 0) { if($user && $user->email && strlen($user->email) > 0) {
\Yii::$app->mailer->compose( \Yii::$app->mailer->compose(

+ 2
- 2
common/mail/creditUser-html.php View File

termes. termes.
*/ */


use common\logic\Payment\Model\Payment;
use yii\helpers\Html; use yii\helpers\Html;
use common\helpers\Price; use common\helpers\Price;
use common\logic\User\CreditHistory\Model\CreditHistory;


?> ?>


<p>Bonjour <?= Html::encode($user->name); ?>,</p> <p>Bonjour <?= Html::encode($user->name); ?>,</p>


<p>Votre producteur <strong><?= Html::encode($producer->name); ?></strong> vient <p>Votre producteur <strong><?= Html::encode($producer->name); ?></strong> vient
de <?php if($creditForm->type == CreditHistory::TYPE_CREDIT): ?>créditer<?php else: ?>débiter<?php endif; ?> votre compte de <strong><?= Price::format($creditForm->amount); ?></strong> sur le site <a href="http://www.opendistrib.net/">Opendistrib</a>.</p>
de <?php if($creditForm->type == Payment::TYPE_CREDIT): ?>créditer<?php else: ?>débiter<?php endif; ?> votre compte de <strong><?= Price::format($creditForm->amount); ?></strong> sur le site <a href="http://www.opendistrib.net/">Opendistrib</a>.</p>


<p>Votre compte est désormais à <strong><?= Price::format($userProducer->credit); ?></strong><br /> <p>Votre compte est désormais à <strong><?= Price::format($userProducer->credit); ?></strong><br />
<a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['credit/history','slug_producer' => $producer->slug]) ?>">Cliquez ici</a> pour voir l'historique de votre crédit.</p> <a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['credit/history','slug_producer' => $producer->slug]) ?>">Cliquez ici</a> pour voir l'historique de votre crédit.</p>

+ 2
- 2
common/mail/creditUser-text.php View File

*/ */


use common\helpers\Price ; use common\helpers\Price ;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\Payment\Model\Payment;


?> ?>


Bonjour <?= $user->name; ?>,</p> Bonjour <?= $user->name; ?>,</p>


Votre producteur <?= $producer->name; ?> vient de <?php if($creditForm->type == CreditHistory::TYPE_CREDIT): ?>créditer<?php else: ?>débiter<?php endif; ?> votre compte de <?= Price::format($creditForm->amount); ?> sur le site http://www.opendistrib.net/
Votre producteur <?= $producer->name; ?> vient de <?php if($creditForm->type == Payment::TYPE_CREDIT): ?>créditer<?php else: ?>débiter<?php endif; ?> votre compte de <?= Price::format($creditForm->amount); ?> sur le site http://www.opendistrib.net/


Votre compte est désormais à : <?= Price::format($userProducer->credit); ?>. Votre compte est désormais à : <?= Price::format($userProducer->credit); ?>.
Suivez ce lien pour voir l'historique de votre crédit : <?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['credit/history','slug_producer' => $producer->slug]) ?>"> Suivez ce lien pour voir l'historique de votre crédit : <?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['credit/history','slug_producer' => $producer->slug]) ?>">

+ 1
- 1
composer.json View File

}, },
"require-dev": { "require-dev": {
"yiisoft/yii2-codeception": "*", "yiisoft/yii2-codeception": "*",
"yiisoft/yii2-debug": "*",
"yiisoft/yii2-debug": "^2.1",
"yiisoft/yii2-gii": "*", "yiisoft/yii2-gii": "*",
"yiisoft/yii2-faker": "*", "yiisoft/yii2-faker": "*",
"codeception/codeception": "^2.3", "codeception/codeception": "^2.3",

+ 6
- 6
composer.lock View File

"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "1d287231533b2d1fef1047dd81b0e4d5",
"content-hash": "a8cbf9ba6bfa2f0b47fba2344732ac95",
"packages": [ "packages": [
{ {
"name": "2amigos/yii2-chartjs-widget", "name": "2amigos/yii2-chartjs-widget",
}, },
{ {
"name": "yiisoft/yii2-debug", "name": "yiisoft/yii2-debug",
"version": "2.1.22",
"version": "2.1.24",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/yiisoft/yii2-debug.git", "url": "https://github.com/yiisoft/yii2-debug.git",
"reference": "c0fa388c56b64edfb92987fdcc37d7a0243170d7"
"reference": "e15e954d0beb82b0b532f998f55e7275083de592"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/c0fa388c56b64edfb92987fdcc37d7a0243170d7",
"reference": "c0fa388c56b64edfb92987fdcc37d7a0243170d7",
"url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/e15e954d0beb82b0b532f998f55e7275083de592",
"reference": "e15e954d0beb82b0b532f998f55e7275083de592",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-11-18T17:29:27+00:00"
"time": "2023-07-10T06:07:43+00:00"
}, },
{ {
"name": "yiisoft/yii2-faker", "name": "yiisoft/yii2-faker",

+ 28
- 0
console/migrations/m230913_071815_alter_table_credit_history_rename_payment.php View File

<?php

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

/**
* Class m230913_071815_alter_table_credit_history_rename_payment
*/
class m230913_071815_alter_table_credit_history_rename_payment extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->renameTable('credit_history', 'payment');
$this->addColumn('payment', 'id_invoice', Schema::TYPE_INTEGER);
$this->alterColumn('payment', 'id_user', Schema::TYPE_INTEGER.' DEFAULT NULL');
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->renameTable('payment', 'credit_history');
}
}

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

<?php

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

/**
* Class m230920_081923_add_column_payment_date_transaction
*/
class m230920_081923_add_column_payment_date_transaction extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('payment', 'date_transaction', Schema::TYPE_DATE);
}

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

+ 7
- 8
producer/controllers/CreditController.php View File

namespace producer\controllers; namespace producer\controllers;


use common\helpers\GlobalParam; use common\helpers\GlobalParam;
use common\helpers\Mailjet;
use common\helpers\MeanPayment; use common\helpers\MeanPayment;
use common\logic\User\CreditHistory\Model\CreditHistory;
use common\logic\User\CreditHistory\Model\CreditHistorySearch;
use common\logic\Payment\Model\Payment;
use common\logic\Payment\Model\CreditHistorySearch;
use producer\models\CreditForm; use producer\models\CreditForm;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;


public function actionStripeVerification() public function actionStripeVerification()
{ {
$orderManager = $this->getOrderManager(); $orderManager = $this->getOrderManager();
$creditHistoryManager = $this->getCreditHistoryManager();
$paymentManager = $this->getPaymentManager();
$producerManager = $this->getProducerManager(); $producerManager = $this->getProducerManager();
$userManager = $this->getUserManager(); $userManager = $this->getUserManager();
$producer = $this->getProducerCurrent(); $producer = $this->getProducerCurrent();
switch ($event->type) { switch ($event->type) {
case 'charge.succeeded': case 'charge.succeeded':


$creditHistoryExist = CreditHistory::searchOne([
$paymentExist = Payment::searchOne([
'id_user' => $idUser, 'id_user' => $idUser,
'amount' => $amount, 'amount' => $amount,
], [ ], [
] ]
]); ]);


if (!$creditHistoryExist) {
if (!$paymentExist) {


$creditHistoryManager->creditUser($user, $amount, MeanPayment::CREDIT_CARD, $user);
$paymentManager->creditUser($user, $amount, MeanPayment::CREDIT_CARD, $user);


if (isset($order) && $order) { if (isset($order) && $order) {


$creditHistoryManager->payOrder($order, $user, true);
$paymentManager->payOrder($order, $user, true);




// client : envoi d'un email de confirmation de paiement // client : envoi d'un email de confirmation de paiement

+ 3
- 3
producer/controllers/OrderController.php View File

$producerManager = $this->getProducerManager(); $producerManager = $this->getProducerManager();
$productOrderManager = $this->getProductOrderManager(); $productOrderManager = $this->getProductOrderManager();
$userManager = $this->getUserManager(); $userManager = $this->getUserManager();
$creditHistoryManager = $this->getCreditHistoryManager();
$paymentManager = $this->getPaymentManager();


$posts = \Yii::$app->request->post(); $posts = \Yii::$app->request->post();
$productsArray = []; $productsArray = [];
)) { )) {
// à payer // à payer
if ($orderManager->getPaymentStatus($order) == Order::PAYMENT_UNPAID) { if ($orderManager->getPaymentStatus($order) == Order::PAYMENT_UNPAID) {
$creditHistoryManager->payOrder($order, $this->getUserCurrent(), true);
$paymentManager->payOrder($order, $this->getUserCurrent(), true);
} // surplus à rembourser } // surplus à rembourser
elseif ($orderManager->getPaymentStatus($order) == Order::PAYMENT_SURPLUS) { elseif ($orderManager->getPaymentStatus($order) == Order::PAYMENT_SURPLUS) {
$creditHistoryManager->refundSurplusOrder($order, $this->getUserCurrent());
$paymentManager->refundSurplusOrder($order, $this->getUserCurrent());
} }
} }



+ 16
- 16
producer/views/credit/history.php View File

* termes. * termes.
*/ */


use common\logic\User\CreditHistory\Wrapper\CreditHistoryManager;
use common\logic\Payment\Wrapper\PaymentManager;
use yii\grid\GridView; use yii\grid\GridView;


$creditHistoryManager = CreditHistoryManager::getInstance();
$paymentManager = PaymentManager::getInstance();
$producer = $this->context->getProducerCurrent(); $producer = $this->context->getProducerCurrent();
$this->setTitle('Crédit : <span id="credit-user">' . number_format($creditUser, 2) . ' €</span>'); $this->setTitle('Crédit : <span id="credit-user">' . number_format($creditUser, 2) . ' €</span>');
$this->setPageTitle('Crédit'); $this->setPageTitle('Crédit');
'columns' => [ 'columns' => [
[ [
'attribute' => 'date', 'attribute' => 'date',
'value' => function ($model) use ($creditHistoryManager) {
return $creditHistoryManager->getDate($model, true);
'value' => function ($model) use ($paymentManager) {
return $paymentManager->getDate($model, true);
} }
], ],
[ [
'attribute' => 'id_user_action', 'attribute' => 'id_user_action',
'value' => function ($model) use ($creditHistoryManager) {
return $creditHistoryManager->getStrUserAction($model);
'value' => function ($model) use ($paymentManager) {
return $paymentManager->getStrUserAction($model);
} }
], ],
[ [
'label' => 'Type', 'label' => 'Type',
'format' => 'raw', 'format' => 'raw',
'value' => function ($model) use ($creditHistoryManager) {
return $creditHistoryManager->getStrWording($model);
'value' => function ($model) use ($paymentManager) {
return $paymentManager->getStrWording($model);
} }
], ],
[ [
'attribute' => 'mean_payment', 'attribute' => 'mean_payment',
'value' => function ($model) use ($creditHistoryManager) {
return $creditHistoryManager->getStrMeanPayment($model);
'value' => function ($model) use ($paymentManager) {
return $paymentManager->getStrMeanPayment($model);
} }
], ],
[ [
'label' => '- Débit', 'label' => '- Débit',
'format' => 'raw', 'format' => 'raw',
'value' => function ($model) use ($creditHistoryManager) {
if ($creditHistoryManager->isTypeDebit($model)) {
return '-&nbsp;' . $creditHistoryManager->getAmount($model, true);
'value' => function ($model) use ($paymentManager) {
if ($paymentManager->isTypeDebit($model)) {
return '-&nbsp;' . $paymentManager->getAmount($model, true);
} }
return ''; return '';
} }
[ [
'label' => '+ Crédit', 'label' => '+ Crédit',
'format' => 'raw', 'format' => 'raw',
'value' => function ($model) use ($creditHistoryManager) {
if ($creditHistoryManager->isTypeCredit($model)) {
return '+&nbsp;' . $creditHistoryManager->getAmount($model, true);
'value' => function ($model) use ($paymentManager) {
if ($paymentManager->isTypeCredit($model)) {
return '+&nbsp;' . $paymentManager->getAmount($model, true);
} }
return ''; return '';
} }

Loading…
Cancel
Save