bundles/CheckoutBundle/Repository/TransactionRepository.php line 57

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * TransactionRepository.php File.
  5. * This file is part of the Payment.net Project.
  6. *
  7. * PHP version 5
  8. *
  9. * @category Application
  10. * @package Bdm\CheckoutBundle\Repository
  11. * @author Pavel Baraulya <pbaraulya@bdmultimedia.fr>
  12. * @link http://www.payment.net/
  13. *
  14. * FEATURES :
  15. * ==========
  16. *
  17. * TODO-LIST :
  18. * ===========
  19. *
  20. * HISTORY :
  21. * =========
  22. * 20150710 - Pavel Baraulya
  23. *
  24. **/
  25. namespace Bdm\CheckoutBundle\Repository;
  26. use Bdm\BackofficeBundle\Entity\Application;
  27. use Bdm\BackofficeBundle\Entity\Merchant;
  28. use Bdm\CheckoutBundle\Entity\AcquiredBatch;
  29. use Bdm\CheckoutBundle\Entity\Order;
  30. use Bdm\CheckoutBundle\Entity\RecurrentConfiguration;
  31. use Bdm\CheckoutBundle\Entity\Subscription;
  32. use Bdm\CheckoutBundle\Entity\Transaction;
  33. use Bdm\CheckoutBundle\Service\PaymentGateway;
  34. use Bdm\CheckoutBundle\Service\PaymentGatewayService;
  35. use Bdm\CoreBundle\Exception\InvalidFormException;
  36. use Doctrine\ORM\EntityManager;
  37. use Doctrine\ORM\Query\Expr\Join;
  38. use Doctrine\Persistence\ObjectRepository;
  39. /**
  40. * Class TransactionRepository
  41. */
  42. class TransactionRepository
  43. {
  44. protected ObjectRepository $oRepository;
  45. protected PaymentGatewayService $oPaymentGateway;
  46. /**
  47. * Constructor
  48. *
  49. * @param EntityManager $oEm object manager
  50. */
  51. public function __construct(protected EntityManager $oEm)
  52. {
  53. $this->oRepository = $oEm->getRepository(Transaction::class);
  54. }
  55. /**
  56. * Add new transaction
  57. *
  58. * @param Transaction $oTransaction transaction
  59. *
  60. * @throws InvalidFormException
  61. * @return void
  62. */
  63. public function add(Transaction $oTransaction)
  64. {
  65. $this->oEm->persist($oTransaction);
  66. $this->oEm->flush();
  67. }
  68. /**
  69. * Update transaction
  70. *
  71. * @param Transaction $oTransaction transaction
  72. *
  73. * @return Transaction
  74. */
  75. public function update(Transaction $oTransaction)
  76. {
  77. $this->oEm->persist($oTransaction);
  78. $this->oEm->flush();
  79. return $oTransaction;
  80. }
  81. /**
  82. * Makes card api call
  83. *
  84. * @throws \BadMethodCallException
  85. * @deprecated
  86. */
  87. public function process()
  88. {
  89. throw new \BadMethodCallException(
  90. 'Current method was deprecated. To process transactions use PaymentGatewayService'
  91. );
  92. }
  93. /**
  94. * Create list of transactions
  95. *
  96. * @param Subscription[] $oSubscriptions list of subscriptions
  97. *
  98. * @return Transaction[]
  99. */
  100. public function initTransactions($oSubscriptions)
  101. {
  102. $aTransactions = [];
  103. foreach ($oSubscriptions as $oSubscription) {
  104. $oTransaction = new Transaction();
  105. $oTransaction->setType(Transaction::TYPE_CHARGE);
  106. $oTransaction->setActive(true)
  107. ->setState(Transaction::STATE_IN_PROGRESS)
  108. ->setAmount($oSubscription->getAmount())
  109. ->setCurrencyIsoCode($oSubscription->getCurrencyIsoCode())
  110. ->setPaymentMethod($oSubscription->getPaymentMethod())
  111. ->setPayment($oSubscription);
  112. $this->oEm->persist($oTransaction);
  113. $aTransactions[] = $oTransaction;
  114. }
  115. $this->oEm->flush();
  116. return $aTransactions;
  117. }
  118. /**
  119. * Find transaction by reference
  120. *
  121. * @param string $sRef reference
  122. *
  123. * @return Transaction
  124. */
  125. public function findByRef($sRef)
  126. {
  127. return $this->oRepository->findOneBy(['sReference' => $sRef]);
  128. }
  129. /**
  130. * Find transaction by ID
  131. *
  132. * @param string $iId ID
  133. *
  134. * @return Transaction
  135. */
  136. public function findById($iId)
  137. {
  138. return $this->oRepository->find($iId);
  139. }
  140. /**
  141. * Get transactions by state
  142. *
  143. * @param array $aOrderStates states
  144. * @param null $sGateway gateway key
  145. * @param \DateTime|null $oCreatedBefore date of last changing
  146. * @param array $aTransactionStates transaction states
  147. *
  148. * @return \Doctrine\ORM\Internal\Hydration\IterableResult<Transaction>
  149. */
  150. public function getTransactionByState(
  151. array $aOrderStates,
  152. $sGateway = null,
  153. \DateTime $oCreatedBefore = null,
  154. array $aTransactionStates = []
  155. ) {
  156. $oQb = $this->oRepository->createQueryBuilder('t');
  157. if ($oCreatedBefore instanceof \DateTime) {
  158. $oQb->andWhere('t.oCreationDate < :createdBefore')
  159. ->setParameter('createdBefore', $oCreatedBefore);
  160. }
  161. if ($aOrderStates !== [] || !is_null($sGateway)) {
  162. $aCondition = [];
  163. if ($aOrderStates !== []) {
  164. $aCondition[] = 'p.sState IN (:paymentState)';
  165. $oQb->setParameter('paymentState', $aOrderStates);
  166. }
  167. if ($sGateway) {
  168. $aCondition[] = 'p.sPaymentGateway = :gateway';
  169. $oQb->setParameter('gateway', $sGateway);
  170. }
  171. if ($aTransactionStates !== []) {
  172. $aCondition[] = 't.sState IN (:aTransactionStates)';
  173. $oQb->setParameter('aTransactionStates', $aTransactionStates);
  174. }
  175. $oQb->innerJoin('t.oPayment', 'p', 'WITH', implode(' AND ', $aCondition));
  176. }
  177. return $oQb->getQuery()->iterate();
  178. }
  179. /**
  180. * @param string|null $sMerchantEmail merchant's email
  181. * @param array $aReferences array or order references
  182. *
  183. * @return Transaction []
  184. */
  185. public function getForSplitPaymentSync($sMerchantEmail = null, $aReferences = [])
  186. {
  187. $oQb = $this->oRepository->createQueryBuilder('t');
  188. $oQb
  189. ->andWhere('t.sState = :sState')
  190. ->setParameter('sState', Transaction::STATE_SUCCEEDED)
  191. ->leftJoin('t.oPayment', 'p', Join::WITH, 't.oPayment = p')
  192. ->leftJoin(RecurrentConfiguration::class, 'rc', Join::WITH, 'rc.oOrder = p')
  193. ->andWhere('rc.oOrder IS NOT NULL');
  194. ;
  195. if ($sMerchantEmail != null) {
  196. $oQb->leftJoin(Application::class, 'a', 'WITH', 'p.oApplication = a')
  197. ->leftJoin(Merchant::class, 'm', 'WITH', 'a.oMerchant = m')
  198. ->andWhere('m.sEmail = :sMerchantEmail')
  199. ->setParameter('sMerchantEmail', $sMerchantEmail);
  200. }
  201. if (!empty($aReferences)) {
  202. $oQb->andWhere('p.sReference IN (:aReferences)')
  203. ->setParameter('aReferences', $aReferences);
  204. }
  205. return $oQb->getQuery()->getResult();
  206. }
  207. /**
  208. * Get transactions by period
  209. *
  210. * @param \DateTime $oCreationDate transactions created equal or later this date
  211. * @param array $aStates transaction states
  212. * @param array $aOrderStates order states
  213. * @param array $aGateways payment gateways
  214. * @param array $aReferences transaction references
  215. * @param bool $b3DS 3DS flag
  216. *
  217. * @return Transaction[]
  218. */
  219. public function getTransactionsByPeriod(
  220. \DateTime $oCreationDate = null,
  221. $aStates = [],
  222. $aOrderStates = [],
  223. $aGateways = [],
  224. $aReferences = [],
  225. $b3DS = null
  226. ) {
  227. $oQb = $this->oRepository->createQueryBuilder('t');
  228. if ($oCreationDate instanceof \DateTime) {
  229. $oQb->where('t.oCreationDate >= :oCreationDate')
  230. ->setParameter('oCreationDate', $oCreationDate);
  231. }
  232. if ($aStates) {
  233. $oQb->andWhere('t.sState IN (:aStates)')
  234. ->setParameter('aStates', $aStates);
  235. }
  236. if ($aReferences) {
  237. $oQb->andWhere('t.sReference IN (:aReferences)')
  238. ->setParameter('aReferences', $aReferences);
  239. }
  240. if (!empty($aGateways) || !empty($aOrderStates)) {
  241. $oQb->join('t.oPayment', 'p');
  242. }
  243. if ($aGateways) {
  244. $oQb->andWhere('p.sPaymentGateway IN (:gateways)')
  245. ->setParameter('gateways', $aGateways);
  246. }
  247. if ($aOrderStates) {
  248. $oQb->andWhere('p.sState IN (:aOrderStates)')
  249. ->setParameter('aOrderStates', $aOrderStates);
  250. }
  251. if ($b3DS !== null) {
  252. $oQb->andWhere('t.b3DS = :b3ds')
  253. ->setParameter('b3ds', $b3DS);
  254. }
  255. return $oQb->getQuery()->getResult();
  256. }
  257. /**
  258. * @param AcquiredBatch $oAcquiredBatch AcquiredBatch object
  259. * @return float|int|mixed|string
  260. * @throws \Doctrine\ORM\NoResultException
  261. * @throws \Doctrine\ORM\NonUniqueResultException
  262. */
  263. public function calculateBalanceByBatch(AcquiredBatch $oAcquiredBatch)
  264. {
  265. $oQb = $this->oRepository->createQueryBuilder('t')
  266. ->select('SUM(t.fAmount) AS total')
  267. ->where('t.oAcquiredBatch = :acquiredBatch')
  268. ->andWhere('t.sState IN (:state)')
  269. ->setParameters([
  270. 'acquiredBatch' => $oAcquiredBatch,
  271. 'state' => [Transaction::STATE_SETTLED, Transaction::STATE_SUCCEEDED]
  272. ])
  273. ;
  274. return $oQb->getQuery()->getSingleScalarResult();
  275. }
  276. }