diff --git a/public/static/js/communities/transaction.js b/public/static/js/communities/transaction.js new file mode 100644 index 0000000..0abaf6c --- /dev/null +++ b/public/static/js/communities/transaction.js @@ -0,0 +1,30 @@ +(function () { + const element = document.getElementById('transactionForm').elements['event_id']; + const select = new TomSelect(element, { + valueField: 'value', + labelField: 'label', + searchField: 'label', + loadThrottle: 300, + load: function (query, callback) { + var self = this; + RVR.httpRequest('GET', searchEventUrl.replace('QUERY', encodeURIComponent(query)), function () { + self.clearOptions(); + callback(this.response.results); + }); + }, + }); + + select.on('change', function (value) { + this.clearOptions(); + }); + + select.on('blur', function (value) { + this.clearOptions(); + }); + + select.on('type', function (value) { + if (value === '') { + this.clearOptions(); + } + }); +})(); diff --git a/src/Controller/TransactionController.php b/src/Controller/TransactionController.php index aafbea0..2a08ff5 100644 --- a/src/Controller/TransactionController.php +++ b/src/Controller/TransactionController.php @@ -11,6 +11,7 @@ use RVR\Repository\CommunityMemberRepository; use RVR\Repository\CommunityRepository; use RVR\Repository\CurrencyRepository; use RVR\Repository\TransactionRepository; +use RVR\Repository\EventRepository; use SokoWeb\Interfaces\Authentication\IAuthenticationRequired; use SokoWeb\Interfaces\Authorization\ISecured; use SokoWeb\Interfaces\Response\IContent; @@ -27,9 +28,11 @@ class TransactionController implements IAuthenticationRequired, ISecured private TransactionRepository $transactionRepository; - private Community $community; + private EventRepository $eventRepository; - private CommunityMember $ownCommunityMember; + private ?Community $community; + + private ?CommunityMember $ownCommunityMember; public function __construct() { @@ -37,6 +40,7 @@ class TransactionController implements IAuthenticationRequired, ISecured $this->communityMemberRepository = new CommunityMemberRepository(); $this->currencyRepository = new CurrencyRepository(); $this->transactionRepository = new TransactionRepository(); + $this->eventRepository = new EventRepository(); } public function isAuthenticationRequired(): bool @@ -69,20 +73,38 @@ class TransactionController implements IAuthenticationRequired, ISecured 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 = $this->transactionRepository->countAllByCommunity($this->community); + $numberOfTransactions = $event ? + $this->transactionRepository->countAllByEvent($event) : + $this->transactionRepository->countAllByCommunity($this->community); $pages = ceil($numberOfTransactions / $itemsPerPage); $currentPage = Container::$request->query('page') ?: 0; - $transactions = $this->transactionRepository->getPagedByCommunity( - $this->community, - $currentPage * $itemsPerPage, - $itemsPerPage, - true, - ['currency', 'payer_user', 'payee_user'] - ); + $transactions = $event ? + $this->transactionRepository->getPagedByEvent( + $event, + $currentPage * $itemsPerPage, + $itemsPerPage, + true, + ['currency', 'payer_user', 'payee_user'] + ) : + $this->transactionRepository->getPagedByCommunity( + $this->community, + $currentPage * $itemsPerPage, + $itemsPerPage, + true, + ['event', 'currency', 'payer_user', 'payee_user'] + ); return new HtmlContent('communities/transactions', [ 'community' => $this->community, + 'event' => $event, 'exchangeRateCalculator' => $exchangeRateCalculator, 'pages' => $pages, 'currentPage' => $currentPage, @@ -99,13 +121,22 @@ class TransactionController implements IAuthenticationRequired, ISecured if ($transaction === null) { return null; } + Container::$persistentDataManager->loadRelationsFromDb($transaction, false, ['event']); + $event = $transaction->getEvent(); } else { $transaction = null; + $eventSlug = Container::$request->query('event'); + if ($eventSlug) { + $event = $this->eventRepository->getBySlug($eventSlug); + } else { + $event = null; + } } return new HtmlContent('communities/transaction_edit', [ 'community' => $this->community, 'transaction' => $transaction, + 'event' => $event, 'members' => $this->getMembers($this->community), 'currencies' => $this->getCurrencies($this->community) ]); @@ -121,6 +152,7 @@ class TransactionController implements IAuthenticationRequired, ISecured $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->setPayeeUserId(Container::$request->post('payee_user_id') ?: null); @@ -143,7 +175,7 @@ class TransactionController implements IAuthenticationRequired, ISecured private function getMembers(Community $community): array { $members = iterator_to_array($this->communityMemberRepository->getAllByCommunity($community, true, ['user'])); - usort($members, function($a, $b) { + usort($members, function ($a, $b) { return strnatcmp($a->getUser()->getDisplayName(), $b->getUser()->getDisplayName()); }); return $members; @@ -152,10 +184,10 @@ class TransactionController implements IAuthenticationRequired, ISecured private function getCurrencies(Community $community): array { $currencies = iterator_to_array($this->currencyRepository->getAllByCommunity($community)); - usort($currencies, function($a, $b) { + usort($currencies, function ($a, $b) { return strnatcmp($a->getCode(), $b->getCode()); }); - usort($currencies, function($a, $b) use ($community) { + usort($currencies, function ($a, $b) use ($community) { return (int)($b->getId() === $community->getMainCurrencyId()) - (int)($a->getId() === $community->getMainCurrencyId()); }); return $currencies; diff --git a/src/PersistentData/Model/Transaction.php b/src/PersistentData/Model/Transaction.php index a4a9b48..fe73d49 100644 --- a/src/PersistentData/Model/Transaction.php +++ b/src/PersistentData/Model/Transaction.php @@ -7,10 +7,11 @@ class Transaction extends Model { protected static string $table = 'transactions'; - protected static array $fields = ['community_id', 'currency_id', 'payer_user_id', 'payee_user_id', 'description', 'sum', 'time']; + protected static array $fields = ['community_id', 'event_id', 'currency_id', 'payer_user_id', 'payee_user_id', 'description', 'sum', 'time']; protected static array $relations = [ 'community' => Community::class, + 'event' => Event::class, 'currency' => Currency::class, 'payer_user' => User::class, 'payee_user' => User::class @@ -20,6 +21,10 @@ class Transaction extends Model private int $communityId; + private ?Event $event = null; + + private ?int $eventId = null; + private ?Currency $currency = null; private int $currencyId; @@ -48,6 +53,16 @@ class Transaction extends Model $this->communityId = $communityId; } + public function setEvent(?Event $event): void + { + $this->event = $event; + } + + public function setEventId(?int $eventId): void + { + $this->eventId = $eventId; + } + public function setCurrency(Currency $currency): void { $this->currency = $currency; @@ -108,6 +123,16 @@ class Transaction extends Model return $this->communityId; } + public function getEvent(): ?Event + { + return $this->event; + } + + public function getEventId(): ?int + { + return $this->eventId; + } + public function getCurrency(): ?Currency { return $this->currency; diff --git a/src/Repository/TransactionRepository.php b/src/Repository/TransactionRepository.php index 4535e74..8d2c5b0 100644 --- a/src/Repository/TransactionRepository.php +++ b/src/Repository/TransactionRepository.php @@ -4,6 +4,7 @@ use Container; use Generator; use RVR\PersistentData\Model\Community; use RVR\PersistentData\Model\Currency; +use RVR\PersistentData\Model\Event; use RVR\PersistentData\Model\Transaction; use RVR\PersistentData\Model\User; use SokoWeb\Database\Query\Select; @@ -22,11 +23,23 @@ class TransactionRepository yield from Container::$persistentDataManager->selectMultipleFromDb($select, Transaction::class, $useRelations, $withRelations); } + public function getAllByEvent(Event $event, bool $useRelations = false, array $withRelations = []): Generator + { + $select = $this->selectAllByEvent($event); + + yield from Container::$persistentDataManager->selectMultipleFromDb($select, Transaction::class, $useRelations, $withRelations); + } + public function countAllByCommunity(Community $community): int { return $this->selectAllByCommunity($community)->count(); } + public function countAllByEvent(Event $event): int + { + return $this->selectAllByEvent($event)->count(); + } + public function isAnyForUser(User $user): bool { $select = new Select(Container::$dbConnection, Transaction::getTable()); @@ -55,8 +68,16 @@ class TransactionRepository public function getPagedByCommunity(Community $community, int $start, int $limit, bool $useRelations = false, array $withRelations = []): Generator { - $select = new Select(Container::$dbConnection); - $select->where('community_id', '=', $community->getId()); + $select = $this->selectAllByCommunity($community); + $select->orderBy('time', 'DESC'); + $select->limit($limit, $start); + + yield from Container::$persistentDataManager->selectMultipleFromDb($select, Transaction::class, $useRelations, $withRelations); + } + + public function getPagedByEvent(Event $event, int $start, int $limit, bool $useRelations = false, array $withRelations = []): Generator + { + $select = $this->selectAllByEvent($event); $select->orderBy('time', 'DESC'); $select->limit($limit, $start); @@ -69,4 +90,11 @@ class TransactionRepository $select->where('community_id', '=', $community->getId()); return $select; } + + private function selectAllByEvent(Event $event) + { + $select = new Select(Container::$dbConnection, Transaction::getTable()); + $select->where('event_id', '=', $event->getId()); + return $select; + } } diff --git a/views/communities/transaction_edit.php b/views/communities/transaction_edit.php index 76c3392..2d98c7f 100644 --- a/views/communities/transaction_edit.php +++ b/views/communities/transaction_edit.php @@ -1,9 +1,17 @@ +@css(/static/node_modules/tom-select/dist/css/tom-select.min.css) +@js(/static/node_modules/tom-select/dist/js/tom-select.base.min.js) +@js(js/communities/transaction.js) + @extends(templates/layout_normal) @section(main)