<?php
namespace App\Controller\Web;
use App\Entity\Building;
use App\Entity\ProcessedFiles;
use App\Exception\ParseFileFailedException;
use App\Form\LastLoginType;
use App\Form\MultipleFileUploadType;
use App\Form\ProcessedFileType;
use App\Helpers\ApiLogger;
use App\Helpers\CommonHelper;
use App\Repository\FlatRepository;
use App\Repository\ProcessedFilesRepository;
use App\Repository\UserRepository;
use App\Response\PdfResponse;
use App\Services\Bank\ParserInterface;
use App\Services\BuildingService;
use App\Services\DefaultService;
use App\Services\ProcessService;
use DateTime;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Knp\Snappy\Pdf;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\User;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class DefaultController extends AbstractController
{
private DefaultService $defaultService;
private UserRepository $userRepository;
private Pdf $pdf;
private FlatRepository $flatRepository;
private ProcessService $processService;
private BuildingService $buildingService;
private ProcessedFilesRepository $processedFilesRepository;
/**
* DefaultController constructor.
* @param DefaultService $defaultService
* @param UserRepository $userRepository
* @param Pdf $pdf
* @param FlatRepository $flatRepository
* @param ProcessService $processService
* @param BuildingService $buildingService
* @param ProcessedFilesRepository $processedFilesRepository
*/
public function __construct(
DefaultService $defaultService,
UserRepository $userRepository,
Pdf $pdf,
FlatRepository $flatRepository,
ProcessService $processService,
BuildingService $buildingService,
ProcessedFilesRepository $processedFilesRepository
) {
$this->defaultService = $defaultService;
$this->userRepository = $userRepository;
$this->pdf = $pdf;
$this->flatRepository = $flatRepository;
$this->processService = $processService;
$this->buildingService = $buildingService;
$this->processedFilesRepository = $processedFilesRepository;
}
/**
* @Route("/", name="homepage")
* @return RedirectResponse
*/
public function indexAction(): RedirectResponse
{
return new RedirectResponse($this->generateUrl('dashboard'));
}
/**
* @return Response
* @throws NoResultException
* @throws NonUniqueResultException
*/
#[Route('/dashboard', name: 'dashboard')]
public function dashboardAction(): Response
{
/** @var User $user */
$user = $this->getUser();
$isSuperAdmin = $this->defaultService->isImpersonatorSuperAdmin();
return $this->render(
'@views/Default/dashboard.html.twig',
$this->defaultService->getDashboardInformation($user, $isSuperAdmin)
);
}
/**
* @return Response
* @throws NoResultException
* @throws NonUniqueResultException
*/
#[Route('/dashboard_new', name: 'dashboard_new')]
public function dashboardNewAction(Request $request): Response
{
$processedBuildings = [];//todo: fetch unprocessed files
$logs = [];
/** @var User $user */
$user = $this->getUser();
$isSuperAdmin = $this->defaultService->isImpersonatorSuperAdmin();
$allMonths = [
'2024-10-01' => '2024-10-01',
'2024-09-01' => '2024-09-01',
'2024-08-01' => '2024-08-01',
'2024-07-01' => '2024-07-01',
'2024-06-01' => '2024-06-01',
'2024-05-01' => '2024-05-01',
'2024-04-01' => '2024-04-01',
'2024-03-01' => '2024-03-01',
'2024-02-01' => '2024-02-01',
'2024-01-01' => '2024-01-01',
'2023-12-01' => '2024-12-01',
];
$allMonthsView = [];
foreach ($allMonths as $month) {
$newMonth = CommonHelper::getMonth($month);
$allMonthsView[] = $newMonth;
}
$form = $this->createForm(MultipleFileUploadType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$files = $form->get('files')->getData();
$logs[] = "\n================================== START ==================================================\n";
foreach ($files as $key => $file) {
//// BEGIN - add to job -----------
$logs[] = "\n ------- file :$key ------- ";
$fileExtension = $file->guessClientExtension();
$fileName = sprintf(
"%s%s.%s",
md5($file->getClientOriginalName()),
uniqid(),
$file->guessClientExtension()
);
$logs[] = "\n". date("Y-m-m H:i:s") . " - file: ".$file->getClientOriginalName() .".". $fileExtension .". md5 hash: ".$fileName;
// Move the file to the directory where brochures are stored
$file->move(
$this->getParameter('bank_notification_directory'),
$fileName
);
$logs[] = "\nMoved file to directory: ";
$bankNameDetails = $this->processService->getBankNameDetails(
$fileName,
$fileExtension,
$this->getParameter('bank_notification_directory')
);
if (empty($bankNameDetails)) {
//to do: add log
$logs[] = "\nBank detail is empty. ";
$logs[] = "\nFinished file\n==================\n";
$processedBuildings[] = [
"building" => $file->getClientOriginalName().".".$file->guessClientExtension(),
"type" => "file",
"status" => false
];
continue;
}
$logs[] = "\nBank detail: bankName: ". $bankNameDetails['bankName'] ." datum: " .$bankNameDetails['datum']->getTimestamp() ;
//to do: add log
/** @var Building|null $building */
$building = $this->buildingService->getBuildingByBankAccount($bankNameDetails['account']);
if (!$building) {
$logs[] = "\nBuilding does not exist with account: ".$bankNameDetails['account'];
$logs[] = "\nFinished file\n==================\n";
$processedBuildings[] = [
"building" => $file->getClientOriginalName().".".$file->guessClientExtension(),
"type" => "building",
"status" => false
];
continue;
}
try {
$this->defaultService->checkEntity($building, $user);
} catch (\Exception $exception) {
$processedBuildings[] = [
"building" => $file->getClientOriginalName().".".$file->guessClientExtension(),
"type" => "building not belong",
"status" => false
];
$logs[] = "\nBuilding not belong. ";
$logs[] = "\nFinished file\n==================\n";
continue;
}
$processedBuildings[] = [
"building" => $building ?? null,
"type" => "building",
"status" => $building ? true : false
];
$processedFiles = new ProcessedFiles();
$processedFiles->setBankDailyNotification($fileName);
$processedFiles->setBankName($bankNameDetails['bankName']);
$processedFiles->setBankDate($bankNameDetails['datum']);
$processedFiles->setBuilding($building);
$processedFiles->setUser($user);
$logs[] = "\nSet ProcessedFiles, with values: $fileName, bankName: ". $bankNameDetails['bankName'] ." datum: " .$bankNameDetails['datum']->getTimestamp() .", user: ".$user->getId() .", building: ".$building->getId();
/** @var ProcessedFiles|null $file */
$file = $this->processedFilesRepository->findOneBy([
'user' => $building->getUser(),
'bankDate' => $bankNameDetails['datum'],
'building' => $building,
'bankName' => $bankNameDetails['bankName']
]);
if (!$file) {
$logs[] = "\nSave new file. ";
$processedFiles->setStatus(0);
$this->processedFilesRepository->save($processedFiles);
} else {
$logs[] = "\nAlready exist file. ";
$processedFiles = $file;
}
$companyUsers = $this->userRepository->findUsersByMain($user);
if (!in_array($building->getUser(), $companyUsers)) {
$logs[] = "\nBuilding is not belong to user: ".$user->getId() .", building: ".$building->getId();
$logs[] = "\nFinished file\n==================\n";
$processedBuildings[] = [
"building" => $fileName,
"type" => "user",
"status" => false
];
continue;
}
/** @var ParserInterface $parser */
$parser = $this->processService->getParser($bankNameDetails['bankName']);
$parsedData = $parser->parseFile($this->getParameter('bank_notification_directory'), $processedFiles);
if (!$this->processService->isValidParsedData($parsedData, $building)) {
$logs[] = "\nParsed data is not valid";
$logs[] = "\nFinished file\n==================\n";
$processedBuildings[] = [
"building" => $file->getClientOriginalName().".".$file->guessClientExtension(),
"type" => "data",
"status" => false
];
continue;
}
$logs[] = "\nParsed file: ".$parsedData['bankDailyCheckPoint'];
$processedFiles->setBankFileId($parsedData['bankDailyCheckPoint']);
$processedFileStatus = $this->processService->processBankNotification($parsedData, $processedFiles, $building, $logs);
$count = $processedFiles->getProcessedFlats() ? $processedFiles->getProcessedFlats()->count() : 0;
$notProcessedFilesCount = count($parsedData['flats']) - $count;
$currentDate = new \DateTime($parsedData['bankCheckpointData']);
$processedFiles->setBankDate($currentDate);
$processedFiles->setNumberOfNotProcessedFiles($notProcessedFilesCount);
$processedFiles->setStatus($processedFileStatus['status']);
$this->processedFilesRepository->save($processedFiles);
$logs[] = "\nFinished file\n==================\n";
//// END - add to job -----------
}
$logs[] = "\n================================== END ========================================================\n";
$logString = implode(" ", $logs);
ApiLogger::addApiLog($logString, 'bank_statements_bulk');
//tod: add in action_log table
}
$response = $this->defaultService->getDashboardInformation($user, $isSuperAdmin);
$response['form'] = $form->createView();
$response['processedBuildings'] = $processedBuildings;
$response['allMonths'] = $allMonthsView;
return $this->render(
'@views/Default/dashboardNew.html.twig',
$response
);
}
/**
* @Route("/datatable-problems", name="datatable_problems", options={"expose"=true})
* @param Request $request
* @return JsonResponse
* @throws NoResultException
* @throws NonUniqueResultException
*/
public function datatableProblemsAction(Request $request): JsonResponse
{
/** @var User $user */
$user = $this->getUser();
return new JsonResponse($this->defaultService->getDatatableProblems($request, $user));
}
/**
* @Route("super-admin/last-login", name="last_login", options={"expose"=true})
* @param Request $request
* @return RedirectResponse|Response
*/
public function lastLoginAction(Request $request): Response|RedirectResponse
{
/** @var User $user */
$user = $this->getUser();
/** @var Form $form */
$form = $this->createForm(
LastLoginType::class,
[],
[
'method' => 'POST',
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$startDate = $form->getData()['startDate']->format('Y-m-d');
$endDate = null;
if ($form->getData()['endDate']) {
$endDate = $form->getData()['endDate']->format('Y-m-d');
}
if ($form->getClickedButton() === $form->get('login')) {
$url = $this->generateUrl('last_login_pdf', ['startDate' => $startDate, 'endDate' => $endDate]);
} else {
$url = $this->generateUrl('flats_import_list', ['startDate' => $startDate, 'endDate' => $endDate]);
}
return new RedirectResponse($url);
}
return $this->render('@views/Default/lastLogin.html.twig', [
'user' => $user,
'form' => $form->createView()
]);
}
/**
* @Route(
* "super-admin/last-login-pdf/{startDate}/{endDate}",
* requirements={"startDate" = "\d{4}-\d{2}-\d{2}",
* "endDate" = "\d{4}-\d{2}-\d{2}"},
* name="last_login_pdf",
* options={"expose"=true}
* )
* @param DateTime $startDate
* @param DateTime|null $endDate
* @return PdfResponse
*/
public function lastLoginPdfAction(DateTime $startDate, ?DateTime $endDate = null): PdfResponse
{
$users = $this->userRepository->getLastLoginUsers($startDate, $endDate);
$html = $this->renderView('@views/Default/lastLoginPdf.html.twig', [
'users' => $users,
'startDate' => $startDate,
'endDate' => $endDate,
]);
return new PdfResponse($this->pdf, $html);
}
/**
* @Route(
* "super-admin/flats-import-list/{startDate}/{endDate}",
* requirements={"startDate" = "\d{4}-\d{2}-\d{2}",
* "endDate" = "\d{4}-\d{2}-\d{2}"},
* name="flats_import_list",
* options={"expose"=true}
* )
* @param DateTime $startDate
* @param DateTime|null $endDate
* @return PdfResponse
*/
public function flatImportPdfAction(DateTime $startDate, ?DateTime $endDate = null): PdfResponse
{
$users = $this->flatRepository->getFlatImportReviewByDate($startDate, $endDate);
$html = $this->renderView('@views/Default/flatsImportReport.html.twig', [
'users' => $users,
'startDate' => $startDate,
'endDate' => $endDate,
]);
return new PdfResponse($this->pdf, $html);
}
}