Completed
Push — master ( a3d745...cdb5f9 )
by Adrien
10:34
created

Transaction::accountingDocumentAdded()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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