diff --git a/public/static/css/rvr.css b/public/static/css/rvr.css index b1bb9a9..8d30b86 100644 --- a/public/static/css/rvr.css +++ b/public/static/css/rvr.css @@ -31,7 +31,7 @@ main { color: #ffffff; } -::placeholder, select > option[value=""] { +::placeholder, select > option[value=""], .gray { color: #8e8e8e; } @@ -67,7 +67,7 @@ p, h2, h3 { line-height: 150%; } -p { +p, th, td { font-weight: 400; font-size: 16px; } @@ -104,10 +104,23 @@ hr { font-weight: 700; } -p.small, span.small { +p.small, span.small, td.small { font-size: 14px; } +.red { + color: #a80908; +} + +.green { + color: #008000; +} + +.mono { + font-family: 'Oxygen Mono', mono; + font-weight: 400; +} + .justify { text-align: justify; } diff --git a/src/Controller/CommunityController.php b/src/Controller/CommunityController.php index 1a853e9..30b90be 100644 --- a/src/Controller/CommunityController.php +++ b/src/Controller/CommunityController.php @@ -1,6 +1,7 @@ loadRelationsFromDb($community, false, ['main_currency']); + $balanceCalculator = new BalanceCalculator($community); + $debts = $balanceCalculator->calculate(); + $debtUsers = []; + $debtBalance = 0.0; + $outstandingUsers = []; + $outstandingBalance = 0.0; + foreach ($debts as $debt) { + if ($debt['payer']->getId() === \Container::$request->user()->getUniqueId()) { + $debtBalance += $debt['amount']; + $debtUsers[] = $debt; + } + if ($debt['payee']->getId() === \Container::$request->user()->getUniqueId()) { + $outstandingBalance += $debt['amount']; + $outstandingUsers[] = $debt; + } + } + $balance = $outstandingBalance - $debtBalance; + return new HtmlContent('communities/community', [ 'community' => $community, 'members' => $this->getMembers($community), 'currencies' => $this->getCurrencies($community), 'upcomingEvents' => [], + 'debtUsers' => $debtUsers, + 'debtBalance' => $debtBalance, + 'outstandingUsers' => $outstandingUsers, + 'outstandingBalance' => $outstandingBalance, + 'balance' => $balance, 'editPermission' => $ownCommunityMember->getOwner() ]); } diff --git a/src/Finance/BalanceCalculator.php b/src/Finance/BalanceCalculator.php new file mode 100644 index 0000000..6842b0f --- /dev/null +++ b/src/Finance/BalanceCalculator.php @@ -0,0 +1,90 @@ +community = $community; + $this->transactionRepository = new TransactionRepository(); + $this->communityMemberRepository = new CommunityMemberRepository(); + $this->exchangeRateCalculator = new ExchangeRateCalculator($this->community->getMainCurrency()); + } + + public function calculate(): array + { + $this->collectMembers(); + $this->createPaymentsMatrix(); + $this->sumTransactions(); + return $this->calculateActualDebts(); + } + + private function collectMembers(): void + { + $this->members = []; + foreach ($this->communityMemberRepository->getAllByCommunity($this->community, true, ['user']) as $member) { + $this->members[$member->getUserId()] = $member; + } + } + + private function createPaymentsMatrix(): void + { + $this->payments = []; + foreach ($this->members as $payerUserId => $member) { + $this->payments[$payerUserId] = []; + foreach ($this->members as $payeeUserId => $member) { + $this->payments[$payerUserId][$payeeUserId] = 0; + } + } + } + + private function sumTransactions(): void + { + $membersCount = count($this->members); + $transactions = $this->transactionRepository->getAllByCommunity($this->community, true, ['currency']); + + foreach ($transactions as $transaction) { + $sum = $this->exchangeRateCalculator->calculate($transaction->getSum(), $transaction->getCurrency(), $transaction->getTimeDate()); + + if ($transaction->getPayeeUserId()) { + $this->payments[$transaction->getPayerUserId()][$transaction->getPayeeUserId()] += $sum; + } else { + foreach ($this->members as $payeeUserId => $member) { + $this->payments[$transaction->getPayerUserId()][$payeeUserId] += $sum / $membersCount; + } + } + } + } + + private function calculateActualDebts(): array + { + $actualDebts = []; + + foreach ($this->payments as $payerUserId => $paymentsOfPayer) { + foreach ($paymentsOfPayer as $payeeUserId => $sum) { + $actualDebt = $this->payments[$payeeUserId][$payerUserId] - $sum; + + if (round($actualDebt, $this->community->getMainCurrency()->getRoundDigits()) > 0.0) { + $actualDebts[] = ['payer' => $this->members[$payerUserId], 'payee' => $this->members[$payeeUserId], 'amount' => $actualDebt]; + } + } + } + + return $actualDebts; + } +} diff --git a/views/communities/community.php b/views/communities/community.php index 826b724..fe8bc40 100644 --- a/views/communities/community.php +++ b/views/communities/community.php @@ -46,18 +46,31 @@ $mainCurrencyRoundDigits = $community->getMainCurrency()->getRoundDigits(); ?>
You owe | -= number_format(0, $mainCurrencyRoundDigits) ?> = $mainCurrencyCode ?> | +You owe | += number_format($debtBalance, $mainCurrencyRoundDigits) ?> = $mainCurrencyCode ?> |
= $owe['payee']->getUser()->getDisplayName() ?> | += number_format($owe['amount'], $mainCurrencyRoundDigits) ?> = $mainCurrencyCode ?> | +||
You're owed | -= number_format(0, $mainCurrencyRoundDigits) ?> = $mainCurrencyCode ?> | +You're owed | += number_format($outstandingBalance, $mainCurrencyRoundDigits) ?> = $mainCurrencyCode ?> |
= $owe['payer']->getUser()->getDisplayName() ?> | += number_format($owe['amount'], $mainCurrencyRoundDigits) ?> = $mainCurrencyCode ?> | +||
Your balance | -= number_format(0, $mainCurrencyRoundDigits) ?> = $mainCurrencyCode ?> | +Your balance | += number_format($balance, $mainCurrencyRoundDigits) ?> = $mainCurrencyCode ?> |