240 lines
9.0 KiB
PHP
240 lines
9.0 KiB
PHP
<?php namespace RVR\Controller;
|
|
|
|
use Container;
|
|
use DateTime;
|
|
use RVR\Finance\ExchangeRateCalculator;
|
|
use RVR\PersistentData\Model\Community;
|
|
use RVR\PersistentData\Model\CommunityMember;
|
|
use RVR\PersistentData\Model\Transaction;
|
|
use RVR\PersistentData\Model\TransactionPayee;
|
|
use RVR\PersistentData\Model\User;
|
|
use RVR\Repository\CommunityMemberRepository;
|
|
use RVR\Repository\CommunityRepository;
|
|
use RVR\Repository\CurrencyRepository;
|
|
use RVR\Repository\TransactionRepository;
|
|
use RVR\Repository\TransactionPayeeRepository;
|
|
use RVR\Repository\EventRepository;
|
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
|
use SokoWeb\Interfaces\Authorization\ISecured;
|
|
use SokoWeb\Interfaces\Response\IContent;
|
|
use SokoWeb\Response\HtmlContent;
|
|
use SokoWeb\Response\JsonContent;
|
|
|
|
class TransactionController implements IAuthenticationRequired, ISecured
|
|
{
|
|
private CommunityRepository $communityRepository;
|
|
|
|
private CommunityMemberRepository $communityMemberRepository;
|
|
|
|
private CurrencyRepository $currencyRepository;
|
|
|
|
private TransactionRepository $transactionRepository;
|
|
|
|
private TransactionPayeeRepository $transactionPayeeRepository;
|
|
|
|
private EventRepository $eventRepository;
|
|
|
|
private ?Community $community;
|
|
|
|
private ?CommunityMember $ownCommunityMember;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->communityRepository = new CommunityRepository();
|
|
$this->communityMemberRepository = new CommunityMemberRepository();
|
|
$this->currencyRepository = new CurrencyRepository();
|
|
$this->transactionRepository = new TransactionRepository();
|
|
$this->transactionPayeeRepository = new TransactionPayeeRepository();
|
|
$this->eventRepository = new EventRepository();
|
|
}
|
|
|
|
public function isAuthenticationRequired(): bool
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public function authorize(): bool
|
|
{
|
|
$communitySlug = \Container::$request->query('communitySlug');
|
|
$this->community = $this->communityRepository->getBySlug($communitySlug);
|
|
if ($this->community === null) {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @var User $user
|
|
*/
|
|
$user = \Container::$request->user();
|
|
$this->ownCommunityMember = $this->communityMemberRepository->getByCommunityAndUser($this->community, $user);
|
|
if ($this->ownCommunityMember === null) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getTransactions(): IContent
|
|
{
|
|
Container::$persistentDataManager->loadRelationsFromDb($this->community, true, ['main_currency']);
|
|
$exchangeRateCalculator = new ExchangeRateCalculator($this->community->getMainCurrency());
|
|
|
|
$eventSlug = Container::$request->query('event');
|
|
if ($eventSlug) {
|
|
$event = $this->eventRepository->getBySlug($eventSlug);
|
|
} else {
|
|
$event = null;
|
|
}
|
|
|
|
$itemsPerPage = 50;
|
|
$numberOfTransactions = $event ?
|
|
$this->transactionRepository->countAllByEvent($event) :
|
|
$this->transactionRepository->countAllByCommunity($this->community);
|
|
$currentPage = Container::$request->query('page') ?: 1;
|
|
$transactions = $event ?
|
|
$this->transactionRepository->getPagedByEvent(
|
|
$event,
|
|
$currentPage,
|
|
$itemsPerPage,
|
|
true,
|
|
['currency', 'payer_user']
|
|
) :
|
|
$this->transactionRepository->getPagedByCommunity(
|
|
$this->community,
|
|
$currentPage,
|
|
$itemsPerPage,
|
|
true,
|
|
['event', 'currency', 'payer_user']
|
|
);
|
|
|
|
$transactions = iterator_to_array($transactions);
|
|
Container::$persistentDataManager->loadMultiRelationsFromDb($transactions, 'payees', true, ['user']);
|
|
|
|
return new HtmlContent('communities/transactions', [
|
|
'community' => $this->community,
|
|
'event' => $event,
|
|
'exchangeRateCalculator' => $exchangeRateCalculator,
|
|
'pages' => ceil($numberOfTransactions / $itemsPerPage),
|
|
'currentPage' => $currentPage,
|
|
'numberOfTransactions' => $numberOfTransactions,
|
|
'transactions' => $transactions,
|
|
'members' => $this->getMembers($this->community)
|
|
]);
|
|
}
|
|
|
|
public function getTransactionEdit(): ?IContent
|
|
{
|
|
$transactionId = Container::$request->query('transactionId');
|
|
if ($transactionId) {
|
|
$transaction = $this->transactionRepository->getById($transactionId);
|
|
if ($transaction === null) {
|
|
return null;
|
|
}
|
|
Container::$persistentDataManager->loadRelationsFromDb($transaction, false, ['event']);
|
|
$event = $transaction->getEvent();
|
|
$payeeUserIds = [];
|
|
foreach ($this->transactionPayeeRepository->getAllByTransaction($transaction) as $payee) {
|
|
$payeeUserIds[] = $payee->getUserId();
|
|
}
|
|
} else {
|
|
$transaction = null;
|
|
$eventSlug = Container::$request->query('event');
|
|
if ($eventSlug) {
|
|
$event = $this->eventRepository->getBySlug($eventSlug);
|
|
} else {
|
|
$event = null;
|
|
}
|
|
$payeeUserIds = [];
|
|
}
|
|
|
|
return new HtmlContent('communities/transaction_edit', [
|
|
'community' => $this->community,
|
|
'transaction' => $transaction,
|
|
'payeeUserIds' => $payeeUserIds,
|
|
'event' => $event,
|
|
'members' => $this->getMembers($this->community),
|
|
'currencies' => $this->getCurrencies($this->community)
|
|
]);
|
|
}
|
|
|
|
public function saveTransaction(): ?IContent
|
|
{
|
|
$transactionId = Container::$request->query('transactionId');
|
|
if ($transactionId) {
|
|
$transaction = $this->transactionRepository->getById($transactionId);
|
|
} else {
|
|
$transaction = new Transaction();
|
|
$transaction->setCommunity($this->community);
|
|
}
|
|
|
|
$transaction->setEventId(Container::$request->post('event_id') ?: null);
|
|
$transaction->setCurrencyId(Container::$request->post('currency_id'));
|
|
$transaction->setPayerUserId(Container::$request->post('payer_user_id'));
|
|
$transaction->setDescription(Container::$request->post('description'));
|
|
$transaction->setSum(Container::$request->post('sum'));
|
|
$transaction->setTimeDate(new DateTime(Container::$request->post('time')));
|
|
Container::$persistentDataManager->saveToDb($transaction);
|
|
|
|
$payeeUserIds = array_unique(Container::$request->post('payee_user_ids'));
|
|
if (count($payeeUserIds) === $this->communityMemberRepository->countAllByCommunity($this->community)) {
|
|
$payeeUserIds = [];
|
|
}
|
|
|
|
$currentPayees = [];
|
|
foreach ($payeeUserIds as $payeeUserId) {
|
|
$payee = new TransactionPayee();
|
|
$payee->setTransaction($transaction);
|
|
$payee->setUserId((int)$payeeUserId);
|
|
$currentPayees[(int)$payeeUserId] = $payee;
|
|
}
|
|
$existingPayees = [];
|
|
if ($transactionId) {
|
|
foreach ($this->transactionPayeeRepository->getAllByTransaction($transaction) as $payee) {
|
|
$existingPayees[$payee->getUserId()] = $payee;
|
|
}
|
|
}
|
|
|
|
foreach (array_diff_key($currentPayees, $existingPayees) as $newPayee) {
|
|
Container::$persistentDataManager->saveToDb($newPayee);
|
|
}
|
|
foreach (array_diff_key($existingPayees, $currentPayees) as $deletedPayee) {
|
|
Container::$persistentDataManager->deleteFromDb($deletedPayee);
|
|
}
|
|
|
|
return new JsonContent(['success' => true]);
|
|
}
|
|
|
|
public function deleteTransaction(): IContent
|
|
{
|
|
$transaction = $this->transactionRepository->getById(Container::$request->query('transactionId'));
|
|
|
|
foreach ($this->transactionPayeeRepository->getAllByTransaction($transaction) as $payee) {
|
|
Container::$persistentDataManager->deleteFromDb($payee);
|
|
}
|
|
|
|
Container::$persistentDataManager->deleteFromDb($transaction);
|
|
|
|
return new JsonContent(['success' => true]);
|
|
}
|
|
|
|
private function getMembers(Community $community): array
|
|
{
|
|
$members = iterator_to_array($this->communityMemberRepository->getAllByCommunity($community, true, ['user']));
|
|
usort($members, function ($a, $b) {
|
|
return strnatcmp($a->getUser()->getDisplayName(), $b->getUser()->getDisplayName());
|
|
});
|
|
return $members;
|
|
}
|
|
|
|
private function getCurrencies(Community $community): array
|
|
{
|
|
$currencies = iterator_to_array($this->currencyRepository->getAllByCommunity($community));
|
|
usort($currencies, function ($a, $b) {
|
|
return strnatcmp($a->getCode(), $b->getCode());
|
|
});
|
|
usort($currencies, function ($a, $b) use ($community) {
|
|
return (int)($b->getId() === $community->getMainCurrencyId()) - (int)($a->getId() === $community->getMainCurrencyId());
|
|
});
|
|
return $currencies;
|
|
}
|
|
}
|