TransactionLineRepository::importedExists()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
ccs 7
cts 7
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\Model\Account;
8
use Application\Model\TransactionLine;
9
use Application\Model\User;
10
use Cake\Chronos\Chronos;
11
use Cake\Chronos\ChronosDate;
12
use Ecodev\Felix\Api\Exception;
13
use Ecodev\Felix\Repository\LimitedAccessSubQuery;
14
15
use Money\Money;
16
17
/**
18
 * @extends AbstractRepository<TransactionLine>
19
 */
20
class TransactionLineRepository extends AbstractRepository implements LimitedAccessSubQuery
21
{
22
    /**
23
     * Returns pure SQL to get ID of all objects that are accessible to given user.
24
     *
25
     * @param null|User $user
26
     */
27 28
    public function getAccessibleSubQuery(?\Ecodev\Felix\Model\User $user): string
28
    {
29 28
        if (!$user) {
30 1
            return '-1';
31
        }
32
33 27
        if (in_array($user->getRole(), [User::ROLE_ACCOUNTING_VERIFICATOR, User::ROLE_RESPONSIBLE, User::ROLE_ADMINISTRATOR], true)) {
34 24
            return '';
35
        }
36
37 3
        if ($user->getOwner()) {
38 1
            $id = $user->getOwner()->getId();
39
        } else {
40 2
            $id = $user->getId();
41
        }
42
43 3
        return 'SELECT transaction_line.id FROM transaction_line
44
              JOIN account ON transaction_line.debit_id = account.id OR transaction_line.credit_id = account.id 
45 3
              WHERE account.owner_id = ' . $id;
46
    }
47
48
    /**
49
     * Compute the total balance by credit or debit account and date range.
50
     *
51
     * @param null|ChronosDate $dateStart the lines from this date, included
52
     * @param null|ChronosDate $dateEnd the line until this date, included
53
     */
54 4
    public function totalBalance(?Account $debitAccount, ?Account $creditAccount, ?ChronosDate $dateStart = null, ?ChronosDate $dateEnd = null): Money
55
    {
56 4
        if ($debitAccount === null && $creditAccount === null) {
57
            throw new Exception('At least one debit or credit account is needed to compute the total balance');
58
        }
59
60 4
        $qb = $this->getEntityManager()->getConnection()->createQueryBuilder()
61 4
            ->select('SUM(balance)')
62 4
            ->from('transaction_line');
63
64 4
        if ($debitAccount) {
65 4
            $qb->andWhere('debit_id = :debit')
66 4
                ->setParameter('debit', $debitAccount->getId());
67
        }
68
69 4
        if ($creditAccount) {
70 4
            $qb->andWhere('credit_id = :credit')
71 4
                ->setParameter('credit', $creditAccount->getId());
72
        }
73
74 4
        if ($dateStart) {
75 1
            $qb->andWhere('DATE(transaction_date) >= :dateStart')
76 1
                ->setParameter('dateStart', $dateStart);
77
        }
78
79 4
        if ($dateEnd) {
80 4
            $qb->andWhere('DATE(transaction_date) <= :dateEnd')
81 4
                ->setParameter('dateEnd', $dateEnd);
82
        }
83
84 4
        $result = $qb->executeQuery();
85
86 4
        return Money::CHF((int) $result->fetchOne());
87
    }
88
89 15
    public function importedExists(string $importedId, Chronos $transactionDate): bool
90
    {
91 15
        $connection = $this->getEntityManager()->getConnection();
92 15
        $count = $connection->fetchOne('SELECT COUNT(*) > 0 FROM transaction_line WHERE imported_id = :importedId AND transaction_date = :transactionDate', [
93 15
            'importedId' => $importedId,
94 15
            'transactionDate' => $transactionDate,
95 15
        ]);
96
97 15
        return (bool) $count;
98
    }
99
}
100