1 | <?php |
||||
2 | |||||
3 | /** |
||||
4 | * AccountFactory.php |
||||
5 | * Copyright (c) 2018 [email protected] |
||||
6 | * |
||||
7 | * This file is part of Firefly III. |
||||
8 | * |
||||
9 | * Firefly III is free software: you can redistribute it and/or modify |
||||
10 | * it under the terms of the GNU General Public License as published by |
||||
11 | * the Free Software Foundation, either version 3 of the License, or |
||||
12 | * (at your option) any later version. |
||||
13 | * |
||||
14 | * Firefly III is distributed in the hope that it will be useful, |
||||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
17 | * GNU General Public License for more details. |
||||
18 | * |
||||
19 | * You should have received a copy of the GNU General Public License |
||||
20 | * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. |
||||
21 | */ |
||||
22 | |||||
23 | /** @noinspection PhpDynamicAsStaticMethodCallInspection */ |
||||
24 | /** @noinspection PhpUndefinedMethodInspection */ |
||||
25 | |||||
26 | declare(strict_types=1); |
||||
27 | |||||
28 | namespace FireflyIII\Factory; |
||||
29 | |||||
30 | use FireflyIII\Exceptions\FireflyException; |
||||
31 | use FireflyIII\Models\Account; |
||||
32 | use FireflyIII\Models\AccountType; |
||||
33 | use FireflyIII\Models\TransactionCurrency; |
||||
34 | use FireflyIII\Services\Internal\Support\AccountServiceTrait; |
||||
35 | use FireflyIII\User; |
||||
36 | use Log; |
||||
37 | |||||
38 | /** |
||||
39 | * Factory to create or return accounts. |
||||
40 | * |
||||
41 | * Class AccountFactory |
||||
42 | */ |
||||
43 | class AccountFactory |
||||
44 | { |
||||
45 | /** @var User */ |
||||
46 | private $user; |
||||
47 | |||||
48 | use AccountServiceTrait; |
||||
49 | |||||
50 | /** |
||||
51 | * AccountFactory constructor. |
||||
52 | * @codeCoverageIgnore |
||||
53 | */ |
||||
54 | public function __construct() |
||||
55 | { |
||||
56 | if ('testing' === config('app.env')) { |
||||
57 | Log::warning(sprintf('%s should not be instantiated in the TEST environment!', \get_class($this))); |
||||
58 | } |
||||
59 | } |
||||
60 | |||||
61 | /** |
||||
62 | * @param array $data |
||||
63 | * |
||||
64 | * @return Account |
||||
65 | * @throws FireflyException |
||||
66 | * @SuppressWarnings(PHPMD.CyclomaticComplexity) |
||||
67 | * @SuppressWarnings(PHPMD.ExcessiveMethodLength) |
||||
68 | */ |
||||
69 | public function create(array $data): Account |
||||
70 | { |
||||
71 | $type = $this->getAccountType($data['account_type_id'], $data['accountType']); |
||||
72 | |||||
73 | if (null === $type) { |
||||
74 | throw new FireflyException( |
||||
75 | sprintf('AccountFactory::create() was unable to find account type #%d ("%s").', $data['account_type_id'], $data['accountType']) |
||||
76 | ); |
||||
77 | } |
||||
78 | |||||
79 | $data['iban'] = $this->filterIban($data['iban']); |
||||
80 | |||||
81 | // account may exist already: |
||||
82 | $return = $this->find($data['name'], $type->type); |
||||
83 | |||||
84 | if (null === $return) { |
||||
85 | // create it: |
||||
86 | $databaseData |
||||
87 | = [ |
||||
88 | 'user_id' => $this->user->id, |
||||
89 | 'account_type_id' => $type->id, |
||||
90 | 'name' => $data['name'], |
||||
91 | 'virtual_balance' => $data['virtualBalance'] ?? '0', |
||||
92 | 'active' => true === $data['active'], |
||||
93 | 'iban' => $data['iban'], |
||||
94 | ]; |
||||
95 | |||||
96 | // find currency, or use default currency instead. |
||||
97 | /** @var TransactionCurrencyFactory $factory */ |
||||
98 | $factory = app(TransactionCurrencyFactory::class); |
||||
99 | /** @var TransactionCurrency $currency */ |
||||
100 | $currency = $factory->find((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null)); |
||||
101 | |||||
102 | if (null === $currency) { |
||||
103 | // use default currency: |
||||
104 | $currency = app('amount')->getDefaultCurrencyByUser($this->user); |
||||
105 | } |
||||
106 | $currency->enabled =true; |
||||
107 | $currency->save(); |
||||
108 | |||||
109 | unset($data['currency_code']); |
||||
110 | $data['currency_id'] = $currency->id; |
||||
111 | // remove virtual balance when not an asset account or a liability |
||||
112 | $canHaveVirtual = [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD]; |
||||
113 | if (!\in_array($type->type, $canHaveVirtual, true)) { |
||||
114 | $databaseData['virtual_balance'] = '0'; |
||||
115 | } |
||||
116 | |||||
117 | // fix virtual balance when it's empty |
||||
118 | if ('' === $databaseData['virtual_balance']) { |
||||
119 | $databaseData['virtual_balance'] = '0'; |
||||
120 | } |
||||
121 | |||||
122 | $return = Account::create($databaseData); |
||||
123 | $this->updateMetaData($return, $data); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
124 | |||||
125 | if (\in_array($type->type, $canHaveVirtual, true)) { |
||||
126 | if ($this->validIBData($data)) { |
||||
127 | $this->updateIB($return, $data); |
||||
0 ignored issues
–
show
$return of type null is incompatible with the type FireflyIII\Models\Account expected by parameter $account of FireflyIII\Factory\AccountFactory::updateIB() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
128 | } |
||||
129 | if (!$this->validIBData($data)) { |
||||
130 | $this->deleteIB($return); |
||||
0 ignored issues
–
show
$return of type null is incompatible with the type FireflyIII\Models\Account expected by parameter $account of FireflyIII\Factory\AccountFactory::deleteIB() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
131 | } |
||||
132 | } |
||||
133 | $this->updateNote($return, $data['notes'] ?? ''); |
||||
0 ignored issues
–
show
$return of type null is incompatible with the type FireflyIII\Models\Account expected by parameter $account of FireflyIII\Factory\AccountFactory::updateNote() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
134 | } |
||||
135 | |||||
136 | return $return; |
||||
137 | } |
||||
138 | |||||
139 | /** |
||||
140 | * @param string $accountName |
||||
141 | * @param string $accountType |
||||
142 | * |
||||
143 | * @return Account|null |
||||
144 | */ |
||||
145 | public function find(string $accountName, string $accountType): ?Account |
||||
146 | { |
||||
147 | $type = AccountType::whereType($accountType)->first(); |
||||
148 | $accounts = $this->user->accounts()->where('account_type_id', $type->id)->get(['accounts.*']); |
||||
149 | $return = null; |
||||
150 | /** @var Account $object */ |
||||
151 | foreach ($accounts as $object) { |
||||
152 | if ($object->name === $accountName) { |
||||
153 | $return = $object; |
||||
154 | break; |
||||
155 | } |
||||
156 | } |
||||
157 | |||||
158 | return $return; |
||||
159 | } |
||||
160 | |||||
161 | /** |
||||
162 | * |
||||
163 | * @param string $accountName |
||||
164 | * @param string $accountType |
||||
165 | * |
||||
166 | * @return Account |
||||
167 | * @throws FireflyException |
||||
168 | */ |
||||
169 | public function findOrCreate(string $accountName, string $accountType): Account |
||||
170 | { |
||||
171 | Log::debug(sprintf('Searching for "%s" of type "%s"', $accountName, $accountType)); |
||||
172 | $type = AccountType::whereType($accountType)->first(); |
||||
173 | $accounts = $this->user->accounts()->where('account_type_id', $type->id)->get(['accounts.*']); |
||||
174 | $return = null; |
||||
175 | |||||
176 | Log::debug(sprintf('Account type is #%d', $type->id)); |
||||
177 | |||||
178 | /** @var Account $object */ |
||||
179 | foreach ($accounts as $object) { |
||||
180 | if ($object->name === $accountName) { |
||||
181 | Log::debug(sprintf('Found account #%d "%s".', $object->id, $object->name)); |
||||
182 | $return = $object; |
||||
183 | break; |
||||
184 | } |
||||
185 | } |
||||
186 | if (null === $return) { |
||||
187 | Log::debug('Found nothing. Will create a new one.'); |
||||
188 | $return = $this->create( |
||||
189 | [ |
||||
190 | 'user_id' => $this->user->id, |
||||
191 | 'name' => $accountName, |
||||
192 | 'account_type_id' => $type->id, |
||||
193 | 'accountType' => null, |
||||
194 | 'virtualBalance' => '0', |
||||
195 | 'iban' => null, |
||||
196 | 'active' => true, |
||||
197 | ] |
||||
198 | ); |
||||
199 | } |
||||
200 | |||||
201 | return $return; |
||||
202 | } |
||||
203 | |||||
204 | /** |
||||
205 | * @param User $user |
||||
206 | */ |
||||
207 | public function setUser(User $user): void |
||||
208 | { |
||||
209 | $this->user = $user; |
||||
210 | } |
||||
211 | |||||
212 | /** |
||||
213 | * @param int|null $accountTypeId |
||||
214 | * @param null|string $accountType |
||||
215 | * |
||||
216 | * @return AccountType|null |
||||
217 | * @SuppressWarnings(PHPMD.CyclomaticComplexity) |
||||
218 | */ |
||||
219 | protected function getAccountType(?int $accountTypeId, ?string $accountType): ?AccountType |
||||
220 | { |
||||
221 | $accountTypeId = (int)$accountTypeId; |
||||
222 | $result = null; |
||||
223 | if ($accountTypeId > 0) { |
||||
224 | $result = AccountType::find($accountTypeId); |
||||
225 | } |
||||
226 | if (null === $result) { |
||||
227 | Log::debug(sprintf('No account type found by ID, continue search for "%s".', $accountType)); |
||||
228 | /** @var array $types */ |
||||
229 | $types = config('firefly.accountTypeByIdentifier.' . $accountType) ?? []; |
||||
230 | if (\count($types) > 0) { |
||||
231 | Log::debug(sprintf('%d accounts in list from config', \count($types)), $types); |
||||
232 | $result = AccountType::whereIn('type', $types)->first(); |
||||
233 | } |
||||
234 | if (null === $result && null !== $accountType) { |
||||
235 | // try as full name: |
||||
236 | $result = AccountType::whereType($accountType)->first(); |
||||
237 | } |
||||
238 | } |
||||
239 | |||||
240 | return $result; |
||||
241 | |||||
242 | } |
||||
243 | |||||
244 | } |
||||
245 |