Failed Conditions
Push — master ( 51347b...4787ce )
by Adrien
08:37
created

Transaction   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Test Coverage

Coverage 96%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 38
c 2
b 0
f 0
dl 0
loc 203
ccs 48
cts 50
cp 0.96
rs 10
wmc 20

14 Methods

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