You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
6.5KB

  1. <?php
  2. namespace common\logic\Payment\Service;
  3. use common\helpers\MeanPayment;
  4. use common\logic\AbstractService;
  5. use common\logic\Order\Order\Model\Order;
  6. use common\logic\Order\Order\Service\OrderSolver;
  7. use common\logic\Payment\Model\Payment;
  8. use common\logic\Producer\Producer\Service\ProducerSolver;
  9. use common\logic\User\User\Model\User;
  10. use common\logic\User\User\Repository\UserRepository;
  11. use common\logic\ManagerInterface;
  12. use yii\base\ErrorException;
  13. class PaymentManager extends AbstractService implements ManagerInterface
  14. {
  15. protected PaymentBuilder $paymentBuilder;
  16. protected OrderSolver $orderSolver;
  17. protected UserRepository $userRepository;
  18. protected ProducerSolver $producerSolver;
  19. public function loadDependencies(): void
  20. {
  21. $this->paymentBuilder = $this->loadService(PaymentBuilder::class);
  22. $this->orderSolver = $this->loadService(OrderSolver::class);
  23. $this->userRepository = $this->loadService(UserRepository::class);
  24. $this->producerSolver = $this->loadService(ProducerSolver::class);
  25. }
  26. public function creditUser(User $user, float $amount, string $meanPayment, User $userAction, string $comment = null): void
  27. {
  28. $this->paymentBuilder->createPayment(
  29. Payment::TYPE_CREDIT,
  30. $amount,
  31. $this->getProducerContext(),
  32. $user,
  33. $userAction,
  34. $meanPayment,
  35. $comment
  36. );
  37. }
  38. public function debitUser(User $user, float $amount, string $meanPayment, User $userAction, string $comment = null): void
  39. {
  40. $this->paymentBuilder->createPayment(
  41. Payment::TYPE_DEBIT,
  42. $amount,
  43. $this->getProducerContext(),
  44. $user,
  45. $userAction,
  46. $meanPayment,
  47. $comment
  48. );
  49. }
  50. public function creditOrDebitUser(string $type, User $user, float $amount, string $meanPayment, User $userAction, string $comment): void
  51. {
  52. if($type == Payment::TYPE_CREDIT) {
  53. $this->creditUser($user, $amount, $meanPayment, $userAction, $comment);
  54. }
  55. elseif($type == Payment::TYPE_DEBIT) {
  56. $this->debitUser($user, $amount, $meanPayment, $userAction, $comment);
  57. }
  58. else {
  59. throw new ErrorException('$type a une valeur incorrect');
  60. }
  61. }
  62. public function payOrder(Order $order, string $meanPayment, User $userAction, bool $checkCreditLimit)
  63. {
  64. if($meanPayment == MeanPayment::CREDIT) {
  65. $this->payOrderByCredit($order, $userAction, $checkCreditLimit);
  66. }
  67. elseif(key_exists($meanPayment, MeanPayment::getAll())) {
  68. $this->paymentBuilder->createPayment(
  69. Payment::TYPE_PAYMENT,
  70. $this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_REMAINING),
  71. $this->getProducerContext(),
  72. $order->user,
  73. $userAction,
  74. $meanPayment,
  75. null,
  76. $order
  77. );
  78. }
  79. else {
  80. throw new ErrorException('Moyen de paiement inconnu : '.$meanPayment);
  81. }
  82. }
  83. public function payOrderByCredit(Order $order, User $userAction, bool $checkCreditLimit): void
  84. {
  85. $amountRemaining = round($this->orderSolver->getOrderAmountWithTax($order, Order::AMOUNT_REMAINING), 2);
  86. if($checkCreditLimit) {
  87. $creditLimit = $this->producerSolver->getConfig('credit_limit');
  88. $creditUser = $this->userRepository->getCredit($order->user);
  89. if (!is_null($creditLimit) && $amountRemaining > $creditUser - $creditLimit) {
  90. $amountRemaining = $creditUser - $creditLimit;
  91. }
  92. }
  93. if($amountRemaining > 0) {
  94. $this->paymentBuilder->createPayment(
  95. Payment::TYPE_PAYMENT,
  96. $amountRemaining,
  97. $this->getProducerContext(),
  98. $order->user,
  99. $userAction,
  100. MeanPayment::CREDIT,
  101. null,
  102. $order
  103. );
  104. }
  105. }
  106. public function refundOrder(Order $order, string $meanPayment, User $userAction): void
  107. {
  108. $amountPaid = round($this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID), 2);
  109. if ($amountPaid >= 0.01 && $order->id_user) {
  110. $amount = $this->orderSolver->getOrderAmount($order, Order::AMOUNT_PAID);
  111. if($meanPayment == MeanPayment::CREDIT) {
  112. $amount = $this->orderSolver->getOrderAmountPaidByCredit($order);
  113. }
  114. $this->paymentBuilder->createPayment(
  115. Payment::TYPE_REFUND,
  116. $amount,
  117. $this->getProducerContext(),
  118. $order->user,
  119. $userAction,
  120. $meanPayment,
  121. null,
  122. $order
  123. );
  124. }
  125. }
  126. public function refundOrderCredit(Order $order, User $userAction): void
  127. {
  128. $amountPaidByCredit = $this->orderSolver->getOrderAmountPaidByCredit($order);
  129. if($amountPaidByCredit >= 0.01 && $order->id_user) {
  130. $this->paymentBuilder->createPayment(
  131. Payment::TYPE_REFUND,
  132. $amountPaidByCredit,
  133. $this->getProducerContext(),
  134. $order->user,
  135. $userAction,
  136. MeanPayment::CREDIT,
  137. null,
  138. $order
  139. );
  140. }
  141. }
  142. public function refundSurplusOrderCredit(Order $order, User $userAction): void
  143. {
  144. $amountPaidByCredit = $this->orderSolver->getOrderAmountPaidByCredit($order);
  145. $amount = $this->orderSolver->getOrderAmountWithTax($order);
  146. if($amountPaidByCredit > $amount) {
  147. $this->paymentBuilder->createPayment(
  148. Payment::TYPE_REFUND,
  149. $amountPaidByCredit - $amount,
  150. $this->getProducerContext(),
  151. $order->user,
  152. $userAction,
  153. MeanPayment::CREDIT,
  154. null,
  155. $order
  156. );
  157. }
  158. }
  159. public function payOrRefundOrder(string $type, Order $order, string $meanPayment, User $userAction, bool $checkCreditLimit = false): void
  160. {
  161. if($type == Payment::TYPE_PAYMENT) {
  162. $this->payOrder($order, $meanPayment, $userAction, $checkCreditLimit);
  163. }
  164. elseif($type == Payment::TYPE_REFUND) {
  165. $this->refundOrder($order, $meanPayment, $userAction);
  166. }
  167. else {
  168. throw new ErrorException('$type a une valeur incorrect');
  169. }
  170. }
  171. }