<?php
namespace App\Controller\Web;
use App\Entity\BillPayment;
use App\Entity\Building;
use App\Entity\BuildingPayment;
use App\Entity\Partners;
use App\Entity\ProcessedFiles;
use App\Entity\User;
use App\Enums\BillPaymentTypeEnum;
use App\Enums\BuildingPaymentTypeEnum;
use App\Enums\MoneyLogTypeEnum;
use App\Enums\OptionNameTypeEnum;
use App\Enums\ProcessedFilesStatusEnum;
use App\Form\BillOptionTransferType;
use App\Form\BillPaymentFondType;
use App\Form\BillPaymentType;
use App\Form\TransferredMoneyType;
use App\Repository\BillOptionsRepository;
use App\Repository\BillPaymentRepository;
use App\Repository\BuildingPaymentRepository;
use App\Repository\BuildingRepository;
use App\Repository\MoneyLogRepository;
use App\Repository\OptionNameRepository;
use App\Repository\PartnersRepository;
use App\Repository\ProcessedFilesRepository;
use App\Repository\SeparateBillOptionsRepository;
use App\Repository\UserRepository;
use App\Response\PdfResponse;
use App\Services\Authorization\BuildingPaymentAuthorizationService;
use App\Services\BillService;
use App\Services\DefaultService;
use App\Services\FlatService;
use App\Services\FondService;
use App\Services\OptionNameService;
use App\Services\PartnersService;
use App\Services\PaymentService;
use App\Services\ProcessService;
use App\Services\SummaryBalanceService;
use DateTime;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\ORMException;
use Exception;
use Knp\Snappy\Pdf;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class FondController extends AbstractController
{
private BuildingRepository $buildingRepository;
private DefaultService $defaultService;
private Pdf $pdf;
private BillService $billService;
private BillOptionsRepository $billOptionsRepository;
private BillPaymentRepository $billPaymentRepository;
private PartnersService $partnersService;
private OptionNameService $optionNameService;
private FondService $fondService;
private MoneyLogRepository $moneyLogRepository;
private PaymentService $paymentService;
private FlatService $flatService;
private BuildingPaymentRepository $buildingPaymentRepository;
private PartnersRepository $partnersRepository;
private ProcessService $processService;
private ProcessedFilesRepository $processedFilesRepository;
private SummaryBalanceService $summaryBalanceService;
private OptionNameRepository $optionNameRepository;
private UserRepository $userRepository;
private SeparateBillOptionsRepository $separateBillOptionsRepository;
/**
* @param BuildingRepository $buildingRepository
* @param BillOptionsRepository $billOptionsRepository
* @param BillPaymentRepository $billPaymentRepository
* @param MoneyLogRepository $moneyLogRepository
* @param BuildingPaymentRepository $buildingPaymentRepository
* @param PartnersRepository $partnersRepository
* @param ProcessedFilesRepository $processedFilesRepository
* @param DefaultService $defaultService
* @param PartnersService $partnersService
* @param OptionNameService $optionNameService
* @param FondService $fondService
* @param PaymentService $paymentService
* @param FlatService $flatService
* @param Pdf $pdf
* @param BillService $billService
* @param ProcessService $processService
* @param SummaryBalanceService $summaryBalanceService
* @param OptionNameRepository $optionNameRepository
* @param UserRepository $userRepository
* @param SeparateBillOptionsRepository $separateBillOptionsRepository
*/
public function __construct(
BuildingRepository $buildingRepository,
BillOptionsRepository $billOptionsRepository,
BillPaymentRepository $billPaymentRepository,
MoneyLogRepository $moneyLogRepository,
BuildingPaymentRepository $buildingPaymentRepository,
PartnersRepository $partnersRepository,
ProcessedFilesRepository $processedFilesRepository,
DefaultService $defaultService,
PartnersService $partnersService,
OptionNameService $optionNameService,
FondService $fondService,
PaymentService $paymentService,
FlatService $flatService,
Pdf $pdf,
BillService $billService,
ProcessService $processService,
SummaryBalanceService $summaryBalanceService,
OptionNameRepository $optionNameRepository,
UserRepository $userRepository,
SeparateBillOptionsRepository $separateBillOptionsRepository,
) {
$this->buildingRepository = $buildingRepository;
$this->defaultService = $defaultService;
$this->pdf = $pdf;
$this->billService = $billService;
$this->billOptionsRepository = $billOptionsRepository;
$this->billPaymentRepository = $billPaymentRepository;
$this->partnersService = $partnersService;
$this->optionNameService = $optionNameService;
$this->fondService = $fondService;
$this->moneyLogRepository = $moneyLogRepository;
$this->paymentService = $paymentService;
$this->flatService = $flatService;
$this->buildingPaymentRepository = $buildingPaymentRepository;
$this->partnersRepository = $partnersRepository;
$this->processService = $processService;
$this->processedFilesRepository = $processedFilesRepository;
$this->summaryBalanceService = $summaryBalanceService;
$this->optionNameRepository = $optionNameRepository;
$this->userRepository = $userRepository;
$this->separateBillOptionsRepository = $separateBillOptionsRepository;
}
/**
* @Route("/building/{bid}/tekuci-racun-card", name="tekuci_racun_card", options={"expose"=true})
* @param int $bid
*
* @return PdfResponse
* @throws NoResultException
* @throws NonUniqueResultException
*/
public function tekuciRacunCardCurrentAction(int $bid): PdfResponse
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
$tekuciArray = $this->billService->getPaymentsForTekuciRacunCardCurrentOptimized($building->getUser(), $building);
$html = $this->renderView('@views/Fond/tekuciRacunCardCurrent.html.twig', [
'data' => $tekuciArray,
'building' => $building
]);
return new PdfResponse($this->pdf, $html);
}
/**
* @Route(
* "/fond/dashboard/{id}/{type}",
* requirements={"id" = "\d+", "type" = "\d+"},
* name="fond_dashboard",
* defaults={"type" = null},
* options={"expose"=true}
* )
* @param int $id
* @param null $type
*
* @return Response
* @throws NonUniqueResultException
*/
public function fondDashboardAction(int $id, $type = null): Response
{
/** @var User $user */
$user = $this->getUser();
$companyUsers = $this->userRepository->findUsersByMain($user);
if ($user->getMainUser()) {
$companyUsers = array_merge($companyUsers, [$user->getMainUser()]);
}
/** @var Building $building */
$building = $this->buildingRepository->find($id);
$this->defaultService->checkEntity($building, $user);
$billOptions = $this->billOptionsRepository->getAllBillOptionsUntilNow($building);
$separateBillOptions = $this->separateBillOptionsRepository->getAllSeparateBillOptionsUntilNow($building);
$billPayments = $this->billPaymentRepository
->getPaymentsByBuildingAndIncome($building, BillPaymentTypeEnum::PRILIV->value);
$billPaymentNames = $this->billPaymentRepository->findAllTypesForBuilding($building, $user);
$partnerCards = $this->partnersService
->partnerCardsForBuilding($building->getUser(), $billOptions, $billPayments);
$billOptionsForCards = $this->optionNameService->filterOptionNameKeys(
array_merge($billOptions, $separateBillOptions, $billPaymentNames),
$building->getUser()
);
$billOptionsForCards[3] = 'Investicioni Fond';
$billOptionsForCards[4] = 'Tekući Fond';
$optionNames = $this->optionNameService->getOptionsNameKeys($building->getUser());
$optionNames[100] = 'Tekući račun';
$optionNames[50] = 'Stari dug';
if ($this->fondService->isTestUser($building->getUser()->getId())) {
$billOptionsForCards[150] = 'PREDHODNO Dugovanje';
$optionNames[150] = 'Predhodni dug';
}
$startDate = $this->billPaymentRepository->findOldestBillPaymentDateByBuilding($building);
if (!$startDate) {
$startDate = new DateTime();
$startDate->modify('-1YEAR');
}
$partners = $this->partnersRepository->getUsersPartners($companyUsers);
return $this->render('@views/Fond/fondDashboard.html.twig', [
'building' => $building,
'user' => $building->getUser(),
'optionName' => $optionNames,
'billOptionsForCards' => $billOptionsForCards,
'bid' => $type,
'partnerCards' => $partnerCards,
'startDate' => $startDate,
'partners' => $partners
]);
}
/**
* @Route("/building/{bid}/tekuci-racun-options", name="tekuci_racun_options", options={"expose"=true})
*
* @param int $bid
*
* @return Response
*/
public function tekuciRacunOptionsAction(int $bid): Response
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
return $this->render('@views/Fond/tekuciRacunOptions.html.twig', [
'building' => $building
]);
}
/**
* @Route("/building/{bid}/old-debit-finance-card", requirements={"id" = "\d+"}, name="old_debit_finance_card")
* @param int $bid
* @return PdfResponse
* @throws NoResultException
* @throws NonUniqueResultException
*/
public function olDebitFinanceAction(int $bid): PdfResponse
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
$payments = $this->billPaymentRepository
->getPaymentsByType($building, $building->getUser(), BillPayment::OLD_DEBIT_ID);
$oldDebits = $this->moneyLogRepository
->getMoneyLogByTypeWithFlat($building, $building->getUser(), [MoneyLogTypeEnum::OLD_DEBIT->value]);
$logs = $this->paymentService->getOldDebitFinanceLogs($oldDebits, $payments);
$debitSum = $this->flatService->getBuildingFlatsOldDebitSum($building->getUser(), $building);
$oldDebitPayments = $this->moneyLogRepository
->getMoneyLogByTypeWithFlat(
$building,
$building->getUser(),
[MoneyLogTypeEnum::OLD_DEBIT_PAYMENT->value, MoneyLogTypeEnum::OLD_DEBIT_SEPARATE_PAYMENT->value]
);
$subPaymentTotal = 0;
$paidTotal = 0;
foreach ($payments as $payment) {
if ($payment['income'] !== 0 && $payment['income'] !== 2) {
$paidTotal += $payment['value'];
}
}
foreach ($oldDebitPayments as $payment) {
$subPaymentTotal += $payment['amount'];
}
return new PdfResponse($this->pdf, $this->renderView('@views/Fond/oldDebitFinanceCard.html.twig', [
'logs' => $logs,
'debitSum' => $debitSum,
'subPaymentTotal' => $subPaymentTotal,
'building' => $building,
'paidTotal' => $paidTotal
]));
}
/**
* @Route("/building/{bid}/option-card/{bp}", name="bill_option_card")
*
* @param int $bp
* @param int $bid
*
* @return PdfResponse
* @throws Exception
*/
public function billOptionCardAction(int $bp, int $bid): PdfResponse
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
$information = $this->fondService->getBillOptionCardInformation($bp, $building);
return new PdfResponse($this->pdf, $this->renderView($information['view'], $information['data']));
}
/**
* @Route("/building/{bid}/new-option-card/{bp}", name="new_bill_option_card")
* @param int $bp
* @param int $bid
*
* @return mixed
* @throws NonUniqueResultException|Exception
*/
public function newBillOptionCardAction(int $bp, int $bid): mixed
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
$tmp = new DateTime();
$year = $tmp->format('Y');
$summaryBalance = $this->summaryBalanceService->getLastSummaryBalance($building, $bp);
if ($summaryBalance) {
$year = (string)((int)$summaryBalance->getYear() + 1);
}
// create start and end date
$date = new DateTime(sprintf('%s-01-01', $year));
$startDate = $date->format('Y-m-d');
$date = new DateTime("+2MONTH");
$endDate = $date->format('Y-m-01');
$information = $this->fondService->getBillOptionCardInformation($bp, $building, $startDate, $endDate, true);
return new PdfResponse($this->pdf, $this->renderView($information['view'], $information['data']));
}
/**
* @Route(
* "/add-new-fond/building/{buildingId}/{buildingPaymentId}",
* name="add_new_fond",
* defaults={"buildingPaymentId" = null},
* options={"expose"=true}
* )
*
* @param Request $request
* @param int $buildingId
* @param int|null $buildingPaymentId
*
* @return Response
* @throws NoResultException
* @throws NonUniqueResultException
* @throws ORMException
*/
public function addNewFondAction(Request $request, int $buildingId, ?int $buildingPaymentId): Response
{
/** @var User $user */
$user = $this->getUser();
$companyUsers = $this->userRepository->findUsersByMain($user);
if ($user->getMainUser()) {
$companyUsers = array_merge($companyUsers, [$user->getMainUser()]);
}
$buildingPayment = $buildingPaymentId ?
$this->buildingPaymentRepository->find($buildingPaymentId) :
null;
if ($buildingPaymentId !== null) {
$buildingPaymentAuthorizationService = new BuildingPaymentAuthorizationService($buildingPayment, $user);
if (!$buildingPaymentAuthorizationService->authorize()) {
throw $this->createNotFoundException('Building payment not found');
}
}
$processedFile = $buildingPayment?->getProcessedFile();
//$payment = json_decode($request->query->get('data'), true);
$payment = $buildingPayment !== null ? $buildingPayment->getParsedData() : [];
/** @var Building $building */
$building = $this->buildingRepository->find($buildingId);
$this->defaultService->checkEntity($building, $user);
$options = $this->optionNameService->getBillPaymentOdlivOptions($building->getUser(), $building);
$billPayment = new BillPayment();
$date = null;
$description = '';
if (!empty($payment)) {
$billPayment->setValue($payment['amount']);
$billPayment->setBankFileId($processedFile->getBankFileId());
$date = $payment['date'] ?? null;
$description = $payment['description'] ?? '';
}
$partners = $this->partnersRepository->getUsersPartners($companyUsers);
$form = $this->createForm(
BillPaymentType::class,
$billPayment,
[
'action' => $this->generateUrl(
'add_new_fond',
['buildingId' => $buildingId, 'buildingPaymentId' => $buildingPaymentId]
),
'attr' => [
'typeChose' => json_encode($options),
'date' => $date,
'isTestUser' => $this->fondService->isTestUser($building->getUser()->getId()),
'user' => $building->getUser()->getId(),
'buildingPaymentAmount' => $buildingPayment?->getAmount(),
'bankFileId' => $processedFile?->getBankFileId(),
'description' => $description
],
'method' => 'POST',
'partners' => $partners
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$arr = $this->fondService->createNewFond($form, $building);
$amount = $arr['amount'];
$minusUsersHaveNegativeBalance = $arr['minusUsersHaveNegativeBalance'];
$message = $arr['message'];
if (!$minusUsersHaveNegativeBalance && $billPayment->getValue() > $amount) {
$this->addFlash(
'error',
$message
);
return $this->render('@views/Fond/addNewFond.html.twig', [
'building' => $building,
'id' => $buildingId,
'form' => $form->createView(),
'payment' => $payment,
'processedFile' => $processedFile
]);
}
if ($minusUsersHaveNegativeBalance) {
$this->addFlash('warning', "Vaš fond je u minusu.");
}
$this->billPaymentRepository->save($billPayment);
if ($buildingPayment !== null) {
$buildingPayment->setProcessed(true);
$buildingPayment->setBillPayment($billPayment);
$this->buildingPaymentRepository->save($buildingPayment);
$parser = $this->processService->getParser($processedFile->getBankName());
$parsedData = $parser->parseFile($this->getParameter('bank_notification_directory'), $processedFile);
$parsedData['flats'] = $parsedData['flats'] ?? [];
if (
$this->buildingPaymentRepository->areAllOutflowsProcessed($processedFile) &&
($processedFile->getProcessedFlats()->count() + $this->buildingPaymentRepository->getBuildingPaymentsCountByType($processedFile, 1)) === count($parsedData['flats'])
) {
$processedFile->setStatus(ProcessedFilesStatusEnum::PROCESSED_FILE->value);
} else {
$processedFile->setStatus(ProcessedFilesStatusEnum::PARTIALLY_PROCESSED_FILE->value);
}
$this->processedFilesRepository->save($processedFile);
$url = $this->generateUrl(
'show_statement',
['buildingId' => $buildingId, 'fileId' => $processedFile->getId()]
);
} else {
$url = $this->generateUrl('fond_dashboard', ['id' => $buildingId]);
}
return new RedirectResponse($url);
}
$params['form'] = $form->createView();
$params['id'] = $buildingId;
$params['payment'] = $payment;
$params['processedFile'] = $processedFile;
$params['building'] = $building;
return $this->render('@views/Fond/addNewFond.html.twig', $params);
}
/**
* @Route(
* "/add-new-fond-prilivi/{id}/{date}",
* requirements={"id" = "\d+", "date" = "\d{4}-\d{2}-\d{2}"},
* defaults={"date" = null},
* name="add_new_fond_prilivi",
* options={"expose"=true}
* )
*
* @param Request $request
* @param int $id
* @param string|null $date
*
* @return Response
* @throws Exception
*/
public function addNewFondActionPrilivi(
Request $request,
int $id,
?string $date,
): Response {
$options = [
'Investicioni Fond' => OptionNameTypeEnum::INV_FOND_OP_ID->name,
'Tekući Fond' => OptionNameTypeEnum::TEK_FOND_OP_ID->name
];
$bankDataJson = $request->query->get('data');
$bankData = json_decode($bankDataJson, true);
/** @var User $user */
$user = $this->getUser();
$companyUsers = $this->userRepository->findUsersByMain($user);
if ($user->getMainUser()) {
$companyUsers = array_merge($companyUsers, [$user->getMainUser()]);
}
/** @var Building $building */
$building = $this->buildingRepository->find($id);
$this->defaultService->checkEntity($building, $user);
$partners = $this->partnersRepository->getUsersPartners($companyUsers);
$optionNames = $this->optionNameRepository->getOptionNameByTypeIO(
[$building->getUser()->getMainUser() ?? $building->getUser()->getId()]
);
$billOptions = $this->billOptionsRepository->getAllBillOptionsUntilNow($building);
$separateBillOptions = $this->separateBillOptionsRepository->getAllSeparateBillOptionsUntilNow($building);
$billPaymentNames = $this->billPaymentRepository->findAllTypesForBuilding($building, $building->getUser());
$billOptionsForCards = $this->optionNameService->filterOptionNameKeys(
array_merge($billOptions, $separateBillOptions, $billPaymentNames),
$building->getUser()
);
$filteredOptionNames = [];
foreach ($optionNames as $item) {
if (in_array($item['name'], $billOptionsForCards)) {
$filteredOptionNames[$item['name']] = $item['id'];
}
}
$month = null;
if ($date) {
$month = new DateTime($date);
$params = $this->billOptionsRepository->getBillOptions($id, $month->format('y-m-01'));
$optionName = $this->optionNameService->getOptionsNameKeys($building->getUser());
foreach ($params as $param) {
$options[$optionName[$param['name']]] = $param['name'];
}
}
$billPayment = new BillPayment();
$date = null;
$description = '';
if ($bankData) {
$billPayment->setValue($bankData['amount']);
$billPayment->setBankFileId($bankData['bankDailyCheckPoint']);
$date = $bankData['date'] ?? null;
$description = $bankData['description'] ?? '';
}
$form = $this->createForm(
BillPaymentFondType::class,
$billPayment,
[
'action' => $this->generateUrl('add_new_fond_prilivi', ['id' => $id, 'date' => $date]),
'attr' => [
'typeChose' => json_encode($options),
'date' => $date,
'isTestUser' => $this->fondService->isTestUser($building->getUser()->getId()),
'description' => $description,
],
'method' => 'POST',
'partners' => $partners,
'optionNames' => $filteredOptionNames,
'bankDataJson' => $bankDataJson
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$bankDataRaw = $form->get('bankDataJson')->getData();
$bankDataJson = $bankDataRaw ? json_decode($bankDataRaw, true) : null;
$billPayment = $this->fondService->createNewFondPrilivi($form, $building, $date, $month);
if ($bankDataJson) {
/** @var ProcessedFiles $processedFile */
$processedFile = $this->processedFilesRepository->findOneBy(['id' => $bankDataJson['id']]);
$buildingPayment = new BuildingPayment();
$buildingPayment->setAmount($bankDataJson['amount']);
$buildingPayment->setProcessedFiles($processedFile);
$buildingPayment->setParsedData($bankDataJson);
$buildingPayment->setTransactionId($bankDataJson['transactionId']);
$buildingPayment->setType(BuildingPaymentTypeEnum::TYPE_INCOME->value);
$buildingPayment->setBillPayment($billPayment);
$buildingPayment->setProcessed(true);
$processedFile->setNumberOfNotProcessedFiles($processedFile->getNumberOfNotProcessedFiles() - 1);
$this->buildingPaymentRepository->save($buildingPayment);
$parser = $this->processService->getParser($processedFile->getBankName());
$parsedData = $parser->parseFile($this->getParameter('bank_notification_directory'), $processedFile);
if (
$this->buildingPaymentRepository->areAllOutflowsProcessed($processedFile) &&
($processedFile->getProcessedFlats()->count() + $this->buildingPaymentRepository->getBuildingPaymentsCountByType($processedFile, 1)) === count($parsedData['flats'])
) {
$processedFile->setStatus(ProcessedFilesStatusEnum::PROCESSED_FILE->value);
} else {
$processedFile->setStatus(ProcessedFilesStatusEnum::PARTIALLY_PROCESSED_FILE->value);
}
$this->processedFilesRepository->save($processedFile);
$url = $this->generateUrl('show_statement', ['buildingId' => $building->getId(), 'fileId' => $processedFile->getId()]);
} else {
$url = $this->generateUrl('fond_dashboard', ['id' => $id]);
}
return new RedirectResponse($url);
}
$params['form'] = $form->createView();
$params['id'] = $id;
$params['partnersListCount'] = $this->partnersRepository->getPartnersCountByUser($user);
$params['building'] = $building;
return $this->render('@views/Fond/addNewFondPrilivi.html.twig', $params);
}
/**
* @Route(
* "/building/{id}/bill-option-transfer/old-debit",
* requirements={"id" = "\d+"},
* name="bill_option_transfer_old_debit"
* )
*
* @param int $id
* @param Request $request
*
* @return Response
* @throws NoResultException
* @throws NonUniqueResultException
*/
public function billOptionTransferAction(int $id, Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($id);
$this->defaultService->checkEntity($building, $user);
$billOptionsUntilNow = $this->billOptionsRepository->getAllBillOptionsUntilNow($building);
$separateBillOptions = $this->separateBillOptionsRepository->getAllSeparateBillOptionsUntilNow($building);
$optionNames = $this->optionNameService->getBillOptionsFilteredNameKeys(
array_merge($billOptionsUntilNow, $separateBillOptions),
$building->getUser()
);
// $optionNames[100] = "Tekući račun";
// $optionNames[BillPayment::OLD_DEBIT_ID] = 'Stari dug';
$optionNamesForTransfer = $this->billService->getBillOptionsForTransfer(
$optionNames,
$building->getUser(),
$building
);
$form = $this->createForm(
BillOptionTransferType::class,
[],
[
'method' => 'POST',
'choices' => array_flip($optionNamesForTransfer)
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$amount = $form->getData()['amount'];
$sender = (int)$form->getData()['sender'];
$reciever = (int)$form->getData()['reciever'];
$createdAt = $form->getData()['createdAt'];
$fond = $this->paymentService->getAmountByBuilding($building->getUser(), $building, [$sender])[$sender];
$message = 'Nemate dovoljno sredstava da izvršite ovu pozajmicu.';
// $fond = $this->paymentService->getAmountByBuilding($building->getUser(), $building, [$sender])[$sender];
// $message = 'Nemate dovoljno sredstava u fondu da izvršite ovu pozajmicu.';
//
// if ($sender === 100) {
// $fond = $this->billService->getPaymentsForTekuciRacunCard($building->getUser(), $building)['saldo'];
// $message = 'Nemate dovoljno sredstava na tekućem računu da izvršite ovu pozajmicu.';
// } elseif ($sender === 50) {
// $message = 'Nemate dovoljno sredstava da izvršite ovu pozajmicu.';
// }
if ($amount > $fond) {
$this->addFlash(
'error',
$message
);
return $this->render('@views/Bill/billOptionTransfer.html.twig', [
'building' => $building,
'id' => $id,
'form' => $form->createView()
]);
}
if ($sender == $reciever) {
$this->addFlash(
'error',
'Nije dozvoljeno prebacivanje sredstava sa jedne opcije na tu istu.'
);
return $this->render('@views/Bill/billOptionTransfer.html.twig', [
'building' => $building,
'id' => $id,
'form' => $form->createView()
]);
}
$this->paymentService->optionTransfer(
$building->getUser(),
$building,
$optionNames,
$sender,
$reciever,
$amount,
$createdAt
);
return new RedirectResponse($this->generateUrl('fond_dashboard', ['id' => $building->getId()]));
}
return $this->render('@views/Bill/billOptionTransfer.html.twig', [
'building' => $building,
'id' => $id,
'form' => $form->createView()
]);
}
/**
* @Route(
* "/building/{bid}/tekuci-racun-card-last-year",
* name="tekuci_racun_card_last_year",
* options={"expose"=true}
* )
* @param int $bid
*
* @return PdfResponse
* @throws Exception
*/
public function tekuciRacunCardLastYearAction(int $bid): PdfResponse
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
$startDateOBJ = new DateTime("-12MONTH");
$startDate = $startDateOBJ->format("Y-m-d");
$endDateOBJ = new DateTime();
$endDate = $endDateOBJ->format('Y-m-d');
$tekuciArray = $this->billService
->getPaymentsForTekuciRacunCardForPeriod($building->getUser(), $building, $startDate, $endDate);
return new PdfResponse($this->pdf, $this->renderView('@views/Fond/tekuciRacunForPeriod.html.twig', [
'data' => $tekuciArray,
'building' => $building,
'forPeriod' => "false"
]));
}
/**
* @Route(
* "/building/{bid}/all",
* name="tekuci_racun_card_all"
* )
* @param int $bid
*
* @return PdfResponse
* @throws Exception
*/
public function tekuciRacunCardAllAction(int $bid): PdfResponse
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
$startDateOBJ = new DateTime("-120MONTH");
$startDate = $startDateOBJ->format("Y-m-d");
$endDateOBJ = new DateTime();
$endDate = $endDateOBJ->format('Y-m-d');
$tekuciArray = $this->billService
->getPaymentsForTekuciRacunCardForPeriod($building->getUser(), $building, $startDate, $endDate);
return new PdfResponse($this->pdf, $this->renderView('@views/Fond/tekuciRacunForPeriod.html.twig', [
'data' => $tekuciArray,
'building' => $building,
'forPeriod' => "false"
]));
}
/**
* @Route(
* "/fond/prilivi/updated-partners-list",
* name="updated_partners_list",
* options={"expose"=true},
* methods={"GET"}
* )
* @return JsonResponse
* @throws NonUniqueResultException
* @throws NoResultException
*/
public function getUpdatedListOfPartners(): JsonResponse
{
/** @var User $user */
$user = $this->getUser();
$response = [
'partnersListCount' => $this->partnersRepository->getPartnersCountByUser($user),
'newPartner' => $this->partnersRepository->getLastAddedPartnerByUser($user),
'success' => true
];
return new JsonResponse($response);
}
/**
* @Route(
* "/fond/dashboard/datatable/{building}/{type}",
* requirements={"id" = "\d+"},
* name="datatable_fond_dashboard",
* defaults={"type" = null},
* options={"expose"=true}
* )
* @param Request $request
* @param Building $building
* @param mixed $type
*
* @return JsonResponse
*/
public function datatableFondsInputAction(Request $request, Building $building, mixed $type): JsonResponse
{
return $this->defaultService->datatablePagination(
$request,
BillPayment::class,
'findBillPaymentInputsArrayForFondDatatable',
[
'user' => $building->getUser(),
'building' => $building,
'income' => $request->get('income'),
'type' => $type
]
);
}
/**
* @Route(
* "/building/{id}/fond/{fondId}/edit-fond-priliv",
* requirements={"id" = "\d+", "fondId" = "\d+"},
* name="edit_fond_priliv",
* options={"expose"=true}
* )
* @param Request $request
* @param int $id
* @param int $fondId
*
* @return Response
* @throws ORMException
*/
public function editFondPrilivAction(Request $request, int $id, int $fondId): Response
{
/** @var User $user */
$user = $this->getUser();
$companyUsers = $this->userRepository->findUsersByMain($user);
if ($user->getMainUser()) {
$companyUsers = array_merge($companyUsers, [$user->getMainUser()]);
}
/** @var Building $building */
$building = $this->buildingRepository->find($id);
$this->defaultService->checkEntity($building, $user);
$partners = $this->partnersRepository->getUsersPartners($companyUsers);
$optionNames = $this->optionNameRepository->getOptionNameByTypeIO(
[$building->getUser()->getMainUser() ?? $building->getUser()->getId()]
);
$billOptions = $this->billOptionsRepository->getAllBillOptionsUntilNow($building);
$separateBillOptions = $this->separateBillOptionsRepository->getAllSeparateBillOptionsUntilNow($building);
$billPaymentNames = $this->billPaymentRepository->findAllTypesForBuilding($building, $building->getUser());
$billOptionsForCards = $this->optionNameService->filterOptionNameKeys(
array_merge($billOptions, $billPaymentNames, $separateBillOptions),
$building->getUser()
);
$filteredOptionNames = [];
foreach ($optionNames as $item) {
if (in_array($item['name'], $billOptionsForCards)) {
$filteredOptionNames[$item['name']] = $item['id'];
}
}
/** @var BillPayment|null $billPayment */
$billPayment = $this->billPaymentRepository->find($fondId);
if (empty($billPayment)) {
throw $this->createNotFoundException('Unable to find Bill payment entity.');
}
if ($billPayment->getPartner() != null) {
$billPayment->setPartner($billPayment->getPartner());
}
$form = $this->createForm(
BillPaymentFondType::class,
$billPayment,
[
'attr' => [
'date' => $billPayment->getCreatedAt()->format('Y-m-d'),
'currentOption' => $billPayment->getType(),
'isTestUser' => $this->fondService->isTestUser($building->getUser()->getId()),
'currentPartner' => $billPayment->getPartner()?->getId(),
],
'partners' => $partners,
'optionNames' => $filteredOptionNames,
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$billPayment = $form->getData();
$partnerId = $form->get('partner')->getData();
$partner = null;
if ($partnerId) {
$partner = $this->partnersRepository->find($partnerId);
}
$billPayment->setUser($building->getUser());
$billPayment->setBuilding($building);
$billPayment->setUpdateAt(new DateTime());
$billPayment->setIncome(BillPaymentTypeEnum::PRILIV->value);
$billPayment->setPartner($partner);
$this->billPaymentRepository->save($billPayment);
return new RedirectResponse($this->generateUrl('fond_dashboard', ['id' => $id]));
}
$params['form'] = $form->createView();
$params['id'] = $id;
$params['partnersListCount'] = $this->partnersRepository->getPartnersCountByUser($user);
$params['building'] = $building;
return $this->render('@views/Fond/addNewFondPrilivi.html.twig', $params);
}
/**
* @Route(
* "/building/{id}/fond/{fondId}/edit-fond-odliv",
* requirements={"id" = "\d+", "fondId" = "\d+"},
* name="edit_fond_odliv",
* options={"expose"=true}
* )
* @param Request $request
* @param int $id
* @param int $fondId
*
* @return Response
* @throws NonUniqueResultException
* @throws ORMException
*/
public function editFondOdlivAction(Request $request, int $id, int $fondId): Response
{
/** @var User $user */
$user = $this->getUser();
$companyUsers = $this->userRepository->findUsersByMain($user);
if ($user->getMainUser()) {
$companyUsers = array_merge($companyUsers, [$user->getMainUser()]);
}
/** @var Building $building */
$building = $this->buildingRepository->find($id);
$this->defaultService->checkEntity($building, $user);
$options = $this->optionNameService->getBillPaymentOdlivOptions($building->getUser(), $building);
$partners = $this->partnersRepository->getUsersPartners($companyUsers);
/** @var BillPayment|null $billPayment */
$billPayment = $this->billPaymentRepository->find($fondId);
if (empty($billPayment)) {
throw $this->createNotFoundException('Unable to find Bill payment entity.');
}
if ($billPayment->getPartner() != null) {
$billPayment->setPartner($billPayment->getPartner());
}
$form = $this->createForm(BillPaymentType::class, $billPayment, [
'attr' => [
'typeChose' => json_encode($options),
'date' => $billPayment->getCreatedAt()->format('Y-m-d'),
'isTestUser' => $this->fondService->isTestUser($building->getUser()->getId()),
'user' => $building->getUser()->getId(),
'description' => $billPayment->getComment()
],
'method' => 'POST',
'partners' => $partners
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$billPayment->setUser($building->getUser());
$billPayment->setBuilding($building);
$billPayment->setUpdateAt(new DateTime());
$billPayment->setType($form->getData()->getType());
$billPayment->setIncome(BillPaymentTypeEnum::ODLIV->value);
$partner = $this->partnersRepository->getPartnerByPartnerId(
$user,
$form->getData()->getPartner()?->getId()
);
$billPayment->setPartner($partner);
$this->billPaymentRepository->save($billPayment);
return new RedirectResponse($this->generateUrl('fond_dashboard', ['id' => $id]));
}
return $this->render('@views/Fond/addNewFond.html.twig', [
'building' => $building,
'id' => $id,
'form' => $form->createView(),
'payment' => []
]);
}
/**
* @Route("/transferred-money/{id}", name="transferred_money", options={"expose"=true})
* @param Request $request
* @param int $id
* @param null $saldo
*
* @return Response
*/
public function transferredMoney(Request $request, int $id, $saldo = null): Response
{
$saldo = $request->get('saldo');
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($id);
$this->defaultService->checkEntity($building, $user);
$optionNames = $this->optionNameService->getOptionsNameKeys($building->getUser());
$statistics = $this->billService->getLastYearStatistics2($building->getUser(), $building);
$options = $statistics['fields'];
$obr = 0;
$npl = 0;
$choices = [];
foreach ($options as $option) {
$choices[$optionNames[$option]] = $option;
}
$form = $this->createForm(
TransferredMoneyType::class,
[],
[
'method' => 'POST',
'choices' => $choices
]
);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$optionsName = $form->getData();
$countObr = count($statistics['obr']);
foreach ($statistics['obr'] as $payment) {
if (--$countObr <= 0) {
break;
}
foreach ($payment as $key => $pay) {
if (in_array($key, $optionsName['options'])) {
$obr += $pay;
}
}
}
foreach ($statistics['npl'] as $payment) {
foreach ($payment as $key => $pay) {
if (in_array($key, $optionsName['options'])) {
$npl += $pay;
}
}
}
$saldo = $obr - $npl;
$url = $this->generateUrl('transferred_money', ['id' => $id, 'saldo' => $saldo]);
return new RedirectResponse($url);
}
$params['saldo'] = $saldo;
$params['building'] = $building;
$params['form'] = $form->createView();
return $this->render('@views/Fond/transferredMoney.html.twig', $params);
}
/**
* @Route("/building/{bid}/tekuci-racun-card-period", name="tekuci_racun_card_period", options={"expose"=true})
* @param Request $request
* @param int $bid
*
* @return PdfResponse|string
* @throws Exception
*/
public function tekuciRacunCardForPeriodAction(Request $request, int $bid): PdfResponse|string
{
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
$dateFrom = $request->get('dateFrom');
$dateTo = $request->get('dateTo');
$dateFromObj = new DateTime($dateFrom);
$dateToObj = new DateTime($dateTo);
if ($dateFromObj >= $dateToObj) {
return $this->pdf->getOutputFromHtml(
'<h2>Niste uneli validne podatke. <br/> Pokusajte ponovo sa drugim podacima!</h2>'
);
}
if (date_diff($dateToObj, $dateFromObj)->days > 366) {
return $this->pdf->getOutputFromHtml(
'<h2>Izabrani period je duzi od 12 meseci. <br/> Pokusajte ponovo sa drugim podacima!</h2>'
);
}
$tekuciArray = $this->billService->getPaymentsForTekuciRacunCardForPeriod(
$building->getUser(),
$building,
$dateFrom,
$dateTo
);
return new PdfResponse($this->pdf, $this->renderView('@views/Fond/tekuciRacunForPeriod.html.twig', [
'data' => $tekuciArray,
'building' => $building,
'dateFrom' => $dateFrom,
'dateTo' => $dateTo,
'forPeriod' => "true"
]));
}
/**
* @Route("/building/{bid}/fond/{fid}", name="fond_delete", options={"expose"=true}, methods={"DELETE"})
* @param Request $request
* @param int $bid
* @param int $fid
*
* @return JsonResponse
*/
public function deleteFondAction(
Request $request,
int $bid,
int $fid,
): JsonResponse {
/** @var User $user */
$user = $this->getUser();
/** @var Building $building */
$building = $this->buildingRepository->find($bid);
$this->defaultService->checkEntity($building, $user);
/** @var BillPayment|null $billPayment */
$billPayment = $this->billPaymentRepository->findOneBy(
['id' => $fid, 'building' => $building, 'user' => $building->getUser()]
);
if (!$billPayment) {
throw $this->createNotFoundException(
sprintf("Greska. Nema zapisa sa ovim id-jem: %s", $fid)
);
}
$form = $this->createDeleteForm($billPayment, $bid, ['delete' => 'delete']);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($buildingPayment = $billPayment->getBuildingPayment()) {
$buildingPayment->setProcessed(false);
$this->buildingPaymentRepository->save($buildingPayment);
$processedFile = $buildingPayment->getProcessedFile();
$processedBuildingPayments = 0;
/** @var BuildingPayment $buildingPayment */
foreach ($processedFile->getBuildingPayments() as $buildingPayment) {
if ($buildingPayment->isProcessed()) {
$processedBuildingPayments++;
}
}
if ($processedFile->getProcessedFlats()->count() === 0 && $processedBuildingPayments === 0) {
$processedFile->setStatus(ProcessedFilesStatusEnum::ERROR_PROCESSED_FILE->value);
} else {
$processedFile->setStatus(ProcessedFilesStatusEnum::PARTIALLY_PROCESSED_FILE->value);
}
$this->processedFilesRepository->save($processedFile);
}
$this->billPaymentRepository->remove($billPayment);
return new JsonResponse(['success' => true]);
}
return new JsonResponse([
'html' => $this->renderView('@views\Fond\billPaymentDelete.html.twig', ['form' => $form->createView()]),
'success' => true
]);
}
/**
* @param BillPayment $entity
* @param int $bid
* @param array<string, string> $deleteOpt
*
* @return FormInterface
*/
public function createDeleteForm(BillPayment $entity, int $bid, array $deleteOpt): FormInterface
{
$entityForm['value'] = $entity->getValue();
$entityForm['type'] = $entity->getType();
$entityForm['comment'] = $entity->getComment();
$entityForm['income'] = $entity->getIncome();
$entityForm['typeForm'] = null;
$form = $this->createForm(BillPaymentType::class, $entityForm, [
'action' => $this->generateUrl('fond_delete', ['bid' => $bid, 'fid' => $entity->getId()]),
'attr' => [
'id' => 'deleteFondEntry'
],
'method' => 'DELETE',
'deleteOpt' => $deleteOpt
]);
$form->add('delete', SubmitType::class, ['label' => 'Obrisati', 'attr' => ['class' => 'btn']]);
return $form;
}
/**
* @Route(
* "/building/{bid}/fond_pdf_period/{startDay}/{endDay}/{income}/{partnerId?}",
* name="fond_pdf_period",
* options={"expose"=true}
* )
* @param int $bid
* @param string $startDay
* @param string $endDay
* @param int $income
* @param int|null $partnerId
* @return PdfResponse|string
* @throws Exception
*/
public function findPaymentsForPdfForBillPayment(
int $bid,
string $startDay,
string $endDay,
int $income,
?int $partnerId
): PdfResponse|string {
/** @var User $user */
$user = $this->getUser();
$partner = null;
if ($partnerId) {
/** @var Partners $partner */
$partner = $this->partnersRepository->findOneBy(['id' => $partnerId]);
}
$building = $this->buildingRepository->findOneBy(['id' => $bid]);
$payments = $this->billPaymentRepository
->findBillPaymentsForPdf($building, $startDay, $endDay, $income, $partner);
return new PdfResponse($this->pdf, $this->renderView('@views/Fond/billOptionCardPdf.html.twig', [
'payments' => $payments,
'building' => $building,
'type' => $income,
'dateTo' => $endDay,
'dateFrom' => $startDay
]));
}
}