<?php
namespace App\Controller;
use App\Entity\Theme;
use App\Repository\BasketRepository;
use App\Repository\CellRuleRepository;
use App\Repository\ClientRepository;
use App\Repository\CounterpartyRepository;
use App\Repository\CurrencyRepository;
use App\Repository\HoverOverRepository;
use App\Repository\SdsFormRequestRepository;
use App\Repository\SettingsRepository;
use App\Repository\ThemeRepository;
use App\Repository\UserRepository;
use App\Service\CommonService;
use App\Service\SpreadsheetService;
use Doctrine\ORM\EntityManagerInterface;
use PhpOffice\PhpSpreadsheet\Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
class HomeController extends AbstractController
{
public function __construct(private readonly EntityManagerInterface $entityManager, private readonly ParameterBagInterface $parameterBag)
{
}
#[Route('/', name: 'index')]
public function index(): Response
{
if ($this->getUser()) {
if (in_array('ROLE_ADMIN', $this->getUser()->getRoles())) {
return $this->redirectToRoute('admin_dashboard');
} elseif (in_array('ROLE_STAFF', $this->getUser()->getRoles())) {
return $this->redirectToRoute('sds_requests_menu');
} elseif (in_array('ROLE_COUNTERPARTY', $this->getUser()->getRoles())) {
return $this->redirectToRoute('counterparty_home');
} else {
return $this->redirectToRoute('home');
}
}
return $this->redirectToRoute('home');
}
// Waiting for approval page
#[Route('/user/waiting-for-approval', name: 'waiting_for_approval')]
public function waitingForApproval(): Response
{
/** @var \App\Entity\User|null $user */
$user = $this->getUser();
if ($user && $user->isApproved()) {
return $this->redirectToRoute('index');
}
return $this->render('waiting_for_approval.html.twig');
}
// Privacy Policy page
#[Route('/user/privacy-policy', name: 'privacy_policy')]
public function privacyPolicy(): Response
{
return $this->render('privacy_policy.html.twig');
}
#[Route('/user/home', name: 'home')]
public function home(
CommonService $commonService,
UserRepository $userRepository,
ThemeRepository $themeRepository,
HoverOverRepository $hoverOverRepository,
BasketRepository $basketRepository,
CounterpartyRepository $counterpartyRepository,
CellRuleRepository $cellRuleRepository,
CurrencyRepository $currencyRepository,
SettingsRepository $settingsRepository,
ClientRepository $clientRepository
): Response {
/** @var \App\Entity\User|null $user */
$user = $this->getUser();
if ($user && !$user->isApproved()) {
return $this->redirectToRoute('waiting_for_approval');
}
$loggedUser = $userRepository->findOneBy(['email' => $this->getUser()->getUserIdentifier()]);
$loggedUserTheme = $loggedUser->getAssociatedTheme();
try {
$ratesTableSpreadsheet = new SpreadsheetService($this->parameterBag->get('kernel.project_dir').'/spreadsheets/WWW_rates_table.xlsx');
} catch (Exception) {
return $this->render('please_wait.html.twig', [
'timer' => 1,
'url' => $this->generateUrl('home'),
]);
}
$userSelectedCurrency = $loggedUser->getSelectedCurrency()->getValue();
$sheetName = $userSelectedCurrency.'_'.$loggedUserTheme->getDataSheetName();
$dataTablesSheet = $ratesTableSpreadsheet->loadSheet($sheetName);
if (null == $dataTablesSheet) {
return $this->render('please_wait.html.twig', [
'timer' => 1,
'url' => $this->generateUrl('home'),
]);
}
$dataTablesSheetArray = $ratesTableSpreadsheet->loadArraySheet($sheetName);
// Rendering Graph Image
$graphImgPath = $this->getParameter('kernel.project_dir').'/public/assets/spreadsheet_images/';
$graphImgName = $ratesTableSpreadsheet->loadGraphImg('Graph', $graphImgPath);
// Bank Holidays Dates Disabling
$bankHolidaysArray = [];
$bankHolidaysSheetData = $ratesTableSpreadsheet->loadArraySheet('Bank_Hols');
foreach ($bankHolidaysSheetData as $row) {
if ($row['C'] == $userSelectedCurrency) {
$bankHolidaysArray[] = date('Y-m-d', strtotime($row['A']));
}
}
// User Saved Form read from DB
$encoder = new JsonEncoder();
$defaultContext = [
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => fn ($object, $format, $context) => $object->getId(),
];
$normalizer = new ObjectNormalizer(null, null, null, null, null, null, $defaultContext);
$serializer = new Serializer([$normalizer], [$encoder]);
$userSavedForm = $serializer->normalize($loggedUser->getUserForm(), 'json', ['attributes' => ['seek', 'amount', 'tolerance', 'settlementType', 'ccEmails', 'notes']]);
$userSavedFormExtension = [
'tradingEntity' => $loggedUser->getUserForm() && $loggedUser->getUserForm()->getClient() ? $loggedUser->getUserForm()->getClient()->getId() : '',
'basket' => $loggedUser->getUserForm() && $loggedUser->getUserForm()->getBasket() ? $loggedUser->getUserForm()->getBasket()->getId() : '',
'counterparty' => $loggedUser->getUserForm() && $loggedUser->getUserForm()->getCounterparty() ? $loggedUser->getUserForm()->getCounterparty()->getId() : '',
'currency' => $loggedUser->getUserForm() && $loggedUser->getUserForm()->getCurrency() ? $loggedUser->getUserForm()->getCurrency()->getId() : '',
];
// Cell rules from DB
$backgroundColorSelectableCellsArray = [];
$fontColorSelectableCellsArray = [];
$cellRules = $cellRuleRepository->findAll();
foreach ($cellRules as $cellRule) {
if (str_contains($cellRule->getValue(), 'BG-')) {
$backgroundColorSelectableCellsArray[] = substr($cellRule->getValue(), 3);
} elseif (str_contains($cellRule->getValue(), 'TXT-')) {
$fontColorSelectableCellsArray[] = substr($cellRule->getValue(), 4);
}
}
$feeMargin = $loggedUser->getFeeMargin() / 100;
$feeMarginStr = (string) $feeMargin;
$feeMarginDotPos = strpos($feeMarginStr, '.');
$feeMarginDigits = false !== $feeMarginDotPos ? strlen(substr($feeMarginStr, $feeMarginDotPos)) - 1 : 0;
$newTableArr = [];
foreach ($dataTablesSheetArray as $key => $row) {
if (1 == $key) {
$newTableArr[] = $row;
} else {
$oneRowArr = [];
foreach ($row as $letterRef => $cellValue) {
if (('double' == gettype($cellValue)) || ('integer' == gettype($cellValue))) {
$cellValueStr = (string) $cellValue;
$cellValueDotPos = strpos($cellValueStr, '.');
$cellValueDigits = false !== $cellValueDotPos ? strlen(substr($cellValueStr, $cellValueDotPos)) - 1 : 0;
$scale = $cellValueDigits >= $feeMarginDigits ? $cellValueDigits : $feeMarginDigits;
$cellValue = bcsub($cellValueStr, $feeMarginStr, $scale);
}
$oneRowArr[$letterRef] = $cellValue;
}
$newTableArr[] = $oneRowArr;
}
}
$associatedClients = $clientRepository->fetchUserLinkedClients($loggedUser->getId());
$associatedClientsEntitiesApprovedSsisCurrencies = $currencyRepository->fetchAssociatedClientsEntitiesApprovedSsisCurrenciesByUserId($loggedUser->getId());
return $this->render('home/index.html.twig', [
'table_data_sheet' => $dataTablesSheet,
'table_data_sheet_array' => $newTableArr,
'border_width_array' => Theme::BORDER_WIDTH,
'hover_data_array' => $hoverOverRepository->findAll(),
'theme' => $loggedUserTheme,
'table_column_style' => $commonService->getColumnsStyle($dataTablesSheet, $dataTablesSheetArray[1]),
'counterparty_data_array' => $counterpartyRepository->findBy(['isDeleted' => false]),
'basket_data_array' => $basketRepository->findBy(['isDeleted' => false]),
'currency_data_array' => $currencyRepository->findBy(['isDeleted' => false]),
'graph_img_path' => $graphImgName,
'available_themes' => $themeRepository->fetchPublicThemes(),
'bank_Holidays_Array_Encoded' => json_encode($bankHolidaysArray),
'user_form_array' => json_encode($userSavedForm),
'user_form_array_extension' => json_encode($userSavedFormExtension),
'background_color_selectable_cells' => json_encode($backgroundColorSelectableCellsArray),
'font_color_selectable_cells' => json_encode($fontColorSelectableCellsArray),
/* 'currencies' => $currencyRepository->findBy(["isDeleted" => false]), */
'currencies' => $associatedClientsEntitiesApprovedSsisCurrencies,
'instructions_from_db' => $settingsRepository->findOneBy(['property' => 'instructions']),
'clients' => $associatedClients,
]);
}
// Save theme for user
#[Route('/user/home/theme/save', name: 'theme_save')]
public function themeSave(Request $request, ThemeRepository $themeRepository, UserRepository $userRepository): Response
{
$selectedThemeId = $request->request->get('selectedTheme');
$selectedTheme = $themeRepository->find($selectedThemeId);
$loggedUser = $userRepository->findOneBy(['email' => $this->getUser()->getUserIdentifier()]);
$loggedUser->setAssociatedTheme($selectedTheme);
$this->entityManager->persist($loggedUser);
$this->entityManager->flush();
return $this->redirect($request->headers->get('referer'));
}
#[Route('/user/home/currency/save', name: 'currency_save')]
public function currencySave(Request $request, CurrencyRepository $currencyRepository, UserRepository $userRepository): Response
{
$selectedCurrencyId = $request->request->get('currencyToChange');
$selectedCurrency = $currencyRepository->find($selectedCurrencyId);
if ($selectedCurrency) {
$loggedUser = $userRepository->findOneBy(['email' => $this->getUser()->getUserIdentifier()]);
$loggedUser->setSelectedCurrency($selectedCurrency);
$this->entityManager->persist($loggedUser);
$this->entityManager->flush();
}
return $this->redirect($request->headers->get('referer'));
}
// Populate form data from link
#[Route('/user/home/{id}/autofill', name: 'sds_request_indication_only_form_autofill')]
public function autofillFormDataIndication(int $id, SdsFormRequestRepository $sdsFormRequestRepository, Request $request): Response
{
$session = $request->getSession();
$sdsRequest = $sdsFormRequestRepository->find($id);
$currency = $sdsRequest->getCurrency();
$sdsRequestUser = $sdsRequest->getUser()->setSelectedCurrency($currency);
$autofilledCounts = $sdsRequest->getAutoFilledRequestsCount();
++$autofilledCounts;
$sdsRequest->setAutoFilledRequestsCount($autofilledCounts);
$this->entityManager->persist($sdsRequestUser);
$this->entityManager->flush();
$session->set('requestsCount', $autofilledCounts);
$session->set('tradingEntity', $sdsRequest->getClient()->getId());
$session->set('amount', $sdsRequest->getAmount());
if ($sdsRequest->getCounterparty()) {
$session->set('counterpartyId', $sdsRequest->getCounterparty()->getId());
$session->set('counterpartyValue', $sdsRequest->getCounterparty()->getValue());
}
if ($sdsRequest->getBasket()) {
$session->set('basket', $sdsRequest->getBasket()->getId());
$session->set('basketValue', $sdsRequest->getBasket()->getValue());
}
if ($sdsRequest->getRate()) {
$session->set('period', explode(' - ', $sdsRequest->getRate())[0]);
}
if ($sdsRequest->getNetTradeRate()) {
$session->set('tradeRate', $sdsRequest->getNetTradeRate());
}
if ($sdsRequest->getValueDate()) {
$session->set('valueDate', $sdsRequest->getValueDate()->format('d-m-Y'));
}
if ($sdsRequest->getMaturityDate()) {
$session->set('maturityDate', $sdsRequest->getMaturityDate()->format('d-m-Y'));
}
if ($sdsRequest->getSeek()) {
$session->set('seek', $sdsRequest->getSeek());
}
if ($sdsRequest->getTolerance()) {
$session->set('tolerance', $sdsRequest->getTolerance());
}
if ($sdsRequest->getCcEmails()) {
$session->set('ccEmails', implode(';', $sdsRequest->getCcEmails()));
}
if ($sdsRequest->getNotes() && '' !== trim($sdsRequest->getNotes())) {
$session->set('notes', trim(preg_replace("/\r|\n/", ' ', $sdsRequest->getNotes())));
} else {
$session->set('notes', '');
}
$session->set('indicationRequestDateTime', $sdsRequest->getCreatedAt()->format('Y-m-d H:i'));
return $this->redirectToRoute('home');
}
}