Compare commits
38
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17d9437a50
|
||
|
|
aed4548c7b
|
||
|
|
0d6d152b82
|
||
|
|
7beec510a1
|
||
|
|
22b849a1c8
|
||
|
|
492aa9fcef
|
||
|
|
b6da70e015
|
||
|
|
afead7fd61
|
||
|
|
69acbf708b
|
||
|
|
08ebfae030
|
||
|
|
a597839379
|
||
|
|
e0fe6a8622
|
||
|
|
5ebce653dc
|
||
|
|
61eb2404a2
|
||
|
|
e199dfccc7
|
||
|
|
1d0a2b09d5
|
||
|
|
1886257b63
|
||
|
|
eda1415e86
|
||
|
|
4e9c7f8c3c
|
||
|
|
eebf4aff00
|
||
|
|
6dae33507f
|
||
|
|
96d5aa2219
|
||
|
|
6c326b89e2
|
||
|
|
6c821d41b4
|
||
|
|
ade02f4736
|
||
|
|
bb5b510315
|
||
|
|
1267cb3d95
|
||
|
|
c7641b85e7
|
||
|
|
ee4b8e9d65
|
||
|
|
58d4f982e9
|
||
|
|
ad06cfaa58
|
||
|
|
aa2e0e9b4a
|
||
|
|
d1c926541a
|
||
|
|
9929e00a3f
|
||
|
|
bf415a2a46
|
||
|
|
c0bfa5b334
|
||
|
|
e122248a97
|
||
|
|
d2bb1d4936
|
No files matched your search
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"esoko/soko-web": "0.12.1",
|
"esoko/soko-web": "0.13.1",
|
||||||
"firebase/php-jwt": "^6.4"
|
"firebase/php-jwt": "^6.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|||||||
Generated
+4
-4
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "a6f50b31b14027eec094629b13cc4097",
|
"content-hash": "59130fbd82b1c81275666b16adb0c1a1",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "cocur/slugify",
|
"name": "cocur/slugify",
|
||||||
@@ -82,11 +82,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "esoko/soko-web",
|
"name": "esoko/soko-web",
|
||||||
"version": "v0.12.1",
|
"version": "v0.13.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.esoko.eu/esoko/soko-web.git",
|
"url": "https://git.esoko.eu/esoko/soko-web.git",
|
||||||
"reference": "bda12177ebc201f04fdad5493b93039676a983ca"
|
"reference": "8bf495c89b4ce1456da1133adc285003e544dd48"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"cocur/slugify": "^4.3",
|
"cocur/slugify": "^4.3",
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
"GNU GPL 3.0"
|
"GNU GPL 3.0"
|
||||||
],
|
],
|
||||||
"description": "Lightweight web framework",
|
"description": "Lightweight web framework",
|
||||||
"time": "2023-05-28T13:56:14+00:00"
|
"time": "2023-07-08T12:38:40+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "firebase/php-jwt",
|
"name": "firebase/php-jwt",
|
||||||
|
|||||||
@@ -11,8 +11,3 @@ CREATE TABLE `events` (
|
|||||||
UNIQUE KEY `slug` (`slug`),
|
UNIQUE KEY `slug` (`slug`),
|
||||||
CONSTRAINT `events_community_id` FOREIGN KEY (`community_id`) REFERENCES `communities` (`id`)
|
CONSTRAINT `events_community_id` FOREIGN KEY (`community_id`) REFERENCES `communities` (`id`)
|
||||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
|
|
||||||
ALTER TABLE `transactions`
|
|
||||||
ADD `event_id` int(10) unsigned NULL,
|
|
||||||
ADD KEY `event_id` (`event_id`) AFTER `community_id`,
|
|
||||||
ADD CONSTRAINT `transactions_event_id` FOREIGN KEY (`event_id`) REFERENCES `events` (`id`);
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE `transactions`
|
||||||
|
ADD `event_id` int(10) unsigned NULL AFTER `community_id`,
|
||||||
|
ADD KEY `event_id` (`event_id`),
|
||||||
|
ADD CONSTRAINT `transactions_event_id` FOREIGN KEY (`event_id`) REFERENCES `events` (`id`);
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
CREATE TABLE `transaction_payees` (
|
||||||
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`transaction_id` int(10) unsigned NOT NULL,
|
||||||
|
`user_id` int(10) unsigned DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `unique_user_for_transaction` (`transaction_id`, `user_id`),
|
||||||
|
KEY `transaction_id` (`transaction_id`),
|
||||||
|
KEY `user_id` (`user_id`),
|
||||||
|
CONSTRAINT `transaction_payees_transaction_id` FOREIGN KEY (`transaction_id`) REFERENCES `transactions` (`id`),
|
||||||
|
CONSTRAINT `transaction_payees_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
|
||||||
|
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
|
||||||
@@ -59,32 +59,21 @@ class CommunityController implements IAuthenticationRequired
|
|||||||
|
|
||||||
\Container::$persistentDataManager->loadRelationsFromDb($community, false, ['main_currency']);
|
\Container::$persistentDataManager->loadRelationsFromDb($community, false, ['main_currency']);
|
||||||
|
|
||||||
$balanceCalculator = new BalanceCalculator($community);
|
/**
|
||||||
$debts = $balanceCalculator->calculate();
|
* @var User $user
|
||||||
$debtItems = [];
|
*/
|
||||||
$debtBalance = 0.0;
|
$user = \Container::$request->user();
|
||||||
$outstandingItems = [];
|
$balanceCalculator = new BalanceCalculator($community, $user);
|
||||||
$outstandingBalance = 0.0;
|
$balance = $balanceCalculator->calculate();
|
||||||
foreach ($debts as $debt) {
|
|
||||||
if ($debt['payer']->getId() === \Container::$request->user()->getUniqueId()) {
|
|
||||||
$debtBalance += $debt['amount'];
|
|
||||||
$debtItems[] = $debt;
|
|
||||||
}
|
|
||||||
if ($debt['payee']->getId() === \Container::$request->user()->getUniqueId()) {
|
|
||||||
$outstandingBalance += $debt['amount'];
|
|
||||||
$outstandingItems[] = $debt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$balance = $outstandingBalance - $debtBalance;
|
|
||||||
|
|
||||||
return new HtmlContent('communities/community', [
|
return new HtmlContent('communities/community', [
|
||||||
'community' => $community,
|
'community' => $community,
|
||||||
'upcomingEvents' => iterator_to_array($this->eventRepository->getUpcomingByCommunity($community, new DateTime(), 3)),
|
'upcomingAndRecentEvents' => iterator_to_array($this->eventRepository->getUpcomingAndRecentByCommunity($community, new DateTime(), 30, 3)),
|
||||||
'debtItems' => $debtItems,
|
'debtItems' => $balance['debtItems'],
|
||||||
'debtBalance' => $debtBalance,
|
'debtBalance' => $balance['debtBalance'],
|
||||||
'outstandingItems' => $outstandingItems,
|
'outstandingItems' => $balance['outstandingItems'],
|
||||||
'outstandingBalance' => $outstandingBalance,
|
'outstandingBalance' => $balance['outstandingBalance'],
|
||||||
'balance' => $balance,
|
'balance' => $balance['absoluteBalance'],
|
||||||
'editPermission' => $ownCommunityMember->getOwner()
|
'editPermission' => $ownCommunityMember->getOwner()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -176,6 +165,43 @@ class CommunityController implements IAuthenticationRequired
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteCommunity(): ?IContent
|
||||||
|
{
|
||||||
|
if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->transactionRepository->countAllByCommunity($community) > 0) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => ['errorText' => 'There are transactions for this community!']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->eventRepository->countAllByCommunity($community) > 0) {
|
||||||
|
return new JsonContent([
|
||||||
|
'error' => ['errorText' => 'There are events for this community!']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->communityMemberRepository->getAllByCommunity($community) as $communityMember) {
|
||||||
|
\Container::$persistentDataManager->deleteFromDb($communityMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
$community->setMainCurrencyId(null);
|
||||||
|
\Container::$persistentDataManager->saveToDb($community);
|
||||||
|
|
||||||
|
foreach ($this->currencyRepository->getAllByCommunity($community) as $currency) {
|
||||||
|
foreach ($this->currencyExchangeRatesRepository->getAllByCurrency($currency) as $currencyExchangeRate) {
|
||||||
|
\Container::$persistentDataManager->deleteFromDb($currencyExchangeRate);
|
||||||
|
}
|
||||||
|
\Container::$persistentDataManager->deleteFromDb($currency);
|
||||||
|
}
|
||||||
|
|
||||||
|
\Container::$persistentDataManager->deleteFromDb($community);
|
||||||
|
|
||||||
|
return new JsonContent(['success' => true]);
|
||||||
|
}
|
||||||
|
|
||||||
public function getMembersEdit(): ?IContent
|
public function getMembersEdit(): ?IContent
|
||||||
{
|
{
|
||||||
if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) {
|
if (!$this->checkPermission(\Container::$request->query('communitySlug'), true, $community, $ownCommunityMember)) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use Container;
|
use Container;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
use RVR\Finance\BalanceCalculator;
|
||||||
use RVR\Finance\ExchangeRateCalculator;
|
use RVR\Finance\ExchangeRateCalculator;
|
||||||
use RVR\PersistentData\Model\Community;
|
use RVR\PersistentData\Model\Community;
|
||||||
use RVR\PersistentData\Model\CommunityMember;
|
use RVR\PersistentData\Model\CommunityMember;
|
||||||
@@ -68,17 +69,16 @@ class EventController implements IAuthenticationRequired, ISecured
|
|||||||
{
|
{
|
||||||
$itemsPerPage = 10;
|
$itemsPerPage = 10;
|
||||||
$numberOfEvents = $this->eventRepository->countAllByCommunity($this->community);
|
$numberOfEvents = $this->eventRepository->countAllByCommunity($this->community);
|
||||||
$pages = ceil($numberOfEvents / $itemsPerPage);
|
$currentPage = Container::$request->query('page') ?: 1;
|
||||||
$currentPage = Container::$request->query('page') ?: 0;
|
|
||||||
$events = $this->eventRepository->getPagedByCommunity(
|
$events = $this->eventRepository->getPagedByCommunity(
|
||||||
$this->community,
|
$this->community,
|
||||||
$currentPage * $itemsPerPage,
|
$currentPage,
|
||||||
$itemsPerPage
|
$itemsPerPage
|
||||||
);
|
);
|
||||||
|
|
||||||
return new HtmlContent('events/events', [
|
return new HtmlContent('events/events', [
|
||||||
'community' => $this->community,
|
'community' => $this->community,
|
||||||
'pages' => $pages,
|
'pages' => ceil($numberOfEvents / $itemsPerPage),
|
||||||
'currentPage' => $currentPage,
|
'currentPage' => $currentPage,
|
||||||
'numberOfEvents' => $numberOfEvents,
|
'numberOfEvents' => $numberOfEvents,
|
||||||
'events' => $events
|
'events' => $events
|
||||||
@@ -106,10 +106,22 @@ class EventController implements IAuthenticationRequired, ISecured
|
|||||||
}
|
}
|
||||||
Container::$persistentDataManager->loadRelationsFromDb($this->community, true, ['main_currency']);
|
Container::$persistentDataManager->loadRelationsFromDb($this->community, true, ['main_currency']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = \Container::$request->user();
|
||||||
|
$balanceCalculator = new BalanceCalculator($this->community, $user, $event);
|
||||||
|
$balance = $balanceCalculator->calculate();
|
||||||
|
|
||||||
return new HtmlContent('events/event', [
|
return new HtmlContent('events/event', [
|
||||||
'community' => $this->community,
|
'community' => $this->community,
|
||||||
'event' => $event,
|
'event' => $event,
|
||||||
'totalCost' => $this->sumTransactions($event)
|
'totalCost' => $this->sumTransactions($event),
|
||||||
|
'debtItems' => $balance['debtItems'],
|
||||||
|
'debtBalance' => $balance['debtBalance'],
|
||||||
|
'outstandingItems' => $balance['outstandingItems'],
|
||||||
|
'outstandingBalance' => $balance['outstandingBalance'],
|
||||||
|
'balance' => $balance['absoluteBalance'],
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?php namespace RVR\Controller;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use Container;
|
||||||
|
use RVR\PersistentData\Model\Event;
|
||||||
|
use RVR\PersistentData\Model\User;
|
||||||
|
use RVR\Repository\EventRepository;
|
||||||
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
||||||
|
use SokoWeb\Interfaces\Response\IRedirect;
|
||||||
|
use SokoWeb\Response\HtmlContent;
|
||||||
|
use SokoWeb\Response\Redirect;
|
||||||
|
|
||||||
|
class EventRedirectController implements IAuthenticationRequired
|
||||||
|
{
|
||||||
|
private EventRepository $eventRepository;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->eventRepository = new EventRepository();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isAuthenticationRequired(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEvent()
|
||||||
|
{
|
||||||
|
$currentEvent = $this->getCurrentEvent();
|
||||||
|
if ($currentEvent === null) {
|
||||||
|
return new HtmlContent('event_redirect/no_event');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Redirect(
|
||||||
|
\Container::$routeCollection->getRoute('community.event')
|
||||||
|
->generateLink([
|
||||||
|
'communitySlug' => $currentEvent->getCommunity()->getSlug(),
|
||||||
|
'eventSlug' => $currentEvent->getSlug()
|
||||||
|
]),
|
||||||
|
IRedirect::TEMPORARY
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEventNewTransaction()
|
||||||
|
{
|
||||||
|
$currentEvent = $this->getCurrentEvent();
|
||||||
|
if ($currentEvent === null) {
|
||||||
|
return new HtmlContent('event_redirect/no_event');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Redirect(
|
||||||
|
\Container::$routeCollection->getRoute('community.transactions.new')
|
||||||
|
->generateLink([
|
||||||
|
'communitySlug' => $currentEvent->getCommunity()->getSlug(),
|
||||||
|
'event' => $currentEvent->getSlug()
|
||||||
|
]),
|
||||||
|
IRedirect::TEMPORARY
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCurrentEvent(): ?Event
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = Container::$request->user();
|
||||||
|
|
||||||
|
return $this->eventRepository->getCurrentByUser($user, new DateTime(), 30, true, ['community']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,7 +44,7 @@ class HomeController implements IAuthenticationRequired
|
|||||||
|
|
||||||
return new HtmlContent('home', [
|
return new HtmlContent('home', [
|
||||||
'communities' => $communities,
|
'communities' => $communities,
|
||||||
'upcomingEvents' => iterator_to_array($this->eventRepository->getUpcomingByUser($user, new DateTime(), 3, true, ['community']))
|
'upcomingAndRecentEvents' => iterator_to_array($this->eventRepository->getUpcomingAndRecentByUser($user, new DateTime(), 30, 3, true, ['community']))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,11 +6,13 @@ use RVR\Finance\ExchangeRateCalculator;
|
|||||||
use RVR\PersistentData\Model\Community;
|
use RVR\PersistentData\Model\Community;
|
||||||
use RVR\PersistentData\Model\CommunityMember;
|
use RVR\PersistentData\Model\CommunityMember;
|
||||||
use RVR\PersistentData\Model\Transaction;
|
use RVR\PersistentData\Model\Transaction;
|
||||||
|
use RVR\PersistentData\Model\TransactionPayee;
|
||||||
use RVR\PersistentData\Model\User;
|
use RVR\PersistentData\Model\User;
|
||||||
use RVR\Repository\CommunityMemberRepository;
|
use RVR\Repository\CommunityMemberRepository;
|
||||||
use RVR\Repository\CommunityRepository;
|
use RVR\Repository\CommunityRepository;
|
||||||
use RVR\Repository\CurrencyRepository;
|
use RVR\Repository\CurrencyRepository;
|
||||||
use RVR\Repository\TransactionRepository;
|
use RVR\Repository\TransactionRepository;
|
||||||
|
use RVR\Repository\TransactionPayeeRepository;
|
||||||
use RVR\Repository\EventRepository;
|
use RVR\Repository\EventRepository;
|
||||||
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
|
||||||
use SokoWeb\Interfaces\Authorization\ISecured;
|
use SokoWeb\Interfaces\Authorization\ISecured;
|
||||||
@@ -28,6 +30,8 @@ class TransactionController implements IAuthenticationRequired, ISecured
|
|||||||
|
|
||||||
private TransactionRepository $transactionRepository;
|
private TransactionRepository $transactionRepository;
|
||||||
|
|
||||||
|
private TransactionPayeeRepository $transactionPayeeRepository;
|
||||||
|
|
||||||
private EventRepository $eventRepository;
|
private EventRepository $eventRepository;
|
||||||
|
|
||||||
private ?Community $community;
|
private ?Community $community;
|
||||||
@@ -40,6 +44,7 @@ class TransactionController implements IAuthenticationRequired, ISecured
|
|||||||
$this->communityMemberRepository = new CommunityMemberRepository();
|
$this->communityMemberRepository = new CommunityMemberRepository();
|
||||||
$this->currencyRepository = new CurrencyRepository();
|
$this->currencyRepository = new CurrencyRepository();
|
||||||
$this->transactionRepository = new TransactionRepository();
|
$this->transactionRepository = new TransactionRepository();
|
||||||
|
$this->transactionPayeeRepository = new TransactionPayeeRepository();
|
||||||
$this->eventRepository = new EventRepository();
|
$this->eventRepository = new EventRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,32 +89,35 @@ class TransactionController implements IAuthenticationRequired, ISecured
|
|||||||
$numberOfTransactions = $event ?
|
$numberOfTransactions = $event ?
|
||||||
$this->transactionRepository->countAllByEvent($event) :
|
$this->transactionRepository->countAllByEvent($event) :
|
||||||
$this->transactionRepository->countAllByCommunity($this->community);
|
$this->transactionRepository->countAllByCommunity($this->community);
|
||||||
$pages = ceil($numberOfTransactions / $itemsPerPage);
|
$currentPage = Container::$request->query('page') ?: 1;
|
||||||
$currentPage = Container::$request->query('page') ?: 0;
|
|
||||||
$transactions = $event ?
|
$transactions = $event ?
|
||||||
$this->transactionRepository->getPagedByEvent(
|
$this->transactionRepository->getPagedByEvent(
|
||||||
$event,
|
$event,
|
||||||
$currentPage * $itemsPerPage,
|
$currentPage,
|
||||||
$itemsPerPage,
|
$itemsPerPage,
|
||||||
true,
|
true,
|
||||||
['currency', 'payer_user', 'payee_user']
|
['currency', 'payer_user']
|
||||||
) :
|
) :
|
||||||
$this->transactionRepository->getPagedByCommunity(
|
$this->transactionRepository->getPagedByCommunity(
|
||||||
$this->community,
|
$this->community,
|
||||||
$currentPage * $itemsPerPage,
|
$currentPage,
|
||||||
$itemsPerPage,
|
$itemsPerPage,
|
||||||
true,
|
true,
|
||||||
['event', 'currency', 'payer_user', 'payee_user']
|
['event', 'currency', 'payer_user']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$transactions = iterator_to_array($transactions);
|
||||||
|
Container::$persistentDataManager->loadMultiRelationsFromDb($transactions, 'payees', true, ['user']);
|
||||||
|
|
||||||
return new HtmlContent('communities/transactions', [
|
return new HtmlContent('communities/transactions', [
|
||||||
'community' => $this->community,
|
'community' => $this->community,
|
||||||
'event' => $event,
|
'event' => $event,
|
||||||
'exchangeRateCalculator' => $exchangeRateCalculator,
|
'exchangeRateCalculator' => $exchangeRateCalculator,
|
||||||
'pages' => $pages,
|
'pages' => ceil($numberOfTransactions / $itemsPerPage),
|
||||||
'currentPage' => $currentPage,
|
'currentPage' => $currentPage,
|
||||||
'numberOfTransactions' => $numberOfTransactions,
|
'numberOfTransactions' => $numberOfTransactions,
|
||||||
'transactions' => $transactions
|
'transactions' => $transactions,
|
||||||
|
'members' => $this->getMembers($this->community)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +131,10 @@ class TransactionController implements IAuthenticationRequired, ISecured
|
|||||||
}
|
}
|
||||||
Container::$persistentDataManager->loadRelationsFromDb($transaction, false, ['event']);
|
Container::$persistentDataManager->loadRelationsFromDb($transaction, false, ['event']);
|
||||||
$event = $transaction->getEvent();
|
$event = $transaction->getEvent();
|
||||||
|
$payeeUserIds = [];
|
||||||
|
foreach ($this->transactionPayeeRepository->getAllByTransaction($transaction) as $payee) {
|
||||||
|
$payeeUserIds[] = $payee->getUserId();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$transaction = null;
|
$transaction = null;
|
||||||
$eventSlug = Container::$request->query('event');
|
$eventSlug = Container::$request->query('event');
|
||||||
@@ -131,11 +143,13 @@ class TransactionController implements IAuthenticationRequired, ISecured
|
|||||||
} else {
|
} else {
|
||||||
$event = null;
|
$event = null;
|
||||||
}
|
}
|
||||||
|
$payeeUserIds = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HtmlContent('communities/transaction_edit', [
|
return new HtmlContent('communities/transaction_edit', [
|
||||||
'community' => $this->community,
|
'community' => $this->community,
|
||||||
'transaction' => $transaction,
|
'transaction' => $transaction,
|
||||||
|
'payeeUserIds' => $payeeUserIds,
|
||||||
'event' => $event,
|
'event' => $event,
|
||||||
'members' => $this->getMembers($this->community),
|
'members' => $this->getMembers($this->community),
|
||||||
'currencies' => $this->getCurrencies($this->community)
|
'currencies' => $this->getCurrencies($this->community)
|
||||||
@@ -155,18 +169,48 @@ class TransactionController implements IAuthenticationRequired, ISecured
|
|||||||
$transaction->setEventId(Container::$request->post('event_id') ?: null);
|
$transaction->setEventId(Container::$request->post('event_id') ?: null);
|
||||||
$transaction->setCurrencyId(Container::$request->post('currency_id'));
|
$transaction->setCurrencyId(Container::$request->post('currency_id'));
|
||||||
$transaction->setPayerUserId(Container::$request->post('payer_user_id'));
|
$transaction->setPayerUserId(Container::$request->post('payer_user_id'));
|
||||||
$transaction->setPayeeUserId(Container::$request->post('payee_user_id') ?: null);
|
|
||||||
$transaction->setDescription(Container::$request->post('description'));
|
$transaction->setDescription(Container::$request->post('description'));
|
||||||
$transaction->setSum(Container::$request->post('sum'));
|
$transaction->setSum(Container::$request->post('sum'));
|
||||||
$transaction->setTimeDate(new DateTime(Container::$request->post('time')));
|
$transaction->setTimeDate(new DateTime(Container::$request->post('time')));
|
||||||
Container::$persistentDataManager->saveToDb($transaction);
|
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]);
|
return new JsonContent(['success' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteTransaction(): IContent
|
public function deleteTransaction(): IContent
|
||||||
{
|
{
|
||||||
$transaction = $this->transactionRepository->getById(Container::$request->query('transactionId'));
|
$transaction = $this->transactionRepository->getById(Container::$request->query('transactionId'));
|
||||||
|
|
||||||
|
foreach ($this->transactionPayeeRepository->getAllByTransaction($transaction) as $payee) {
|
||||||
|
Container::$persistentDataManager->deleteFromDb($payee);
|
||||||
|
}
|
||||||
|
|
||||||
Container::$persistentDataManager->deleteFromDb($transaction);
|
Container::$persistentDataManager->deleteFromDb($transaction);
|
||||||
|
|
||||||
return new JsonContent(['success' => true]);
|
return new JsonContent(['success' => true]);
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<?php namespace RVR\Finance;
|
<?php namespace RVR\Finance;
|
||||||
|
|
||||||
|
use Container;
|
||||||
use RVR\PersistentData\Model\Community;
|
use RVR\PersistentData\Model\Community;
|
||||||
|
use RVR\PersistentData\Model\Event;
|
||||||
|
use RVR\PersistentData\Model\User;
|
||||||
use RVR\Repository\CommunityMemberRepository;
|
use RVR\Repository\CommunityMemberRepository;
|
||||||
use RVR\Repository\TransactionRepository;
|
use RVR\Repository\TransactionRepository;
|
||||||
|
|
||||||
@@ -8,6 +11,10 @@ class BalanceCalculator
|
|||||||
{
|
{
|
||||||
private Community $community;
|
private Community $community;
|
||||||
|
|
||||||
|
private User $user;
|
||||||
|
|
||||||
|
private ?Event $event;
|
||||||
|
|
||||||
private TransactionRepository $transactionRepository;
|
private TransactionRepository $transactionRepository;
|
||||||
|
|
||||||
private CommunityMemberRepository $communityMemberRepository;
|
private CommunityMemberRepository $communityMemberRepository;
|
||||||
@@ -18,9 +25,13 @@ class BalanceCalculator
|
|||||||
|
|
||||||
private array $payments;
|
private array $payments;
|
||||||
|
|
||||||
public function __construct(Community $community)
|
private array $actualDebts;
|
||||||
|
|
||||||
|
public function __construct(Community $community, User $user, ?Event $event = null)
|
||||||
{
|
{
|
||||||
$this->community = $community;
|
$this->community = $community;
|
||||||
|
$this->user = $user;
|
||||||
|
$this->event = $event;
|
||||||
$this->transactionRepository = new TransactionRepository();
|
$this->transactionRepository = new TransactionRepository();
|
||||||
$this->communityMemberRepository = new CommunityMemberRepository();
|
$this->communityMemberRepository = new CommunityMemberRepository();
|
||||||
$this->exchangeRateCalculator = new ExchangeRateCalculator($this->community->getMainCurrency());
|
$this->exchangeRateCalculator = new ExchangeRateCalculator($this->community->getMainCurrency());
|
||||||
@@ -31,7 +42,8 @@ class BalanceCalculator
|
|||||||
$this->collectMembers();
|
$this->collectMembers();
|
||||||
$this->createPaymentsMatrix();
|
$this->createPaymentsMatrix();
|
||||||
$this->sumTransactions();
|
$this->sumTransactions();
|
||||||
return $this->calculateActualDebts();
|
$this->calculateActualDebts();
|
||||||
|
return $this->calculateBalanceForUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function collectMembers(): void
|
private function collectMembers(): void
|
||||||
@@ -56,13 +68,22 @@ class BalanceCalculator
|
|||||||
private function sumTransactions(): void
|
private function sumTransactions(): void
|
||||||
{
|
{
|
||||||
$membersCount = count($this->members);
|
$membersCount = count($this->members);
|
||||||
$transactions = $this->transactionRepository->getAllByCommunity($this->community, true, ['currency']);
|
if ($this->event !== null) {
|
||||||
|
$transactions = iterator_to_array($this->transactionRepository->getAllByEvent($this->event, true, ['currency']));
|
||||||
|
} else {
|
||||||
|
$transactions = iterator_to_array($this->transactionRepository->getAllByCommunity($this->community, true, ['currency']));
|
||||||
|
}
|
||||||
|
Container::$persistentDataManager->loadMultiRelationsFromDb($transactions, 'payees');
|
||||||
|
|
||||||
foreach ($transactions as $transaction) {
|
foreach ($transactions as $transaction) {
|
||||||
$sum = $this->exchangeRateCalculator->calculate($transaction->getSum(), $transaction->getCurrency(), $transaction->getTimeDate());
|
$sum = $this->exchangeRateCalculator->calculate($transaction->getSum(), $transaction->getCurrency(), $transaction->getTimeDate());
|
||||||
|
$payees = $transaction->getPayees();
|
||||||
|
$payeeCount = count($payees);
|
||||||
|
|
||||||
if ($transaction->getPayeeUserId()) {
|
if ($payeeCount > 0) {
|
||||||
$this->payments[$transaction->getPayerUserId()][$transaction->getPayeeUserId()] += $sum;
|
foreach ($payees as $payee) {
|
||||||
|
$this->payments[$transaction->getPayerUserId()][$payee->getUserId()] += $sum / $payeeCount;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
foreach ($this->members as $payeeUserId => $member) {
|
foreach ($this->members as $payeeUserId => $member) {
|
||||||
$this->payments[$transaction->getPayerUserId()][$payeeUserId] += $sum / $membersCount;
|
$this->payments[$transaction->getPayerUserId()][$payeeUserId] += $sum / $membersCount;
|
||||||
@@ -71,20 +92,45 @@ class BalanceCalculator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function calculateActualDebts(): array
|
private function calculateActualDebts(): void
|
||||||
{
|
{
|
||||||
$actualDebts = [];
|
$this->actualDebts = [];
|
||||||
|
|
||||||
foreach ($this->payments as $payerUserId => $paymentsOfPayer) {
|
foreach ($this->payments as $payerUserId => $paymentsOfPayer) {
|
||||||
foreach ($paymentsOfPayer as $payeeUserId => $sum) {
|
foreach ($paymentsOfPayer as $payeeUserId => $sum) {
|
||||||
$actualDebt = $this->payments[$payeeUserId][$payerUserId] - $sum;
|
$actualDebt = $this->payments[$payeeUserId][$payerUserId] - $sum;
|
||||||
|
|
||||||
if (round($actualDebt, $this->community->getMainCurrency()->getRoundDigits()) > 0.0) {
|
if (round($actualDebt, $this->community->getMainCurrency()->getRoundDigits()) > 0.0) {
|
||||||
$actualDebts[] = ['payer' => $this->members[$payerUserId], 'payee' => $this->members[$payeeUserId], 'amount' => $actualDebt];
|
$this->actualDebts[] = ['payer' => $this->members[$payerUserId], 'payee' => $this->members[$payeeUserId], 'amount' => $actualDebt];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $actualDebts;
|
private function calculateBalanceForUser(): array
|
||||||
|
{
|
||||||
|
$debtItems = [];
|
||||||
|
$debtBalance = 0.0;
|
||||||
|
$outstandingItems = [];
|
||||||
|
$outstandingBalance = 0.0;
|
||||||
|
foreach ($this->actualDebts as $debt) {
|
||||||
|
if ($debt['payer']->getId() === $this->user->getId()) {
|
||||||
|
$debtBalance += $debt['amount'];
|
||||||
|
$debtItems[] = $debt;
|
||||||
|
}
|
||||||
|
if ($debt['payee']->getId() === $this->user->getId()) {
|
||||||
|
$outstandingBalance += $debt['amount'];
|
||||||
|
$outstandingItems[] = $debt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$absoluteBalance = $outstandingBalance - $debtBalance;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'absoluteBalance' => $absoluteBalance,
|
||||||
|
'debtItems' => $debtItems,
|
||||||
|
'debtBalance' => $debtBalance,
|
||||||
|
'outstandingItems' => $outstandingItems,
|
||||||
|
'outstandingBalance' => $outstandingBalance
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,12 +33,12 @@ class Community extends ModelWithSlug
|
|||||||
$this->currency = $currency;
|
$this->currency = $currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMainCurrency(Currency $mainCurrency): void
|
public function setMainCurrency(?Currency $mainCurrency): void
|
||||||
{
|
{
|
||||||
$this->mainCurrency = $mainCurrency;
|
$this->mainCurrency = $mainCurrency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMainCurrencyId(int $mainCurrencyId): void
|
public function setMainCurrencyId(?int $mainCurrencyId): void
|
||||||
{
|
{
|
||||||
$this->mainCurrencyId = $mainCurrencyId;
|
$this->mainCurrencyId = $mainCurrencyId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ class Transaction extends Model
|
|||||||
'payee_user' => User::class
|
'payee_user' => User::class
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected static array $multiRelations = [
|
||||||
|
'payees' => [TransactionPayee::class, 'transaction']
|
||||||
|
];
|
||||||
|
|
||||||
private ?Community $community = null;
|
private ?Community $community = null;
|
||||||
|
|
||||||
private int $communityId;
|
private int $communityId;
|
||||||
@@ -37,6 +41,8 @@ class Transaction extends Model
|
|||||||
|
|
||||||
private ?int $payeeUserId = null;
|
private ?int $payeeUserId = null;
|
||||||
|
|
||||||
|
private ?array $payees = null;
|
||||||
|
|
||||||
private string $description = '';
|
private string $description = '';
|
||||||
|
|
||||||
private float $sum = 0.0;
|
private float $sum = 0.0;
|
||||||
@@ -93,6 +99,11 @@ class Transaction extends Model
|
|||||||
$this->payeeUserId = $payeeUserId;
|
$this->payeeUserId = $payeeUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setPayees(array $payees): void
|
||||||
|
{
|
||||||
|
$this->payees = $payees;
|
||||||
|
}
|
||||||
|
|
||||||
public function setDescription(string $description): void
|
public function setDescription(string $description): void
|
||||||
{
|
{
|
||||||
$this->description = $description;
|
$this->description = $description;
|
||||||
@@ -163,6 +174,11 @@ class Transaction extends Model
|
|||||||
return $this->payeeUserId;
|
return $this->payeeUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getPayees(): ?array
|
||||||
|
{
|
||||||
|
return $this->payees;
|
||||||
|
}
|
||||||
|
|
||||||
public function getDescription(): string
|
public function getDescription(): string
|
||||||
{
|
{
|
||||||
return $this->description;
|
return $this->description;
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
<?php namespace RVR\PersistentData\Model;
|
||||||
|
|
||||||
|
use SokoWeb\PersistentData\Model\Model;
|
||||||
|
|
||||||
|
class TransactionPayee extends Model
|
||||||
|
{
|
||||||
|
protected static string $table = 'transaction_payees';
|
||||||
|
|
||||||
|
protected static array $fields = ['transaction_id', 'user_id'];
|
||||||
|
|
||||||
|
protected static array $relations = ['transaction' => Transaction::class, 'user' => User::class];
|
||||||
|
|
||||||
|
private ?Transaction $transaction = null;
|
||||||
|
|
||||||
|
private ?int $transactionId = null;
|
||||||
|
|
||||||
|
private ?User $user = null;
|
||||||
|
|
||||||
|
private ?int $userId = null;
|
||||||
|
|
||||||
|
public function setTransaction(Transaction $transaction): void
|
||||||
|
{
|
||||||
|
$this->transaction = $transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTransactionId(int $transactionId): void
|
||||||
|
{
|
||||||
|
$this->transactionId = $transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUser(User $user): void
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUserId(int $userId): void
|
||||||
|
{
|
||||||
|
$this->userId = $userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTransaction(): ?Transaction
|
||||||
|
{
|
||||||
|
return $this->transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTransactionId(): ?int
|
||||||
|
{
|
||||||
|
return $this->transactionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUser(): ?User
|
||||||
|
{
|
||||||
|
return $this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserId(): ?int
|
||||||
|
{
|
||||||
|
return $this->userId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,12 +15,16 @@ class CommunityMemberRepository
|
|||||||
|
|
||||||
public function getAllByCommunity(Community $community, bool $useRelations = false, array $withRelations = []): Generator
|
public function getAllByCommunity(Community $community, bool $useRelations = false, array $withRelations = []): Generator
|
||||||
{
|
{
|
||||||
$select = new Select(\Container::$dbConnection);
|
$select = $this->selectAllByCommunity($community);
|
||||||
$select->where('community_id', '=', $community->getId());
|
|
||||||
|
|
||||||
yield from \Container::$persistentDataManager->selectMultipleFromDb($select, CommunityMember::class, $useRelations, $withRelations);
|
yield from \Container::$persistentDataManager->selectMultipleFromDb($select, CommunityMember::class, $useRelations, $withRelations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function countAllByCommunity(Community $community): int
|
||||||
|
{
|
||||||
|
return $this->selectAllByCommunity($community)->count();
|
||||||
|
}
|
||||||
|
|
||||||
public function getAllByUser(User $user, bool $useRelations = false, array $withRelations = []): Generator
|
public function getAllByUser(User $user, bool $useRelations = false, array $withRelations = []): Generator
|
||||||
{
|
{
|
||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
@@ -37,4 +41,11 @@ class CommunityMemberRepository
|
|||||||
|
|
||||||
return \Container::$persistentDataManager->selectFromDb($select, CommunityMember::class);
|
return \Container::$persistentDataManager->selectFromDb($select, CommunityMember::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function selectAllByCommunity(Community $community): Select
|
||||||
|
{
|
||||||
|
$select = new Select(\Container::$dbConnection, CommunityMember::getTable());
|
||||||
|
$select->where('community_id', '=', $community->getId());
|
||||||
|
return $select;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use Container;
|
use Container;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
use DateInterval;
|
||||||
use Generator;
|
use Generator;
|
||||||
use RVR\PersistentData\Model\Community;
|
use RVR\PersistentData\Model\Community;
|
||||||
use RVR\PersistentData\Model\Event;
|
use RVR\PersistentData\Model\Event;
|
||||||
@@ -32,31 +33,41 @@ class EventRepository
|
|||||||
return $this->selectAllByCommunity($community)->count();
|
return $this->selectAllByCommunity($community)->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUpcomingByCommunity(Community $community, DateTime $from, int $limit, bool $useRelations = false, array $withRelations = []): Generator
|
public function getUpcomingAndRecentByCommunity(Community $community, DateTime $from, int $days, int $limit, bool $useRelations = false, array $withRelations = []): Generator
|
||||||
{
|
{
|
||||||
$select = $this->selectAllByCommunity($community);
|
$select = $this->selectAllByCommunity($community);
|
||||||
$select->where('end', '>', $from->format('Y-m-d H:i:s'));
|
$this->selectUpcomingAndRecent($select, $from, $days);
|
||||||
$select->orderBy('start', 'ASC');
|
$select->orderBy('start', 'DESC');
|
||||||
$select->limit($limit, 0);
|
$select->limit($limit, 0);
|
||||||
|
|
||||||
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Event::class, $useRelations, $withRelations);
|
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Event::class, $useRelations, $withRelations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUpcomingByUser(User $user, DateTime $from, int $limit, bool $useRelations = false, array $withRelations = []): Generator
|
public function getUpcomingAndRecentByUser(User $user, DateTime $from, int $days, int $limit, bool $useRelations = false, array $withRelations = []): Generator
|
||||||
{
|
{
|
||||||
$select = $this->selectAllByUser($user);
|
$select = $this->selectAllByUser($user);
|
||||||
$select->where('end', '>', $from->format('Y-m-d H:i:s'));
|
$this->selectUpcomingAndRecent($select, $from, $days);
|
||||||
$select->orderBy('start', 'ASC');
|
$select->orderBy('start', 'DESC');
|
||||||
$select->limit($limit, 0);
|
$select->limit($limit, 0);
|
||||||
|
|
||||||
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Event::class, $useRelations, $withRelations);
|
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Event::class, $useRelations, $withRelations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPagedByCommunity(Community $community, int $start, int $limit, bool $useRelations = false, array $withRelations = []): Generator
|
public function getCurrentByUser(User $user, DateTime $from, int $days, bool $useRelations = false, array $withRelations = []): ?Event
|
||||||
|
{
|
||||||
|
$select = $this->selectAllByUser($user);
|
||||||
|
$this->selectUpcomingAndRecent($select, $from, $days);
|
||||||
|
$select->orderBy('start', 'DESC');
|
||||||
|
$select->limit(1, 0);
|
||||||
|
|
||||||
|
return Container::$persistentDataManager->selectFromDb($select, Event::class, $useRelations, $withRelations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPagedByCommunity(Community $community, int $page, int $itemsPerPage, bool $useRelations = false, array $withRelations = []): Generator
|
||||||
{
|
{
|
||||||
$select = $this->selectAllByCommunity($community);
|
$select = $this->selectAllByCommunity($community);
|
||||||
$select->orderBy('start', 'DESC');
|
$select->orderBy('start', 'DESC');
|
||||||
$select->limit($limit, $start);
|
$select->paginate($page, $itemsPerPage);
|
||||||
|
|
||||||
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Event::class, $useRelations, $withRelations);
|
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Event::class, $useRelations, $withRelations);
|
||||||
}
|
}
|
||||||
@@ -86,4 +97,16 @@ class EventRepository
|
|||||||
$select->where(['community_members', 'user_id'], '=', $user->getId());
|
$select->where(['community_members', 'user_id'], '=', $user->getId());
|
||||||
return $select;
|
return $select;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function selectUpcomingAndRecent(Select $select, DateTime $from, int $days)
|
||||||
|
{
|
||||||
|
$select->where(function (Select $select) use ($from, $days) {
|
||||||
|
$select->where('start', '<', (clone $from)->add(DateInterval::createFromDateString("$days days"))->format('Y-m-d H:i:s'));
|
||||||
|
$select->where('end', '>', $from->format('Y-m-d H:i:s'));
|
||||||
|
});
|
||||||
|
$select->orWhere(function (Select $select) use ($from, $days) {
|
||||||
|
$select->where('end', '>', (clone $from)->sub(DateInterval::createFromDateString("$days days"))->format('Y-m-d H:i:s'));
|
||||||
|
$select->where('start', '<', $from->format('Y-m-d H:i:s'));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php namespace RVR\Repository;
|
||||||
|
|
||||||
|
use Container;
|
||||||
|
use Generator;
|
||||||
|
use RVR\PersistentData\Model\Transaction;
|
||||||
|
use RVR\PersistentData\Model\TransactionPayee;
|
||||||
|
use SokoWeb\Database\Query\Select;
|
||||||
|
|
||||||
|
class TransactionPayeeRepository
|
||||||
|
{
|
||||||
|
public function getById(int $id): ?TransactionPayee
|
||||||
|
{
|
||||||
|
return Container::$persistentDataManager->selectFromDbById($id, TransactionPayee::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllByTransaction(Transaction $transaction, bool $useRelations = false, array $withRelations = []): Generator
|
||||||
|
{
|
||||||
|
$select = new Select(Container::$dbConnection);
|
||||||
|
$select->where('transaction_id', '=', $transaction->getId());
|
||||||
|
|
||||||
|
yield from Container::$persistentDataManager->selectMultipleFromDb($select, TransactionPayee::class, $useRelations, $withRelations);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,20 +66,20 @@ class TransactionRepository
|
|||||||
return $select->count() > 0;
|
return $select->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPagedByCommunity(Community $community, int $start, int $limit, bool $useRelations = false, array $withRelations = []): Generator
|
public function getPagedByCommunity(Community $community, int $page, int $itemsPerPage, bool $useRelations = false, array $withRelations = []): Generator
|
||||||
{
|
{
|
||||||
$select = $this->selectAllByCommunity($community);
|
$select = $this->selectAllByCommunity($community);
|
||||||
$select->orderBy('time', 'DESC');
|
$select->orderBy('time', 'DESC');
|
||||||
$select->limit($limit, $start);
|
$select->paginate($page, $itemsPerPage);
|
||||||
|
|
||||||
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Transaction::class, $useRelations, $withRelations);
|
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
|
public function getPagedByEvent(Event $event, int $page, int $itemsPerPage, bool $useRelations = false, array $withRelations = []): Generator
|
||||||
{
|
{
|
||||||
$select = $this->selectAllByEvent($event);
|
$select = $this->selectAllByEvent($event);
|
||||||
$select->orderBy('time', 'DESC');
|
$select->orderBy('time', 'DESC');
|
||||||
$select->limit($limit, $start);
|
$select->paginate($page, $itemsPerPage);
|
||||||
|
|
||||||
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Transaction::class, $useRelations, $withRelations);
|
yield from Container::$persistentDataManager->selectMultipleFromDb($select, Transaction::class, $useRelations, $withRelations);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,16 +12,16 @@
|
|||||||
|
|
||||||
<div class="gridContainer marginTop">
|
<div class="gridContainer marginTop">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="marginBottom">Upcoming events</h3>
|
<h3 class="marginBottom">Upcoming and recent events</h3>
|
||||||
<?php if (count($upcomingEvents) > 0): ?>
|
<?php if (count($upcomingAndRecentEvents) > 0): ?>
|
||||||
<?php foreach ($upcomingEvents as $event): ?>
|
<?php foreach ($upcomingAndRecentEvents as $event): ?>
|
||||||
<p>
|
<p>
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.event')->generateLink(['communitySlug' => $community->getSlug(), 'eventSlug' => $event->getSlug()]) ?>"><?= $event->getTitle() ?></a>
|
<a href="<?= Container::$routeCollection->getRoute('community.event')->generateLink(['communitySlug' => $community->getSlug(), 'eventSlug' => $event->getSlug()]) ?>"><?= $event->getTitle() ?></a>
|
||||||
<span class="small"><?= $event->getStartDate()->format('Y-m-d') ?> – <?= $event->getEndDate()->format('Y-m-d') ?></span>
|
<span class="small"><?= $event->getStartDate()->format('Y-m-d') ?> – <?= $event->getEndDate()->format('Y-m-d') ?></span>
|
||||||
</p>
|
</p>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<p>There is no upcoming event.</p>
|
<p>There is no event to show.</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug()]) ?>">All events</a> | <a href="<?= Container::$routeCollection->getRoute('community.events.new')->generateLink(['communitySlug' => $community->getSlug()]) ?>">New event</a></p>
|
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug()]) ?>">All events</a> | <a href="<?= Container::$routeCollection->getRoute('community.events.new')->generateLink(['communitySlug' => $community->getSlug()]) ?>">New event</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,9 +25,15 @@
|
|||||||
<input type="number" class="text big fullWidth" name="main_currency_round_digits" min="0" max="9" required>
|
<input type="number" class="text big fullWidth" name="main_currency_round_digits" min="0" max="9" required>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<p id="communityFormError" class="formError justify marginTop"></p>
|
<p id="communityFormError" class="formError justify marginTop"></p>
|
||||||
<div class="right marginTop">
|
<div class="right marginTop" style="font-size: 0;">
|
||||||
<button type="submit" name="submit_button"><?= isset($community) ? '<i class="fa-regular fa-floppy-disk"></i> Save' : '<i class="fa-regular fa-plus"></i> Create' ?></button>
|
<button type="submit" name="submit_button"><?= isset($community) ? '<i class="fa-regular fa-floppy-disk"></i> Save' : '<i class="fa-regular fa-plus"></i> Create' ?></button>
|
||||||
|
<?php if (isset($community)): ?>
|
||||||
|
<button type="submit" form="deleteCommunity" name="submit_button" data-confirmation="Are you sure you want to delete this community?" class="red marginLeft"><i class="fa-regular fa-trash-can"></i> Delete</button>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<?php if (isset($community)): ?>
|
||||||
|
<form id="deleteCommunity" action="<?= Container::$routeCollection->getRoute('community.delete-action')->generateLink(['communitySlug' => $community->getSlug()]) ?>" method="post" data-redirect-on-success="<?= Container::$routeCollection->getRoute('home')->generateLink() ?>"></form>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
@css(/static/node_modules/tom-select/dist/css/tom-select.min.css)
|
@css(node_modules/tom-select/dist/css/tom-select.min.css)
|
||||||
@js(/static/node_modules/tom-select/dist/js/tom-select.base.min.js)
|
@js(node_modules/tom-select/dist/js/tom-select.base.min.js)
|
||||||
@js(js/communities/community_members.js)
|
@js(js/communities/community_members.js)
|
||||||
|
|
||||||
@extends(templates/layout_normal)
|
@extends(templates/layout_normal)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@css(/static/node_modules/tom-select/dist/css/tom-select.min.css)
|
@css(node_modules/tom-select/dist/css/tom-select.min.css)
|
||||||
@js(/static/node_modules/tom-select/dist/js/tom-select.base.min.js)
|
@js(node_modules/tom-select/dist/js/tom-select.base.min.js)
|
||||||
@js(js/communities/transaction.js)
|
@js(js/communities/transaction.js)
|
||||||
|
|
||||||
@extends(templates/layout_normal)
|
@extends(templates/layout_normal)
|
||||||
@@ -7,11 +7,11 @@
|
|||||||
@section(main)
|
@section(main)
|
||||||
<h2>
|
<h2>
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communitySlug' => $community->getSlug()]) ?>"><?= $community->getName() ?></a> »
|
<a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communitySlug' => $community->getSlug()]) ?>"><?= $community->getName() ?></a> »
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug()]) ?>">Transactions</a> »
|
|
||||||
<?php if (isset($event)): ?>
|
<?php if (isset($event)): ?>
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug()]) ?>">Events</a> »
|
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug()]) ?>">Events</a> »
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.event')->generateLink(['communitySlug' => $community->getSlug(), 'eventSlug' => $event->getSlug()]) ?>"><?= $event->getTitle() ?></a> »
|
<a href="<?= Container::$routeCollection->getRoute('community.event')->generateLink(['communitySlug' => $community->getSlug(), 'eventSlug' => $event->getSlug()]) ?>"><?= $event->getTitle() ?></a> »
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'event' => isset($event) ? $event->getSlug() : null]) ?>">Transactions</a> »
|
||||||
<?php if (isset($transaction)): ?>
|
<?php if (isset($transaction)): ?>
|
||||||
Edit transaction
|
Edit transaction
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
@@ -36,16 +36,23 @@
|
|||||||
<select class="big fullWidth" name="payer_user_id" required>
|
<select class="big fullWidth" name="payer_user_id" required>
|
||||||
<option value="" hidden></option>
|
<option value="" hidden></option>
|
||||||
<?php foreach ($members as $member): ?>
|
<?php foreach ($members as $member): ?>
|
||||||
<option value="<?= $member->getUser()->getId() ?>" <?= isset($transaction) && $transaction->getPayerUserId() === $member->getUser()->getId() ? 'selected' : '' ?>><?= $member->getUser()->getDisplayName() ?></option>
|
<option value="<?= $member->getUser()->getId() ?>"
|
||||||
|
<?= isset($transaction) ?
|
||||||
|
($transaction->getPayerUserId() === $member->getUser()->getId() ? 'selected' : '') :
|
||||||
|
(Container::$request->user()->getUniqueId() == $member->getUser()->getId() ? 'selected' : '') ?>>
|
||||||
|
<?= $member->getUser()->getDisplayName() ?>
|
||||||
|
</option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
<p class="formLabel marginTop">Payee</p>
|
<p class="formLabel marginTop">Payee(s)</p>
|
||||||
<select class="big fullWidth" name="payee_user_id">
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); grid-gap: 10px;">
|
||||||
<option value="">[common]</option>
|
|
||||||
<?php foreach ($members as $member): ?>
|
<?php foreach ($members as $member): ?>
|
||||||
<option value="<?= $member->getUser()->getId() ?>" <?= isset($transaction) && $transaction->getPayeeUserId() === $member->getUser()->getId() ? 'selected' : '' ?>><?= $member->getUser()->getDisplayName() ?></option>
|
<div style="text-align: center;">
|
||||||
|
<input id="payee_<?= $member->getUserId() ?>" type="checkbox" name="payee_user_ids[]" value="<?= $member->getUserId() ?>" <?= !isset($transaction) || count($payeeUserIds) === 0 || in_array($member->getUserId(), $payeeUserIds) ? 'checked' : '' ?>><!--
|
||||||
|
--><label for="payee_<?= $member->getUserId() ?>"><?= $member->getUser()->getDisplayName() ?></label>
|
||||||
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</div>
|
||||||
<p class="formLabel marginTop">Description</p>
|
<p class="formLabel marginTop">Description</p>
|
||||||
<input type="text" class="text big fullWidth" name="description" value="<?= isset($transaction) ? $transaction->getDescription() : '' ?>" required>
|
<input type="text" class="text big fullWidth" name="description" value="<?= isset($transaction) ? $transaction->getDescription() : '' ?>" required>
|
||||||
<p class="formLabel marginTop">Sum</p>
|
<p class="formLabel marginTop">Sum</p>
|
||||||
|
|||||||
@@ -13,20 +13,13 @@
|
|||||||
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.transactions.new')->generateLink(['communitySlug' => $community->getSlug(), 'event' => isset($event) ? $event->getSlug() : null]) ?>">New transaction</a></p>
|
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.transactions.new')->generateLink(['communitySlug' => $community->getSlug(), 'event' => isset($event) ? $event->getSlug() : null]) ?>">New transaction</a></p>
|
||||||
|
|
||||||
<?php if ($numberOfTransactions > 0): ?>
|
<?php if ($numberOfTransactions > 0): ?>
|
||||||
|
<?php
|
||||||
|
$paginationRouteId = 'community.transactions';
|
||||||
|
$paginationRouteParams = ['communitySlug' => $community->getSlug()];
|
||||||
|
?>
|
||||||
|
|
||||||
<?php if ($pages > 1): ?>
|
<?php if ($pages > 1): ?>
|
||||||
<p class="paginateContainer marginTop">
|
@include(templates/pagination)
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => 0]) ?>">«</a>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => max(0, $currentPage - 1)]) ?>">‹</a>
|
|
||||||
<?php for ($i = 0; $i < $pages; $i++): ?>
|
|
||||||
<?php if ($currentPage == $i): ?>
|
|
||||||
<span class="selected"><?= $i + 1 ?></span>
|
|
||||||
<?php else: ?>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => $i]) ?>"><?= $i + 1 ?></a>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php endfor; ?>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => min($pages - 1, $currentPage + 1)]) ?>">›</a>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => $pages - 1]) ?>">»</a>
|
|
||||||
</p>
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php foreach ($transactions as $transaction): ?>
|
<?php foreach ($transactions as $transaction): ?>
|
||||||
@@ -37,7 +30,29 @@
|
|||||||
<p><span class="label"><?= $transaction->getEvent()->getTitle() ?></span></p>
|
<p><span class="label"><?= $transaction->getEvent()->getTitle() ?></span></p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<p style="font-weight: bold;"><?= $transaction->getDescription() ?></p>
|
<p style="font-weight: bold;"><?= $transaction->getDescription() ?></p>
|
||||||
<p class="small"><?= $transaction->getPayerUser()->getDisplayName() ?> <i class="fa-solid fa-caret-right"></i> <?= $transaction->getPayeeUser() ? $transaction->getPayeeUser()->getDisplayName() : '[common]' ?></p>
|
<p class="small">
|
||||||
|
<?= $transaction->getPayerUser()->getDisplayName() ?>
|
||||||
|
<i class="fa-solid fa-caret-right"></i>
|
||||||
|
<?php foreach ($members as $member): ?>
|
||||||
|
<?php
|
||||||
|
if (count($transaction->getPayees()) > 0) {
|
||||||
|
$found = false;
|
||||||
|
foreach ($transaction->getPayees() as $payee) {
|
||||||
|
if ($member->getUserId() === $payee->getUserId()) {
|
||||||
|
$found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$found = true;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if ($found): ?>
|
||||||
|
<?= $member->getUser()->getDisplayName() ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<span class="gray" style="text-decoration: line-through;"><?= $member->getUser()->getDisplayName() ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</p>
|
||||||
<p class="small"><?= $transaction->getTimeDate()->format('Y-m-d H:i') ?></p>
|
<p class="small"><?= $transaction->getTimeDate()->format('Y-m-d H:i') ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: right;">
|
<div style="text-align: right;">
|
||||||
@@ -51,19 +66,7 @@
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
<?php if ($pages > 1): ?>
|
<?php if ($pages > 1): ?>
|
||||||
<p class="paginateContainer marginTop">
|
@include(templates/pagination)
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => 0]) ?>">«</a>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => max(0, $currentPage - 1)]) ?>">‹</a>
|
|
||||||
<?php for ($i = 0; $i < $pages; $i++): ?>
|
|
||||||
<?php if ($currentPage == $i): ?>
|
|
||||||
<span class="selected"><?= $i + 1 ?></span>
|
|
||||||
<?php else: ?>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => $i]) ?>"><?= $i + 1 ?></a>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php endfor; ?>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => min($pages - 1, $currentPage + 1)]) ?>">›</a>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.transactions')->generateLink(['communitySlug' => $community->getSlug(), 'page' => $pages - 1]) ?>">»</a>
|
|
||||||
</p>
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.transactions.new')->generateLink(['communitySlug' => $community->getSlug(), 'event' => isset($event) ? $event->getSlug() : null]) ?>">New transaction</a></p>
|
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.transactions.new')->generateLink(['communitySlug' => $community->getSlug(), 'event' => isset($event) ? $event->getSlug() : null]) ?>">New transaction</a></p>
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
@extends(templates/layout_normal)
|
||||||
|
|
||||||
|
@section(main)
|
||||||
|
<h2>No event found</h2>
|
||||||
|
<div class="box compactBox">
|
||||||
|
<p class="error justify">No upcoming or recent event was found. <a href="<?= Container::$routeCollection->getRoute('home')->generateLink() ?>" title="<?= $_ENV['APP_NAME'] ?>">Back to start.</a></p>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
@@ -22,6 +22,33 @@
|
|||||||
<td class="mono" style="text-align: right;"><?= number_format($totalCost, $mainCurrencyRoundDigits) ?> <?= $mainCurrencyCode ?></td>
|
<td class="mono" style="text-align: right;"><?= number_format($totalCost, $mainCurrencyRoundDigits) ?> <?= $mainCurrencyCode ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<table class="fullWidth marginTop">
|
||||||
|
<tr>
|
||||||
|
<td class="bold">You owe*</td>
|
||||||
|
<td class="mono red" style="text-align: right;"><?= number_format($debtBalance, $mainCurrencyRoundDigits) ?> <?= $mainCurrencyCode ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach ($debtItems as $item): ?>
|
||||||
|
<tr>
|
||||||
|
<td class="small"><?= $item['payee']->getUser()->getDisplayName() ?></td>
|
||||||
|
<td class="small mono red" style="text-align: right;"><?= number_format($item['amount'], $mainCurrencyRoundDigits) ?> <?= $mainCurrencyCode ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<tr>
|
||||||
|
<td class="bold">You're owed*</td>
|
||||||
|
<td class="mono green" style="text-align: right;"><?= number_format($outstandingBalance, $mainCurrencyRoundDigits) ?> <?= $mainCurrencyCode ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach ($outstandingItems as $item): ?>
|
||||||
|
<tr>
|
||||||
|
<td class="small"><?= $item['payer']->getUser()->getDisplayName() ?></td>
|
||||||
|
<td class="small mono green" style="text-align: right;"><?= number_format($item['amount'], $mainCurrencyRoundDigits) ?> <?= $mainCurrencyCode ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<tr>
|
||||||
|
<td class="bold">Your balance*</td>
|
||||||
|
<td class="mono <?= $balance < 0 ? 'red' : ($balance > 0 ? 'green' : '') ?>" style="text-align: right;;"><?= number_format($balance, $mainCurrencyRoundDigits) ?> <?= $mainCurrencyCode ?></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p class="small right">* Virtual balance only for this event. Check <a href="<?= Container::$routeCollection->getRoute('community')->generateLink(['communitySlug' => $community->getSlug()]) ?>">community</a> finances for your real balance.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
+7
-26
@@ -9,20 +9,13 @@
|
|||||||
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.events.new')->generateLink(['communitySlug' => $community->getSlug()]) ?>">New event</a></p>
|
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.events.new')->generateLink(['communitySlug' => $community->getSlug()]) ?>">New event</a></p>
|
||||||
|
|
||||||
<?php if ($numberOfEvents > 0): ?>
|
<?php if ($numberOfEvents > 0): ?>
|
||||||
|
<?php
|
||||||
|
$paginationRouteId = 'community.events';
|
||||||
|
$paginationRouteParams = ['communitySlug' => $community->getSlug()];
|
||||||
|
?>
|
||||||
|
|
||||||
<?php if ($pages > 1): ?>
|
<?php if ($pages > 1): ?>
|
||||||
<p class="paginateContainer marginTop">
|
@include(templates/pagination)
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => 0]) ?>">«</a>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => max(0, $currentPage - 1)]) ?>">‹</a>
|
|
||||||
<?php for ($i = 0; $i < $pages; $i++): ?>
|
|
||||||
<?php if ($currentPage == $i): ?>
|
|
||||||
<span class="selected"><?= $i + 1 ?></span>
|
|
||||||
<?php else: ?>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => $i]) ?>"><?= $i + 1 ?></a>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php endfor; ?>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => min($pages - 1, $currentPage + 1)]) ?>">›</a>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => $pages - 1]) ?>">»</a>
|
|
||||||
</p>
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php foreach ($events as $event): ?>
|
<?php foreach ($events as $event): ?>
|
||||||
@@ -36,19 +29,7 @@
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
|
||||||
<?php if ($pages > 1): ?>
|
<?php if ($pages > 1): ?>
|
||||||
<p class="paginateContainer marginTop">
|
@include(templates/pagination)
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => 0]) ?>">«</a>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => max(0, $currentPage - 1)]) ?>">‹</a>
|
|
||||||
<?php for ($i = 0; $i < $pages; $i++): ?>
|
|
||||||
<?php if ($currentPage == $i): ?>
|
|
||||||
<span class="selected"><?= $i + 1 ?></span>
|
|
||||||
<?php else: ?>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => $i]) ?>"><?= $i + 1 ?></a>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php endfor; ?>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => min($pages - 1, $currentPage + 1)]) ?>">›</a>
|
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.events')->generateLink(['communitySlug' => $community->getSlug(), 'page' => $pages - 1]) ?>">»</a>
|
|
||||||
</p>
|
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.events.new')->generateLink(['communitySlug' => $community->getSlug()]) ?>">New event</a></p>
|
<p class="marginTop"><a href="<?= Container::$routeCollection->getRoute('community.events.new')->generateLink(['communitySlug' => $community->getSlug()]) ?>">New event</a></p>
|
||||||
|
|||||||
+4
-4
@@ -16,9 +16,9 @@
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="marginBottom">Upcoming events</h3>
|
<h3 class="marginBottom">Upcoming and recent events</h3>
|
||||||
<?php if (count($upcomingEvents) > 0): ?>
|
<?php if (count($upcomingAndRecentEvents) > 0): ?>
|
||||||
<?php foreach ($upcomingEvents as $event): ?>
|
<?php foreach ($upcomingAndRecentEvents as $event): ?>
|
||||||
<p>
|
<p>
|
||||||
<a href="<?= Container::$routeCollection->getRoute('community.event')->generateLink(['communitySlug' => $event->getCommunity()->getSlug(), 'eventSlug' => $event->getSlug()]) ?>"><?= $event->getTitle() ?></a>
|
<a href="<?= Container::$routeCollection->getRoute('community.event')->generateLink(['communitySlug' => $event->getCommunity()->getSlug(), 'eventSlug' => $event->getSlug()]) ?>"><?= $event->getTitle() ?></a>
|
||||||
<span class="small">
|
<span class="small">
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<p>There is no upcoming event.</p>
|
<p>There is no event to show.</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<p class="paginateContainer marginTop">
|
||||||
|
<a href="<?= Container::$routeCollection->getRoute($paginationRouteId)->generateLink(array_merge($paginationRouteParams, ['page' => 1])) ?>">«</a>
|
||||||
|
<a href="<?= Container::$routeCollection->getRoute($paginationRouteId)->generateLink(array_merge($paginationRouteParams, ['page' => max(1, $currentPage - 1)])) ?>">‹</a>
|
||||||
|
<?php
|
||||||
|
$maxPages = 7;
|
||||||
|
if ($pages <= $maxPages) {
|
||||||
|
$start = 1;
|
||||||
|
$end = $pages;
|
||||||
|
} else {
|
||||||
|
$maxAdditionalPages = $maxPages - 1;
|
||||||
|
$maxAdditionalPagesHalf = ceil($maxAdditionalPages / 2);
|
||||||
|
$start = $currentPage - $maxAdditionalPagesHalf > 1 ?
|
||||||
|
($currentPage - $maxAdditionalPagesHalf < $pages - $maxAdditionalPages ?
|
||||||
|
$currentPage - $maxAdditionalPagesHalf :
|
||||||
|
$pages - $maxAdditionalPages) :
|
||||||
|
1;
|
||||||
|
$end = $start + $maxAdditionalPages < $pages ?
|
||||||
|
$start + $maxAdditionalPages :
|
||||||
|
$pages;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php for ($i = $start; $i <= $end; $i++): ?>
|
||||||
|
<?php if ($currentPage == $i): ?>
|
||||||
|
<span class="selected"><?= $i ?></span>
|
||||||
|
<?php else: ?>
|
||||||
|
<a href="<?= Container::$routeCollection->getRoute($paginationRouteId)->generateLink(array_merge($paginationRouteParams, ['page' => $i])) ?>"><?= $i ?></a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endfor; ?>
|
||||||
|
<a href="<?= Container::$routeCollection->getRoute($paginationRouteId)->generateLink(array_merge($paginationRouteParams, ['page' => min($pages, $currentPage + 1)])) ?>">›</a>
|
||||||
|
<a href="<?= Container::$routeCollection->getRoute($paginationRouteId)->generateLink(array_merge($paginationRouteParams, ['page' => $pages])) ?>">»</a>
|
||||||
|
</p>
|
||||||
@@ -13,6 +13,7 @@ use RVR\Controller\UserController;
|
|||||||
use RVR\Controller\UserSearchController;
|
use RVR\Controller\UserSearchController;
|
||||||
use RVR\Controller\CommunityController;
|
use RVR\Controller\CommunityController;
|
||||||
use RVR\Controller\TransactionController;
|
use RVR\Controller\TransactionController;
|
||||||
|
use RVR\Controller\EventRedirectController;
|
||||||
use RVR\Controller\EventController;
|
use RVR\Controller\EventController;
|
||||||
use RVR\Repository\UserRepository;
|
use RVR\Repository\UserRepository;
|
||||||
|
|
||||||
@@ -62,6 +63,10 @@ Container::$routeCollection->group('account', function (RouteCollection $routeCo
|
|||||||
$routeCollection->get('account.googleAuthenticate-action', 'googleAuthenticate/code', [UserController::class, 'authenticateWithGoogle']);
|
$routeCollection->get('account.googleAuthenticate-action', 'googleAuthenticate/code', [UserController::class, 'authenticateWithGoogle']);
|
||||||
});
|
});
|
||||||
Container::$routeCollection->get('searchUser', 'searchUser', [UserSearchController::class, 'searchUser']);
|
Container::$routeCollection->get('searchUser', 'searchUser', [UserSearchController::class, 'searchUser']);
|
||||||
|
Container::$routeCollection->group('now', function (RouteCollection $routeCollection) {
|
||||||
|
$routeCollection->get('now.event', '', [EventRedirectController::class, 'getEvent']);
|
||||||
|
$routeCollection->get('now.transactions.new', 'transactions/new', [EventRedirectController::class, 'getEventNewTransaction']);
|
||||||
|
});
|
||||||
Container::$routeCollection->group('communities', function (RouteCollection $routeCollection) {
|
Container::$routeCollection->group('communities', function (RouteCollection $routeCollection) {
|
||||||
$routeCollection->get('community.new', 'new', [CommunityController::class, 'getCommunityNew']);
|
$routeCollection->get('community.new', 'new', [CommunityController::class, 'getCommunityNew']);
|
||||||
$routeCollection->post('community.new-action', 'new', [CommunityController::class, 'saveCommunity']);
|
$routeCollection->post('community.new-action', 'new', [CommunityController::class, 'saveCommunity']);
|
||||||
@@ -70,6 +75,7 @@ Container::$routeCollection->group('communities', function (RouteCollection $rou
|
|||||||
$routeCollection->get('community.settings', 'settings', [CommunityController::class, 'getCommunitySettings']);
|
$routeCollection->get('community.settings', 'settings', [CommunityController::class, 'getCommunitySettings']);
|
||||||
$routeCollection->get('community.edit', 'edit', [CommunityController::class, 'getCommunityEdit']);
|
$routeCollection->get('community.edit', 'edit', [CommunityController::class, 'getCommunityEdit']);
|
||||||
$routeCollection->post('community.edit-action', 'edit', [CommunityController::class, 'saveCommunity']);
|
$routeCollection->post('community.edit-action', 'edit', [CommunityController::class, 'saveCommunity']);
|
||||||
|
$routeCollection->post('community.delete-action', 'delete', [CommunityController::class, 'deleteCommunity']);
|
||||||
$routeCollection->get('community.members', 'members', [CommunityController::class, 'getMembersEdit']);
|
$routeCollection->get('community.members', 'members', [CommunityController::class, 'getMembersEdit']);
|
||||||
$routeCollection->post('community.members.new-action', 'members/new', [CommunityController::class, 'saveMember']);
|
$routeCollection->post('community.members.new-action', 'members/new', [CommunityController::class, 'saveMember']);
|
||||||
$routeCollection->post('community.members.edit-action', 'members/edit', [CommunityController::class, 'saveMember']);
|
$routeCollection->post('community.members.edit-action', 'members/edit', [CommunityController::class, 'saveMember']);
|
||||||
|
|||||||
Reference in new issue
Block a user