show balance for events #61
@ -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,
 | 
				
			||||||
            'upcomingAndRecentEvents' => iterator_to_array($this->eventRepository->getUpcomingAndRecentByCommunity($community, new DateTime(), 30, 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()
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
@ -105,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'],
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use Container;
 | 
					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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -9,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;
 | 
				
			||||||
@ -19,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());
 | 
				
			||||||
@ -32,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
 | 
				
			||||||
@ -57,7 +68,11 @@ class BalanceCalculator
 | 
				
			|||||||
    private function sumTransactions(): void
 | 
					    private function sumTransactions(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $membersCount = count($this->members);
 | 
					        $membersCount = count($this->members);
 | 
				
			||||||
 | 
					        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']));
 | 
					            $transactions = iterator_to_array($this->transactionRepository->getAllByCommunity($this->community, true, ['currency']));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        Container::$persistentDataManager->loadMultiRelationsFromDb($transactions, 'payees');
 | 
					        Container::$persistentDataManager->loadMultiRelationsFromDb($transactions, 'payees');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($transactions as $transaction) {
 | 
					        foreach ($transactions as $transaction) {
 | 
				
			||||||
@ -77,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
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user