Failed Conditions
Push — master ( 9e07c2...acb8eb )
by Adrien
07:10
created

TransactionRepository::hydrateLinesAndFlush()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 20
nc 6
nop 2
dl 0
loc 33
rs 8.9777
c 0
b 0
f 0
ccs 21
cts 21
cp 1
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\Api\Exception;
8
use Application\Api\Helper;
9
use Application\Model\Transaction;
10
use Application\Model\TransactionLine;
11
use Application\Model\User;
12
13
class TransactionRepository extends AbstractRepository implements LimitedAccessSubQueryInterface
14
{
15
    /**
16
     * Returns pure SQL to get ID of all objects that are accessible to given user.
17
     *
18
     * @param null|User $user
19
     *
20
     * @return string
21
     */
22 6
    public function getAccessibleSubQuery(?User $user): string
23
    {
24 6
        if (!$user) {
25 1
            return '-1';
26
        }
27
28 5
        if (in_array($user->getRole(), [User::ROLE_RESPONSIBLE, User::ROLE_ADMINISTRATOR], true)) {
29 2
            return $this->getAllIdsQuery();
30
        }
31
32
        return 'SELECT transaction.id FROM transaction
33
              JOIN transaction_line ON transaction.id = transaction_line.transaction_id
34
              JOIN account ON transaction_line.debit_id = account.id OR transaction_line.credit_id = account.id 
35 3
              WHERE account.owner_id = ' . $user->getId();
36
    }
37
38
    /**
39
     * @param Transaction $transaction
40
     * @param array $lines
41
     */
42 6
    public function hydrateLinesAndFlush(Transaction $transaction, array $lines): void
43
    {
44 6
        if (!$lines) {
45 1
            throw new Exception('A Transaction must have at least one TransactionLine');
46
        }
47
48
        // Destroy all previously existing TransactionLine
49
        $transaction->getTransactionLines()->forAll(function (int $index, TransactionLine $line): void {
50 2
            $this->getEntityManager()->remove($line);
51 5
        });
52 5
        $transaction->getTransactionLines()->clear();
53
54 5
        $accounts = [];
55 5
        foreach ($lines as $line) {
56 5
            $transactionLine = new TransactionLine();
57 5
            Helper::hydrate($transactionLine, $line);
58 5
            if (!$transactionLine->getCredit() && !$transactionLine->getDebit()) {
59 2
                throw new Exception('Cannot create a TransactionLine without any account');
60
            }
61 3
            $accounts[] = $transactionLine->getCredit();
62 3
            $accounts[] = $transactionLine->getDebit();
63
64 3
            $transactionLine->setTransaction($transaction);
65 3
            _em()->persist($transactionLine);
66
        }
67
68 3
        _em()->persist($transaction);
69 3
        _em()->flush();
70
71
        // Be sure to refresh the new account balance that were computed by DB triggers
72 3
        $accounts = array_filter(array_unique($accounts, SORT_REGULAR));
73 3
        foreach ($accounts as $account) {
74 3
            _em()->refresh($account);
75
        }
76 3
    }
77
}
78