Failed Conditions
Push — master ( 68f81c...e8ee36 )
by Adrien
09:22
created

Transaction   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 179
Duplicated Lines 0 %

Test Coverage

Coverage 96.08%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 20
eloc 39
c 2
b 0
f 0
dl 0
loc 179
ccs 49
cts 51
cp 0.9608
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A transactionLineAdded() 0 3 1
A accountingDocumentRemoved() 0 3 1
A getTransactionLines() 0 3 1
A getAccountingDocuments() 0 3 1
A __construct() 0 5 1
A getExpenseClaim() 0 3 1
A setDatatransRef() 0 3 1
A getDatatransRef() 0 3 1
A checkBalance() 0 15 5
A transactionLineRemoved() 0 3 1
A setTransactionDate() 0 3 1
A getTransactionDate() 0 3 1
A setExpenseClaim() 0 11 3
A accountingDocumentAdded() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Model;
6
7
use Application\DBAL\Types\ExpenseClaimStatusType;
8
use Application\Traits\HasAutomaticUnsignedBalance;
9
use Application\Traits\HasRemarks;
10
use Cake\Chronos\Chronos;
11
use Doctrine\Common\Collections\ArrayCollection;
12
use Doctrine\Common\Collections\Collection;
13
use Doctrine\ORM\Mapping as ORM;
14
use Ecodev\Felix\Format;
15
use Ecodev\Felix\Model\Traits\HasInternalRemarks;
16
use Ecodev\Felix\Model\Traits\HasName;
17
use Money\Money;
18
19
/**
20
 * An accounting journal entry (simple or compound)
21
 *
22
 * @ORM\Entity(repositoryClass="Application\Repository\TransactionRepository")
23
 * @ORM\HasLifecycleCallbacks
24
 */
25
class Transaction extends AbstractModel
26
{
27
    use HasName;
28
    use HasRemarks;
29
    use HasInternalRemarks;
30
    use HasAutomaticUnsignedBalance;
31
32
    /**
33
     * @var Chronos
34
     * @ORM\Column(type="datetime")
35
     */
36
    private $transactionDate;
37
38
    /**
39
     * @var Collection
40
     * @ORM\OneToMany(targetEntity="TransactionLine", mappedBy="transaction")
41
     */
42
    private $transactionLines;
43
44
    /**
45
     * @var Collection
46
     * @ORM\OneToMany(targetEntity="AccountingDocument", mappedBy="transaction")
47
     */
48
    private $accountingDocuments;
49
50
    /**
51
     * @var null|ExpenseClaim
52
     *
53
     * @ORM\ManyToOne(targetEntity="ExpenseClaim", inversedBy="transactions")
54
     * @ORM\JoinColumns({
55
     *     @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
56
     * })
57
     */
58
    private $expenseClaim;
59
60
    /**
61
     * @var string
62
     *
63
     * @ORM\Column(type="string", length=18, options={"default" = ""})
64
     */
65
    private $datatransRef = '';
66
67
    /**
68
     * Constructor
69
     */
70 28
    public function __construct()
71
    {
72 28
        $this->balance = Money::CHF(0);
73 28
        $this->transactionLines = new ArrayCollection();
74 28
        $this->accountingDocuments = new ArrayCollection();
75 28
    }
76
77
    /**
78
     * Set date of transaction
79
     */
80 20
    public function setTransactionDate(Chronos $transactionDate): void
81
    {
82 20
        $this->transactionDate = $transactionDate;
83 20
    }
84
85
    /**
86
     * Get date of transaction
87
     */
88 9
    public function getTransactionDate(): Chronos
89
    {
90 9
        return $this->transactionDate;
91
    }
92
93
    /**
94
     * Notify when a transaction line is added
95
     * This should only be called by TransactionLine::setTransaction()
96
     */
97 18
    public function transactionLineAdded(TransactionLine $transactionLine): void
98
    {
99 18
        $this->transactionLines->add($transactionLine);
100 18
    }
101
102
    /**
103
     * Notify when a transaction line is removed
104
     * This should only be called by TransactionLine::setTransaction()
105
     */
106 1
    public function transactionLineRemoved(TransactionLine $transactionLine): void
107
    {
108 1
        $this->transactionLines->removeElement($transactionLine);
109 1
    }
110
111 22
    public function getTransactionLines(): Collection
112
    {
113 22
        return $this->transactionLines;
114
    }
115
116
    /**
117
     * Notify the transaction that an accounting document was added
118
     * This should only be called by AccountingDocument::setTransaction()
119
     */
120 1
    public function accountingDocumentAdded(AccountingDocument $document): void
121
    {
122 1
        $this->accountingDocuments->add($document);
123 1
    }
124
125
    /**
126
     * Notify the transaction that an accounting document was removed
127
     * This should only be called by AccountingDocument::setTransaction()
128
     */
129 1
    public function accountingDocumentRemoved(AccountingDocument $document): void
130
    {
131 1
        $this->accountingDocuments->removeElement($document);
132 1
    }
133
134
    /**
135
     * Get accounting documents
136
     */
137 1
    public function getAccountingDocuments(): Collection
138
    {
139 1
        return $this->accountingDocuments;
140
    }
141
142
    /**
143
     * Set expense claim
144
     */
145 1
    public function setExpenseClaim(?ExpenseClaim $expenseClaim): void
146
    {
147 1
        if ($this->expenseClaim) {
148 1
            $this->expenseClaim->transactionRemoved($this);
149
        }
150
151 1
        $this->expenseClaim = $expenseClaim;
152
153 1
        if ($this->expenseClaim) {
154 1
            $this->expenseClaim->transactionAdded($this);
155 1
            $this->expenseClaim->setStatus(ExpenseClaimStatusType::PROCESSED);
156
        }
157 1
    }
158
159
    /**
160
     * Get expense claim
161
     */
162
    public function getExpenseClaim(): ?ExpenseClaim
163
    {
164
        return $this->expenseClaim;
165
    }
166
167
    /**
168
     * Get Datatrans payment reference number
169
     */
170 5
    public function setDatatransRef(string $datatransRef): void
171
    {
172 5
        $this->datatransRef = $datatransRef;
173 5
    }
174
175
    /**
176
     * Set Datatrans payment reference number
177
     */
178 2
    public function getDatatransRef(): string
179
    {
180 2
        return $this->datatransRef;
181
    }
182
183
    /**
184
     * Automatically called by Doctrine whenever a transaction is created or updated
185
     *
186
     * @ORM\PrePersist
187
     * @ORM\PreUpdate
188
     */
189 19
    public function checkBalance(): void
190
    {
191 19
        $totalDebit = Money::CHF(0);
192 19
        $totalCredit = Money::CHF(0);
193 19
        foreach ($this->getTransactionLines() as $i => $line) {
194 10
            if ($line->getDebit()) {
195 10
                $totalDebit = $totalDebit->add($line->getBalance());
196
            }
197 10
            if ($line->getCredit()) {
198 10
                $totalCredit = $totalCredit->add($line->getBalance());
199
            }
200
        }
201
202 19
        if (!$totalDebit->equals($totalCredit)) {
203 1
            throw new \Ecodev\Felix\Api\Exception(sprintf('Transaction %s non-équilibrée, débits: %s, crédits: %s', $this->getId() ?? 'NEW', Format::money($totalDebit), Format::money($totalCredit)));
204
        }
205 18
    }
206
}
207