src/Bundles/RemoteSystems/Controller/CorpayController.php line 245

Open in your IDE?
  1. <?php
  2. namespace Bundles\RemoteSystems\Controller;
  3. use Bundles\Instruments\Base\Entity\Forward;
  4. use Bundles\RemoteSystems\Form\DrawdownType;
  5. use Bundles\RemoteSystems\Form\OrderForwardType;
  6. use Bundles\RemoteSystems\Form\OrderSpotType;
  7. use Bundles\RemoteSystems\Entity\Trade;
  8. use App\Controller\ParentController;
  9. use App\Entity\Customer;
  10. use App\Models\systems\broker\Corpay;
  11. use App\Models\systems\broker\CorpayDemo;
  12. use Bundles\Portfolios\Entity\Portfolio;
  13. use Bundles\RemoteSystems\Form\ForwardType;
  14. use Bundles\RemoteSystems\Form\SpotType;
  15. use Psr\Log\LoggerInterface;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\JsonResponse;
  18. use Symfony\Contracts\Cache\CacheInterface;
  19. use function Amp\Promise\wait;
  20. class CorpayController extends ParentController {
  21. protected Customer $customer;
  22. protected Corpay|CorpayDemo $corpay;
  23. protected $useRemoteSystems = false;
  24. protected $useRemoteSystemsDemo = false;
  25. protected $session;
  26. protected $request;
  27. protected $url = '';
  28. protected $contractTypes = ['O' => 'Open', 'C' => 'Closed'];
  29. public function initialize($request, $logger = null) {
  30. parent::initialize($request);
  31. $this->request = $request;
  32. $this->session = $request->getSession();
  33. $this->customer = $this->getCustomer();
  34. $partnerId = $_ENV['CORPAY_PartnerId'] ?: '';
  35. $partnerKey = $_ENV['CORPAY_PartnerKey'] ?: '';
  36. $appSecret = $_ENV['APP_SECRET'] ?: '';
  37. $env = $_ENV['APP_ENV'] ?: '';
  38. if (!empty($logger)) {
  39. $this->logger = $logger;
  40. }
  41. if ($this->useRemoteSystemsDemo) { //fake data
  42. $this->corpay = new CorpayDemo($this->logger, $this->session);
  43. $this->useRemoteSystems = true;
  44. } elseif (!empty($this->customer->getRemoteUserCode()) && $this->getUser()->isAccessRemoteSystems()) { //production, sandbox
  45. $this->corpay = new Corpay($this->logger, $this->session, $env);
  46. $validCredentials = $this->corpay->setCredentionals($partnerId, $partnerKey, $this->customer->getRemoteUserCode(), $this->customer->getRemoteUserId(), $this->customer->getDecryptedKey($appSecret));
  47. if ($validCredentials) {
  48. $checkConnection = $this->corpay->clientCall('0/');
  49. $this->useRemoteSystems = !empty($checkConnection['clientCode']);
  50. }
  51. }
  52. return $this;
  53. }
  54. public function dashboard(Request $request, LoggerInterface $dbLogger) {
  55. $this->logger = $dbLogger;
  56. $this->initialize($request);
  57. $this->data['title'] = 'Corpay Dashboard';
  58. $this->data['useRemoteSystems'] = $this->useRemoteSystems;
  59. if (!$this->useRemoteSystems) {
  60. $this->data['apiErrors'] = 'No access to remote system management. Please contact support';
  61. return $this->render('@remoteSystems/corpay/index.html.twig', $this->data);
  62. }
  63. $statusColors = [1 => 'secondary', 2 => 'mustard', 3 => 'primary'];
  64. $statusOrders = ['F' => 'Filled', 'P' => 'Pending', 'E' => 'Expired', 'X' => 'Deleted'];
  65. $statusOrderColors = ['F' => 'primary', 'P' => 'orchid', 'E' => 'gray', 'X' => 'salmon'];
  66. $this->data['statusColors'] = $statusColors;
  67. $step = $request->query->get('step') ?? 1;
  68. if ($this->useRemoteSystems) {
  69. if ($step == 1) {
  70. $this->data['forwards'] = $this->corpay->getForwards();
  71. $this->data['spots'] = $this->corpay->getSpots();
  72. } elseif ($step == 2) {
  73. $this->data['orders'] = $this->corpay->getOrders();
  74. $this->data['statusOrders'] = $statusOrders;
  75. $this->data['statusOrderColors'] = $statusOrderColors;
  76. } elseif ($step == 3) {
  77. $this->data['accounts'] = $this->corpay->getAccounts();
  78. $this->data['accountHistory'] = $this->corpay->getBalanceHistory('610324866000031001', '2024-01-01', date('Y-m-d'));
  79. } elseif ($step == 4) {
  80. $this->data['payments'] = $this->corpay->getPayments();
  81. $this->data['tracking'] = $this->corpay->getPaymentTracking();
  82. } elseif ($step == 5) {
  83. $this->data['news'] = $this->corpay->getMarketNews(10);
  84. } elseif ($step == 6) { //tests
  85. // $this->data['forwardsInfo'] = $this->corpay->getForwardGuideline();
  86. // $this->data['BusinessTypes'] = $this->corpay->call('clientonboarding/onboardingpicklists?pickListType=BusinessType');
  87. $data = [
  88. 'amount' => $request->request->get('amount') ?? 1000,
  89. 'buyCurrency' => $request->request->get('buyCurrency') ?? 'USD',
  90. // 'forwardType' => $request->request->get('forwardType') ?? 'C',
  91. 'lockSide' => $request->request->get('lockSide') ?? 'Settlement', //Payment/Settlement
  92. // 'maturityDate' => $request->request->get('maturityDate') ?? date_create('+ 35 days')->format('Y-m-d'),
  93. 'expiryDate' => $request->request->get('expiryDate') ?? date_create('+ 35 days')->format('Y-m-d'),
  94. // 'openDateFrom' => $request->request->get('openDateFrom') ?? date_create('+ 1 day')->format('Y-m-d'),
  95. 'sellCurrency' => $request->request->get('sellCurrency') ?? 'EUR',
  96. // 'settlementCurrency' => $request->request->get('sellCurrency') ?? 'EUR',
  97. // 'paymentCurrency' => $request->request->get('sellCurrency') ?? 'USD',
  98. 'rate' => $request->request->get('rate') ?? '1.11',
  99. 'limitOrderType' => $request->request->get('limitOrderType') ?? 'Spot', //Spot/Forward
  100. ];
  101. // $forwardPost = $this->corpay->postForward($data);
  102. // $quotId = $this->corpay->postSpot($data);
  103. // $orderResponse = $this->corpay->postOrder($data);
  104. if (!empty($quotId)) {
  105. $quotDetails = $this->corpay->rateResource($quotId);
  106. $spotOrderData = $this->corpay->spotBook($quotId);
  107. }
  108. $this->data['tests']['forwardPost'] = $forwardPost ?? [];
  109. $this->data['tests']['quotDetails'] = $quotDetails ?? [];
  110. $this->data['tests']['spotOrderData'] = $spotOrderData ?? [];
  111. $this->data['tests']['orderResponse'] = $orderResponse ?? [];
  112. }
  113. } else {
  114. $this->data['apiErrors'] = 'No access to Corpay remote system';
  115. }
  116. $this->data['step'] = $step;
  117. $this->data['apiErrors'] = $this->corpay->getErrors();
  118. //dump($this->data);
  119. return $this->render('@remoteSystems/corpay/index.html.twig', $this->data);
  120. }
  121. public function getForwards($portfolioId, Request|null $request, LoggerInterface|null $dbLogger, CacheInterface|null $cache) {
  122. $this->logger = $dbLogger;
  123. $this->initialize($request);
  124. if (!$this->useRemoteSystems) {
  125. return $this->json(['error' => 'No access to remote system'], 403);
  126. }
  127. if (empty($portfolioId)) {
  128. return $this->json(['error' => 'No portfolioId'], 403);
  129. }
  130. $portfolio = $this->em->getRepository(Portfolio::class)->findOneBy(['id' => $portfolioId,
  131. 'customer' => $this->customer,
  132. ]);
  133. if (empty($portfolio)) {
  134. return $this->json(['error' => 'No portfolio found'], 403);
  135. }
  136. $currPairName = $portfolio->getCurrencyPair()->getName();
  137. $minorCurr = $portfolio->getCurrencyPair()->getCurrencyNameByNumber(2);
  138. $forwards = $this->corpay->getForwards();
  139. $spots = [];// siai dienai istoriniu spotu dealu paimti negalime, nes API neturi reikiamo endpointo tam
  140. $list = [];
  141. $forwardCount = 0;
  142. if (!empty($forwards['data']['rows'])) {
  143. $forwards = $forwards['data']['rows'];
  144. $forwardNumbers = [];
  145. foreach ($forwards as $key => $item) {
  146. $forwardNumbers[] = $item['ordNum'];
  147. }
  148. $existingForwards = $this->em->getRepository(Forward::class)->findBy(['tradeNumber' => $forwardNumbers, 'Portfolio' => $portfolioId]);
  149. foreach ($existingForwards as $item) {
  150. $existingForwardList[$item->getTradeNumber()] = $item->getId();
  151. }
  152. foreach ($forwards as $item) {
  153. $tradePairName1 = $item['currency'].'/'.$item['costCurrency'];
  154. $tradePairName2 = $item['costCurrency'].'/'.$item['currency'];
  155. if ($currPairName == $tradePairName1 || $currPairName == $tradePairName2) {
  156. $item['currencyPair'] = $currPairName;
  157. $item['createdBy'] = 'forward';
  158. if ($item['currency'] != $minorCurr) { //kartais buna, kai valiutu pora atvirkstine, todel reikia patikrinti ir isvesti pagal poras vistiek minor valiutos amounta
  159. $item['amount'] = $item['costAmount'];
  160. }
  161. $item['exist'] = $existingForwardList[$item['ordNum']] ?? 0;
  162. $list[] = $item;
  163. $forwardCount++;
  164. }
  165. }
  166. }
  167. if (!empty($spots)) {
  168. $spotCount = 0;
  169. foreach ($spots as $item) {
  170. $tradePairName1 = substr($item['rateType'], 0, 3).'/'.substr($item['rateType'], 3);
  171. $tradePairName2 = substr($item['rateType'], 3).'/'.substr($item['rateType'], 0, 3);
  172. if ($currPairName == $tradePairName1 || $currPairName == $tradePairName2) {
  173. $list[] = [
  174. 'maturityDate' => $item['quoteTimestamp'],
  175. 'token' => $item['id'],
  176. 'ordNum' => '',
  177. 'currencyPair' => $currPairName,
  178. 'costAmount' => $item['paymentAmount'],
  179. 'rate' => $item['rate'],
  180. 'createdBy' => 'spot',
  181. ];
  182. $spotCount++;
  183. }
  184. }
  185. }
  186. $error = '';
  187. if (count($list) != (count($spots) + count($forwards))) {
  188. if (!empty($forwards) && count($forwards) != $forwardCount) {
  189. $error .= 'Forwards received '.count($forwards).', but fit for this portfolio '.$forwardCount.'<br>';
  190. }
  191. if (!empty($spots) && count($spots) != $spotCount) {
  192. $error .= 'Spots received '.count($spots).', but fit for this portfolio '.$spotCount;
  193. }
  194. }
  195. $data = [
  196. 'list' => $list,
  197. ];
  198. if (!empty($cache)) {
  199. // Generate a unique key for this session
  200. $cacheKey = 'broker_forwards_'.$this->getUser()->getId();
  201. // Save big array in cache for 1 hour
  202. $cache->delete($cacheKey); // optional, clear previous
  203. $cache->get($cacheKey, function () use ($list) {
  204. return $list;
  205. });
  206. $data['count'] = count($cache->getItem($cacheKey)->get());
  207. }
  208. return new JsonResponse($data, 200);
  209. }
  210. public function getForms(?int $portfolioId, Request $request, LoggerInterface $dbLogger) {
  211. $this->logger = $dbLogger;
  212. $this->initialize($request);
  213. $portfolio = $this->em->getRepository(Portfolio::class)->findOneBy([
  214. 'id' => $portfolioId,
  215. 'customer' => $this->getCustomer()->getId(),
  216. ]);
  217. if (empty($portfolio) || !$this->useRemoteSystems) {
  218. return new JsonResponse(['error' => 'Unauthorized access or lack of rights. Please reach the support for more information.']);
  219. }
  220. $this->url = $portfolio->getId();
  221. $majorCurr = $portfolio->getCurrencyPair()->getCurrencyNameByNumber(1);
  222. $minorCurr = $portfolio->getCurrencyPair()->getCurrencyNameByNumber(2);
  223. $sellCurr = $majorCurr;
  224. $buyCurr = $minorCurr;
  225. $currencies = [
  226. 'buy' => [$minorCurr => $minorCurr],
  227. 'sell' => [$majorCurr => $majorCurr],
  228. ];
  229. if ($portfolio->getDirection() == 'receive') {
  230. $currencies['buy'] = [$majorCurr => $majorCurr];
  231. $currencies['sell'] = [$minorCurr => $minorCurr];
  232. $sellCurr = $minorCurr;
  233. $buyCurr = $majorCurr;
  234. }
  235. $accounts = $this->corpay->getAccounts($sellCurr);
  236. $options = [
  237. 'currencies' => $currencies,
  238. 'currentCurr' => $buyCurr,
  239. 'accounts' => $accounts['accounts'],
  240. ];
  241. $spotForm = $this->getForm('spot', null, $options);
  242. $forwardForm = $this->getForm('forward', null, $options);
  243. // $orderSpotForm = $this->getForm('orderSpot', null, $options);
  244. // $orderForwardForm = $this->getForm('orderForward', null, $options);
  245. $data = [
  246. 'spotForm' => $spotForm->createView(),
  247. 'forwardForm' => $forwardForm->createView(),
  248. // 'orderSpotForm' => $orderSpotForm->createView(),
  249. // 'orderForwardForm' => $orderForwardForm->createView(),
  250. 'accountDetails' => $accounts['details'],
  251. 'sellCurr' => $sellCurr,
  252. 'buyCurr' => $buyCurr,
  253. ];
  254. $operatinForm = $this->render('@remoteSystems/corpay/forms.html.twig', $data)->getContent();
  255. return new JsonResponse($operatinForm, 200);
  256. }
  257. protected function getForm($type, $object = null, $options = []) {
  258. switch ($type) {
  259. case 'forward':
  260. if (empty($object)) {
  261. $object = new Trade();
  262. }
  263. $objetType = ForwardType::class;
  264. $vars = '&type='.$type;
  265. break;
  266. case 'spot':
  267. if (empty($object)) {
  268. $object = new Trade();
  269. }
  270. $objetType = SpotType::class;
  271. $vars = '&type='.$type;
  272. break;
  273. case 'orderSpot':
  274. if (empty($object)) {
  275. $object = new Trade();
  276. }
  277. $objetType = OrderSpotType::class;
  278. $vars = '&type='.$type;
  279. break;
  280. case 'orderForward':
  281. if (empty($object)) {
  282. $object = new Trade();
  283. }
  284. $objetType = OrderForwardType::class;
  285. $vars = '&type='.$type;
  286. break;
  287. case 'drawdown':
  288. if (empty($object)) {
  289. $object = new Trade();
  290. }
  291. $objetType = DrawdownType::class;
  292. $vars = '&type='.$type;
  293. break;
  294. }
  295. $options['url'] = $this->url.'&step=6'.$vars;
  296. return $this->createForm($objetType, $object, $options);
  297. }
  298. protected function getErrors($errors) {
  299. $errorList = null;
  300. if (!empty($errors)) {
  301. $errorList = 'Errors: <br><ul>';
  302. foreach ($errors as $error) {
  303. if (!empty($error['message'])) {
  304. $errorList .= '<li>'.$error['message'].'</li>';
  305. }
  306. }
  307. $errorList .= '</ul>';
  308. }
  309. return $errorList;
  310. }
  311. }