RVRNEXT-7 add BalanceCalculator class
This commit is contained in:
parent
ae3554c365
commit
3fd43b6e41
90
src/Finance/BalanceCalculator.php
Normal file
90
src/Finance/BalanceCalculator.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php namespace RVR\Finance;
|
||||
|
||||
use RVR\PersistentData\Model\Community;
|
||||
use RVR\Repository\CommunityMemberRepository;
|
||||
use RVR\Repository\TransactionRepository;
|
||||
|
||||
class BalanceCalculator
|
||||
{
|
||||
private Community $community;
|
||||
|
||||
private TransactionRepository $transactionRepository;
|
||||
|
||||
private CommunityMemberRepository $communityMemberRepository;
|
||||
|
||||
private ExchangeRateCalculator $exchangeRateCalculator;
|
||||
|
||||
private array $members;
|
||||
|
||||
private array $payments;
|
||||
|
||||
public function __construct(Community $community)
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user