mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Remove v2 transformers.
This commit is contained in:
		| @@ -1,54 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * AbstractTransformer.php |  | ||||||
|  * Copyright (c) 2022 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use League\Fractal\TransformerAbstract; |  | ||||||
| use Symfony\Component\HttpFoundation\ParameterBag; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class AbstractTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| abstract class AbstractTransformer extends TransformerAbstract |  | ||||||
| { |  | ||||||
|     protected ParameterBag $parameters; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * This method is called exactly ONCE from FireflyIII\Api\V2\Controllers\Controller::jsonApiList |  | ||||||
|      */ |  | ||||||
|     abstract public function collectMetaData(Collection $objects): Collection; |  | ||||||
| 
 |  | ||||||
|     final public function getParameters(): ParameterBag |  | ||||||
|     { |  | ||||||
|         return $this->parameters; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     final public function setParameters(ParameterBag $parameters): void |  | ||||||
|     { |  | ||||||
|         $this->parameters = $parameters; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,440 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * AccountTransformer.php |  | ||||||
|  * Copyright (c) 2022 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use Carbon\Carbon; |  | ||||||
| use FireflyIII\Exceptions\FireflyException; |  | ||||||
| use FireflyIII\Models\Account; |  | ||||||
| use FireflyIII\Models\AccountType; |  | ||||||
| use FireflyIII\Models\TransactionCurrency; |  | ||||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; |  | ||||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Illuminate\Support\Facades\Log; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class AccountTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class AccountTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     private array               $accountMeta; |  | ||||||
|     private array               $accountTypes; |  | ||||||
|     private array               $balanceDifferences; |  | ||||||
|     private array               $balances; |  | ||||||
|     private array               $convertedBalances; |  | ||||||
|     private array               $currencies; |  | ||||||
|     private TransactionCurrency $default; |  | ||||||
|     private array               $fullTypes; |  | ||||||
|     private array               $lastActivity; |  | ||||||
|     private array               $objectGroups; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * This method collects meta-data for one or all accounts in the transformer's collection. |  | ||||||
|      */ |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         $this->currencies         = []; |  | ||||||
|         $this->balances           = []; |  | ||||||
|         $this->accountMeta        = []; |  | ||||||
|         $this->accountTypes       = []; |  | ||||||
|         $this->fullTypes          = []; |  | ||||||
|         $this->lastActivity       = []; |  | ||||||
|         $this->objectGroups       = []; |  | ||||||
|         $this->convertedBalances  = []; |  | ||||||
|         $this->balanceDifferences = []; |  | ||||||
| 
 |  | ||||||
|         Log::debug(sprintf('collectMetaData on %d object(s)', $objects->count())); |  | ||||||
| 
 |  | ||||||
|         // first collect all the "heavy" stuff that relies on ALL data to be present.
 |  | ||||||
|         // get last activity:
 |  | ||||||
|         $this->getLastActivity($objects); |  | ||||||
| 
 |  | ||||||
|         // get balances of all accounts
 |  | ||||||
|         $this->getMetaBalances($objects); |  | ||||||
| 
 |  | ||||||
|         // get default currency:
 |  | ||||||
|         $this->getDefaultCurrency(); |  | ||||||
| 
 |  | ||||||
|         // collect currency and other meta-data:
 |  | ||||||
|         $this->collectAccountMetaData($objects); |  | ||||||
| 
 |  | ||||||
|         // get account types:
 |  | ||||||
|         $this->collectAccountTypes($objects); |  | ||||||
| 
 |  | ||||||
|         // add balance difference
 |  | ||||||
|         if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { |  | ||||||
|             $this->getBalanceDifference($objects, $this->parameters->get('start'), $this->parameters->get('end')); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // get object groups
 |  | ||||||
|         $this->getObjectGroups($objects); |  | ||||||
| 
 |  | ||||||
|         // sort:
 |  | ||||||
|         $objects                  = $this->sortAccounts($objects); |  | ||||||
| 
 |  | ||||||
|         // if pagination is disabled, do it now:
 |  | ||||||
|         if (true === $this->parameters->get('disablePagination')) { |  | ||||||
|             $page    = (int) $this->parameters->get('page'); |  | ||||||
|             $size    = (int) $this->parameters->get('pageSize'); |  | ||||||
|             $objects = $objects->slice(($page - 1) * $size, $size); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function getLastActivity(Collection $accounts): void |  | ||||||
|     { |  | ||||||
|         /** @var AccountRepositoryInterface $accountRepository */ |  | ||||||
|         $accountRepository = app(AccountRepositoryInterface::class); |  | ||||||
|         $lastActivity      = $accountRepository->getLastActivity($accounts); |  | ||||||
|         foreach ($lastActivity as $row) { |  | ||||||
|             $this->lastActivity[(int) $row['account_id']] = Carbon::parse($row['date_max'], config('app.timezone')); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function getMetaBalances(Collection $accounts): void |  | ||||||
|     { |  | ||||||
|         try { |  | ||||||
|             $this->convertedBalances = app('steam')->finalAccountsBalance($accounts, $this->getDate()); |  | ||||||
|         } catch (FireflyException $e) { |  | ||||||
|             Log::error($e->getMessage()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function getDate(): Carbon |  | ||||||
|     { |  | ||||||
|         if (null !== $this->parameters->get('date')) { |  | ||||||
|             return $this->parameters->get('date'); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return today(config('app.timezone')); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function getDefaultCurrency(): void |  | ||||||
|     { |  | ||||||
|         $this->default = app('amount')->getPrimaryCurrency(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectAccountMetaData(Collection $accounts): void |  | ||||||
|     { |  | ||||||
|         /** @var CurrencyRepositoryInterface $repository */ |  | ||||||
|         $repository        = app(CurrencyRepositoryInterface::class); |  | ||||||
| 
 |  | ||||||
|         /** @var AccountRepositoryInterface $accountRepository */ |  | ||||||
|         $accountRepository = app(AccountRepositoryInterface::class); |  | ||||||
|         $metaFields        = $accountRepository->getMetaValues($accounts, ['currency_id', 'account_role', 'account_number', 'liability_direction', 'interest', 'interest_period', 'current_debt']); |  | ||||||
|         $currencyIds       = $metaFields->where('name', 'currency_id')->pluck('data')->toArray(); |  | ||||||
| 
 |  | ||||||
|         $currencies        = $repository->getByIds($currencyIds); |  | ||||||
|         foreach ($currencies as $currency) { |  | ||||||
|             $id                    = $currency->id; |  | ||||||
|             $this->currencies[$id] = $currency; |  | ||||||
|         } |  | ||||||
|         foreach ($metaFields as $entry) { |  | ||||||
|             $id                                   = $entry->account_id; |  | ||||||
|             $this->accountMeta[$id][$entry->name] = $entry->data; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectAccountTypes(Collection $accounts): void |  | ||||||
|     { |  | ||||||
|         /** @var AccountRepositoryInterface $accountRepository */ |  | ||||||
|         $accountRepository = app(AccountRepositoryInterface::class); |  | ||||||
|         $accountTypes      = $accountRepository->getAccountTypes($accounts); |  | ||||||
| 
 |  | ||||||
|         /** @var AccountType $row */ |  | ||||||
|         foreach ($accountTypes as $row) { |  | ||||||
|             $this->accountTypes[$row->id] = (string) config(sprintf('firefly.shortNamesByFullName.%s', $row->type)); |  | ||||||
|             $this->fullTypes[$row->id]    = $row->type; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function getBalanceDifference(Collection $accounts, Carbon $start, Carbon $end): void |  | ||||||
|     { |  | ||||||
|         if ('en_US' === config('app.fallback_locale')) { |  | ||||||
|             throw new FireflyException('Used deprecated method, rethink this.'); |  | ||||||
|         } |  | ||||||
|         // collect balances, start and end for both native and converted.
 |  | ||||||
|         // yes the b is usually used for boolean by idiots but here it's for balance.
 |  | ||||||
|         $bStart = []; |  | ||||||
|         $bEnd   = []; |  | ||||||
| 
 |  | ||||||
|         try { |  | ||||||
|             Log::debug(sprintf('v2 transformer: finalAccountsBalance("%s")', $start->format('Y-m-d H:i:s'))); |  | ||||||
|             Log::debug(sprintf('v2 transformer: finalAccountsBalance("%s")', $end->format('Y-m-d H:i:s'))); |  | ||||||
|             $bStart = app('steam')->finalAccountsBalance($accounts, $start); |  | ||||||
|             $bEnd   = app('steam')->finalAccountsBalance($accounts, $end); |  | ||||||
|         } catch (FireflyException $e) { |  | ||||||
|             Log::error($e->getMessage()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /** @var Account $account */ |  | ||||||
|         foreach ($accounts as $account) { |  | ||||||
|             $id = $account->id; |  | ||||||
|             if (array_key_exists($id, $bStart) && array_key_exists($id, $bEnd)) { |  | ||||||
|                 $this->balanceDifferences[$id] = [ |  | ||||||
|                     'balance'        => bcsub((string) $bEnd[$id]['balance'], (string) $bStart[$id]['balance']), |  | ||||||
|                     'native_balance' => bcsub((string) $bEnd[$id]['native_balance'], (string) $bStart[$id]['native_balance']), |  | ||||||
|                 ]; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function getObjectGroups(Collection $accounts): void |  | ||||||
|     { |  | ||||||
|         /** @var AccountRepositoryInterface $accountRepository */ |  | ||||||
|         $accountRepository  = app(AccountRepositoryInterface::class); |  | ||||||
|         $this->objectGroups = $accountRepository->getObjectGroups($accounts); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function sortAccounts(Collection $accounts): Collection |  | ||||||
|     { |  | ||||||
|         /** @var null|array $sort */ |  | ||||||
|         $sort = $this->parameters->get('sort'); |  | ||||||
| 
 |  | ||||||
|         if (null === $sort || 0 === count($sort)) { |  | ||||||
|             return $accounts; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * @var string $column |  | ||||||
|          * @var string $direction |  | ||||||
|          */ |  | ||||||
|         foreach ($sort as $column => $direction) { |  | ||||||
|             // account_number + iban
 |  | ||||||
|             if ('iban' === $column) { |  | ||||||
|                 $accounts = $this->sortByIban($accounts, $direction); |  | ||||||
|             } |  | ||||||
|             if ('balance' === $column) { |  | ||||||
|                 $accounts = $this->sortByBalance($accounts, $direction); |  | ||||||
|             } |  | ||||||
|             if ('last_activity' === $column) { |  | ||||||
|                 $accounts = $this->sortByLastActivity($accounts, $direction); |  | ||||||
|             } |  | ||||||
|             if ('balance_difference' === $column) { |  | ||||||
|                 $accounts = $this->sortByBalanceDifference($accounts, $direction); |  | ||||||
|             } |  | ||||||
|             if ('current_debt' === $column) { |  | ||||||
|                 $accounts = $this->sortByCurrentDebt($accounts, $direction); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $accounts; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function sortByIban(Collection $accounts, string $direction): Collection |  | ||||||
|     { |  | ||||||
|         $meta = $this->accountMeta; |  | ||||||
| 
 |  | ||||||
|         return $accounts->sort(function (Account $left, Account $right) use ($meta, $direction) { |  | ||||||
|             $leftIban  = trim(sprintf('%s%s', $left->iban, $meta[$left->id]['account_number'] ?? '')); |  | ||||||
|             $rightIban = trim(sprintf('%s%s', $right->iban, $meta[$right->id]['account_number'] ?? '')); |  | ||||||
|             if ('asc' === $direction) { |  | ||||||
|                 return strcasecmp($leftIban, $rightIban); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return strcasecmp($rightIban, $leftIban); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function sortByBalance(Collection $accounts, string $direction): Collection |  | ||||||
|     { |  | ||||||
|         $balances = $this->convertedBalances; |  | ||||||
| 
 |  | ||||||
|         return $accounts->sort(function (Account $left, Account $right) use ($balances, $direction) { |  | ||||||
|             $leftBalance  = (float) ($balances[$left->id]['native_balance'] ?? 0); |  | ||||||
|             $rightBalance = (float) ($balances[$right->id]['native_balance'] ?? 0); |  | ||||||
|             if ('asc' === $direction) { |  | ||||||
|                 return $leftBalance <=> $rightBalance; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return $rightBalance <=> $leftBalance; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function sortByLastActivity(Collection $accounts, string $direction): Collection |  | ||||||
|     { |  | ||||||
|         $dates = $this->lastActivity; |  | ||||||
| 
 |  | ||||||
|         return $accounts->sort(function (Account $left, Account $right) use ($dates, $direction) { |  | ||||||
|             $leftDate  = $dates[$left->id] ?? Carbon::create(1900, 1, 1, 0, 0, 0); |  | ||||||
|             $rightDate = $dates[$right->id] ?? Carbon::create(1900, 1, 1, 0, 0, 0); |  | ||||||
|             if ('asc' === $direction) { |  | ||||||
|                 return $leftDate->gt($rightDate) ? 1 : -1; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return $rightDate->gt($leftDate) ? 1 : -1; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function sortByBalanceDifference(Collection $accounts, string $direction): Collection |  | ||||||
|     { |  | ||||||
|         $balances = $this->balanceDifferences; |  | ||||||
| 
 |  | ||||||
|         return $accounts->sort(function (Account $left, Account $right) use ($balances, $direction) { |  | ||||||
|             $leftBalance  = (float) ($balances[$left->id]['native_balance'] ?? 0); |  | ||||||
|             $rightBalance = (float) ($balances[$right->id]['native_balance'] ?? 0); |  | ||||||
|             if ('asc' === $direction) { |  | ||||||
|                 return $leftBalance <=> $rightBalance; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return $rightBalance <=> $leftBalance; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function sortByCurrentDebt(Collection $accounts, string $direction): Collection |  | ||||||
|     { |  | ||||||
|         $amounts = $this->accountMeta; |  | ||||||
| 
 |  | ||||||
|         return $accounts->sort(function (Account $left, Account $right) use ($amounts, $direction) { |  | ||||||
|             $leftCurrent  = (float) ($amounts[$left->id]['current_debt'] ?? 0); |  | ||||||
|             $rightCurrent = (float) ($amounts[$right->id]['current_debt'] ?? 0); |  | ||||||
|             if ('asc' === $direction) { |  | ||||||
|                 return $leftCurrent <=> $rightCurrent; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return $rightCurrent <=> $leftCurrent; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform the account. |  | ||||||
|      */ |  | ||||||
|     public function transform(Account $account): array |  | ||||||
|     { |  | ||||||
|         $id                 = $account->id; |  | ||||||
| 
 |  | ||||||
|         // various meta
 |  | ||||||
|         $accountRole        = $this->accountMeta[$id]['account_role'] ?? null; |  | ||||||
|         $accountType        = $this->accountTypes[$id]; |  | ||||||
|         $order              = $account->order; |  | ||||||
| 
 |  | ||||||
|         // liability type
 |  | ||||||
|         $liabilityType      = 'liabilities' === $accountType ? $this->fullTypes[$id] : null; |  | ||||||
|         $liabilityDirection = $this->accountMeta[$id]['liability_direction'] ?? null; |  | ||||||
|         $interest           = $this->accountMeta[$id]['interest'] ?? null; |  | ||||||
|         $interestPeriod     = $this->accountMeta[$id]['interest_period'] ?? null; |  | ||||||
|         $currentDebt        = $this->accountMeta[$id]['current_debt'] ?? null; |  | ||||||
| 
 |  | ||||||
|         // no currency? use default
 |  | ||||||
|         $currency           = $this->default; |  | ||||||
|         if (array_key_exists($id, $this->accountMeta) && 0 !== (int) ($this->accountMeta[$id]['currency_id'] ?? 0)) { |  | ||||||
|             $currency = $this->currencies[(int) $this->accountMeta[$id]['currency_id']]; |  | ||||||
|         } |  | ||||||
|         // amounts and calculation.
 |  | ||||||
|         $balance            = $this->balances[$id]['balance'] ?? null; |  | ||||||
|         $nativeBalance      = $this->convertedBalances[$id]['native_balance'] ?? null; |  | ||||||
| 
 |  | ||||||
|         // no order for some accounts:
 |  | ||||||
|         if (!in_array(strtolower((string) $accountType), ['liability', 'liabilities', 'asset'], true)) { |  | ||||||
|             $order = null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // object group
 |  | ||||||
|         $objectGroupId      = $this->objectGroups[$id]['id'] ?? null; |  | ||||||
|         $objectGroupOrder   = $this->objectGroups[$id]['order'] ?? null; |  | ||||||
|         $objectGroupTitle   = $this->objectGroups[$id]['title'] ?? null; |  | ||||||
| 
 |  | ||||||
|         // balance difference
 |  | ||||||
|         $diffStart          = null; |  | ||||||
|         $diffEnd            = null; |  | ||||||
|         $balanceDiff        = null; |  | ||||||
|         $nativeBalanceDiff  = null; |  | ||||||
|         if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { |  | ||||||
|             $diffStart         = $this->parameters->get('start')->toAtomString(); |  | ||||||
|             $diffEnd           = $this->parameters->get('end')->toAtomString(); |  | ||||||
|             $balanceDiff       = $this->balanceDifferences[$id]['balance'] ?? null; |  | ||||||
|             $nativeBalanceDiff = $this->balanceDifferences[$id]['native_balance'] ?? null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return [ |  | ||||||
|             'id'                             => (string) $account->id, |  | ||||||
|             'created_at'                     => $account->created_at->toAtomString(), |  | ||||||
|             'updated_at'                     => $account->updated_at->toAtomString(), |  | ||||||
|             'active'                         => $account->active, |  | ||||||
|             'order'                          => $order, |  | ||||||
|             'name'                           => $account->name, |  | ||||||
|             'iban'                           => '' === (string) $account->iban ? null : $account->iban, |  | ||||||
|             'account_number'                 => $this->accountMeta[$id]['account_number'] ?? null, |  | ||||||
|             'type'                           => strtolower((string) $accountType), |  | ||||||
|             'account_role'                   => $accountRole, |  | ||||||
|             'currency_id'                    => (string) $currency->id, |  | ||||||
|             'currency_code'                  => $currency->code, |  | ||||||
|             'currency_symbol'                => $currency->symbol, |  | ||||||
|             'currency_decimal_places'        => $currency->decimal_places, |  | ||||||
| 
 |  | ||||||
|             'native_currency_id'             => (string) $this->default->id, |  | ||||||
|             'native_currency_code'           => $this->default->code, |  | ||||||
|             'native_currency_symbol'         => $this->default->symbol, |  | ||||||
|             'native_currency_decimal_places' => $this->default->decimal_places, |  | ||||||
| 
 |  | ||||||
|             // balance:
 |  | ||||||
|             'current_balance'                => $balance, |  | ||||||
|             'native_current_balance'         => $nativeBalance, |  | ||||||
|             'current_balance_date'           => $this->getDate()->endOfDay()->toAtomString(), |  | ||||||
| 
 |  | ||||||
|             // balance difference
 |  | ||||||
|             'balance_difference'             => $balanceDiff, |  | ||||||
|             'native_balance_difference'      => $nativeBalanceDiff, |  | ||||||
|             'balance_difference_start'       => $diffStart, |  | ||||||
|             'balance_difference_end'         => $diffEnd, |  | ||||||
| 
 |  | ||||||
|             // more meta
 |  | ||||||
|             'last_activity'                  => array_key_exists($id, $this->lastActivity) ? $this->lastActivity[$id]->toAtomString() : null, |  | ||||||
| 
 |  | ||||||
|             // liability stuff
 |  | ||||||
|             'liability_type'                 => $liabilityType, |  | ||||||
|             'liability_direction'            => $liabilityDirection, |  | ||||||
|             'interest'                       => $interest, |  | ||||||
|             'interest_period'                => $interestPeriod, |  | ||||||
|             'current_debt'                   => $currentDebt, |  | ||||||
| 
 |  | ||||||
|             // object group
 |  | ||||||
|             'object_group_id'                => null !== $objectGroupId ? (string) $objectGroupId : null, |  | ||||||
|             'object_group_order'             => $objectGroupOrder, |  | ||||||
|             'object_group_title'             => $objectGroupTitle, |  | ||||||
| 
 |  | ||||||
|             //            'notes'                   => $this->repository->getNoteText($account),
 |  | ||||||
|             //            'monthly_payment_date'    => $monthlyPaymentDate,
 |  | ||||||
|             //            'credit_card_type'        => $creditCardType,
 |  | ||||||
|             //            'bic'                     => $this->repository->getMetaValue($account, 'BIC'),
 |  | ||||||
|             //            'virtual_balance'         => number_format((float) $account->virtual_balance, $decimalPlaces, '.', ''),
 |  | ||||||
|             //            'opening_balance'         => $openingBalance,
 |  | ||||||
|             //            'opening_balance_date'    => $openingBalanceDate,
 |  | ||||||
|             //            'include_net_worth'       => $includeNetWorth,
 |  | ||||||
|             //            'longitude'               => $longitude,
 |  | ||||||
|             //            'latitude'                => $latitude,
 |  | ||||||
|             //            'zoom_level'              => $zoomLevel,
 |  | ||||||
|             'links'                          => [ |  | ||||||
|                 [ |  | ||||||
|                     'rel' => 'self', |  | ||||||
|                     'uri' => '/accounts/'.$account->id, |  | ||||||
|                 ], |  | ||||||
|             ], |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,367 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * BillTransformer.php |  | ||||||
|  * Copyright (c) 2019 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use Carbon\Carbon; |  | ||||||
| use Carbon\CarbonInterface; |  | ||||||
| use FireflyIII\Exceptions\FireflyException; |  | ||||||
| use FireflyIII\Models\Bill; |  | ||||||
| use FireflyIII\Models\Note; |  | ||||||
| use FireflyIII\Models\ObjectGroup; |  | ||||||
| use FireflyIII\Models\Transaction; |  | ||||||
| use FireflyIII\Models\TransactionCurrency; |  | ||||||
| use FireflyIII\Models\TransactionJournal; |  | ||||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Illuminate\Support\Facades\DB; |  | ||||||
| use Illuminate\Support\Facades\Log; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class BillTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class BillTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     private ExchangeRateConverter $converter; |  | ||||||
|     private array                 $currencies; |  | ||||||
|     private TransactionCurrency   $default; |  | ||||||
|     private array                 $groups; |  | ||||||
|     private array                 $notes; |  | ||||||
|     private array                 $paidDates; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @throws FireflyException |  | ||||||
|      * |  | ||||||
|      * @SuppressWarnings("PHPMD.ExcessiveMethodLength") |  | ||||||
|      */ |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         /** @var array<int, TransactionCurrency> $currencies */ |  | ||||||
|         $currencies       = []; |  | ||||||
|         $bills            = []; |  | ||||||
|         $this->notes      = []; |  | ||||||
|         $this->groups     = []; |  | ||||||
|         $this->paidDates  = []; |  | ||||||
| 
 |  | ||||||
|         /** @var Bill $object */ |  | ||||||
|         foreach ($objects as $object) { |  | ||||||
|             $id      = $object->transaction_currency_id; |  | ||||||
|             $bills[] = $object->id; |  | ||||||
|             $currencies[$id] ??= TransactionCurrency::find($id); |  | ||||||
|         } |  | ||||||
|         $this->currencies = $currencies; |  | ||||||
|         $notes            = Note::whereNoteableType(Bill::class)->whereIn('noteable_id', array_keys($bills))->get(); |  | ||||||
| 
 |  | ||||||
|         /** @var Note $note */ |  | ||||||
|         foreach ($notes as $note) { |  | ||||||
|             $id               = $note->noteable_id; |  | ||||||
|             $this->notes[$id] = $note; |  | ||||||
|         } |  | ||||||
|         // grab object groups:
 |  | ||||||
|         $set              = DB::table('object_groupables') |  | ||||||
|             ->leftJoin('object_groups', 'object_groups.id', '=', 'object_groupables.object_group_id') |  | ||||||
|             ->where('object_groupables.object_groupable_type', Bill::class) |  | ||||||
|             ->get(['object_groupables.*', 'object_groups.title', 'object_groups.order']) |  | ||||||
|         ; |  | ||||||
| 
 |  | ||||||
|         /** @var ObjectGroup $entry */ |  | ||||||
|         foreach ($set as $entry) { |  | ||||||
|             $billId                = (int) $entry->object_groupable_id; |  | ||||||
|             $id                    = (int) $entry->object_group_id; |  | ||||||
|             $order                 = $entry->order; |  | ||||||
|             $this->groups[$billId] = [ |  | ||||||
|                 'object_group_id'    => $id, |  | ||||||
|                 'object_group_title' => $entry->title, |  | ||||||
|                 'object_group_order' => $order, |  | ||||||
|             ]; |  | ||||||
|         } |  | ||||||
|         Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__)); |  | ||||||
|         $this->default    = app('amount')->getPrimaryCurrency(); |  | ||||||
|         $this->converter  = new ExchangeRateConverter(); |  | ||||||
| 
 |  | ||||||
|         // grab all paid dates:
 |  | ||||||
|         if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { |  | ||||||
|             $journals     = TransactionJournal::whereIn('bill_id', $bills) |  | ||||||
|                 ->where('date', '>=', $this->parameters->get('start')) |  | ||||||
|                 ->where('date', '<=', $this->parameters->get('end')) |  | ||||||
|                 ->get(['transaction_journals.id', 'transaction_journals.transaction_group_id', 'transaction_journals.date', 'transaction_journals.bill_id']) |  | ||||||
|             ; |  | ||||||
|             $journalIds   = $journals->pluck('id')->toArray(); |  | ||||||
| 
 |  | ||||||
|             // grab transactions for amount:
 |  | ||||||
|             $set          = Transaction::whereIn('transaction_journal_id', $journalIds) |  | ||||||
|                 ->where('transactions.amount', '<', 0) |  | ||||||
|                 ->get(['transactions.id', 'transactions.transaction_journal_id', 'transactions.amount', 'transactions.foreign_amount', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']) |  | ||||||
|             ; |  | ||||||
|             $transactions = []; |  | ||||||
| 
 |  | ||||||
|             /** @var Transaction $transaction */ |  | ||||||
|             foreach ($set as $transaction) { |  | ||||||
|                 $journalId                = $transaction->transaction_journal_id; |  | ||||||
|                 $transactions[$journalId] = $transaction->toArray(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             /** @var TransactionJournal $journal */ |  | ||||||
|             foreach ($journals as $journal) { |  | ||||||
|                 app('log')->debug(sprintf('Processing journal #%d', $journal->id)); |  | ||||||
|                 $transaction                = $transactions[$journal->id] ?? []; |  | ||||||
|                 $billId                     = (int) $journal->bill_id; |  | ||||||
|                 $currencyId                 = (int) ($transaction['transaction_currency_id'] ?? 0); |  | ||||||
|                 $currencies[$currencyId] ??= TransactionCurrency::find($currencyId); |  | ||||||
| 
 |  | ||||||
|                 // foreign currency
 |  | ||||||
|                 $foreignCurrencyId          = null; |  | ||||||
|                 $foreignCurrencyCode        = null; |  | ||||||
|                 $foreignCurrencyName        = null; |  | ||||||
|                 $foreignCurrencySymbol      = null; |  | ||||||
|                 $foreignCurrencyDp          = null; |  | ||||||
|                 app('log')->debug('Foreign currency is NULL'); |  | ||||||
|                 if (null !== $transaction['foreign_currency_id']) { |  | ||||||
|                     app('log')->debug(sprintf('Foreign currency is #%d', $transaction['foreign_currency_id'])); |  | ||||||
|                     $foreignCurrencyId     = (int) $transaction['foreign_currency_id']; |  | ||||||
|                     $currencies[$foreignCurrencyId] ??= TransactionCurrency::find($foreignCurrencyId); |  | ||||||
|                     $foreignCurrencyCode   = $currencies[$foreignCurrencyId]->code;           // @phpstan-ignore property.notFound
 |  | ||||||
|                     $foreignCurrencyName   = $currencies[$foreignCurrencyId]->name;           // @phpstan-ignore property.notFound
 |  | ||||||
|                     $foreignCurrencySymbol = $currencies[$foreignCurrencyId]->symbol;         // @phpstan-ignore property.notFound
 |  | ||||||
|                     $foreignCurrencyDp     = $currencies[$foreignCurrencyId]->decimal_places; // @phpstan-ignore property.notFound
 |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 $this->paidDates[$billId][] = [ |  | ||||||
|                     'transaction_group_id'            => (string) $journal->id, |  | ||||||
|                     'transaction_journal_id'          => (string) $journal->transaction_group_id, |  | ||||||
|                     'date'                            => $journal->date->toAtomString(), |  | ||||||
|                     'currency_id'                     => $currencies[$currencyId]->id, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'currency_code'                   => $currencies[$currencyId]->code, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'currency_name'                   => $currencies[$currencyId]->name, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'currency_symbol'                 => $currencies[$currencyId]->symbol, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'currency_decimal_places'         => $currencies[$currencyId]->decimal_places, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'native_currency_id'              => $currencies[$currencyId]->id, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'native_currency_code'            => $currencies[$currencyId]->code, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'native_currency_symbol'          => $currencies[$currencyId]->symbol, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'native_currency_decimal_places'  => $currencies[$currencyId]->decimal_places, // @phpstan-ignore property.notFound
 |  | ||||||
|                     'foreign_currency_id'             => $foreignCurrencyId, |  | ||||||
|                     'foreign_currency_code'           => $foreignCurrencyCode, |  | ||||||
|                     'foreign_currency_name'           => $foreignCurrencyName, |  | ||||||
|                     'foreign_currency_symbol'         => $foreignCurrencySymbol, |  | ||||||
|                     'foreign_currency_decimal_places' => $foreignCurrencyDp, |  | ||||||
|                     'amount'                          => $transaction['amount'], |  | ||||||
|                     'foreign_amount'                  => $transaction['foreign_amount'], |  | ||||||
|                     'native_amount'                   => null, |  | ||||||
|                     'foreign_native_amount'           => null, |  | ||||||
|                 ]; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform the bill. |  | ||||||
|      */ |  | ||||||
|     public function transform(Bill $bill): array |  | ||||||
|     { |  | ||||||
|         $paidData              = $this->paidDates[$bill->id] ?? []; |  | ||||||
|         $nextExpectedMatch     = $this->nextExpectedMatch($bill, $this->paidDates[$bill->id] ?? []); |  | ||||||
|         $payDates              = $this->payDates($bill); |  | ||||||
|         $currency              = $this->currencies[$bill->transaction_currency_id]; |  | ||||||
|         $group                 = $this->groups[$bill->id] ?? null; |  | ||||||
| 
 |  | ||||||
|         // date for currency conversion
 |  | ||||||
|         /** @var null|Carbon $startParam */ |  | ||||||
|         $startParam            = $this->parameters->get('start'); |  | ||||||
| 
 |  | ||||||
|         /** @var null|Carbon $date */ |  | ||||||
|         $date                  = null === $startParam ? today() : clone $startParam; |  | ||||||
| 
 |  | ||||||
|         $nextExpectedMatchDiff = $this->getNextExpectedMatchDiff($nextExpectedMatch, $payDates); |  | ||||||
|         $this->converter->summarize(); |  | ||||||
| 
 |  | ||||||
|         return [ |  | ||||||
|             'id'                             => $bill->id, |  | ||||||
|             'created_at'                     => $bill->created_at->toAtomString(), |  | ||||||
|             'updated_at'                     => $bill->updated_at->toAtomString(), |  | ||||||
|             'name'                           => $bill->name, |  | ||||||
|             'amount_min'                     => app('steam')->bcround($bill->amount_min, $currency->decimal_places), |  | ||||||
|             'amount_max'                     => app('steam')->bcround($bill->amount_max, $currency->decimal_places), |  | ||||||
|             'native_amount_min'              => $this->converter->convert($currency, $this->default, $date, $bill->amount_min), |  | ||||||
|             'native_amount_max'              => $this->converter->convert($currency, $this->default, $date, $bill->amount_max), |  | ||||||
|             'currency_id'                    => (string) $bill->transaction_currency_id, |  | ||||||
|             'currency_code'                  => $currency->code, |  | ||||||
|             'currency_name'                  => $currency->name, |  | ||||||
|             'currency_symbol'                => $currency->symbol, |  | ||||||
|             'currency_decimal_places'        => $currency->decimal_places, |  | ||||||
|             'native_currency_id'             => $this->default->id, |  | ||||||
|             'native_currency_code'           => $this->default->code, |  | ||||||
|             'native_currency_name'           => $this->default->name, |  | ||||||
|             'native_currency_symbol'         => $this->default->symbol, |  | ||||||
|             'native_currency_decimal_places' => $this->default->decimal_places, |  | ||||||
|             'date'                           => $bill->date->toAtomString(), |  | ||||||
|             'end_date'                       => $bill->end_date?->toAtomString(), |  | ||||||
|             'extension_date'                 => $bill->extension_date?->toAtomString(), |  | ||||||
|             'repeat_freq'                    => $bill->repeat_freq, |  | ||||||
|             'skip'                           => $bill->skip, |  | ||||||
|             'active'                         => $bill->active, |  | ||||||
|             'order'                          => $bill->order, |  | ||||||
|             'notes'                          => $this->notes[$bill->id] ?? null, |  | ||||||
|             'object_group_id'                => $group ? $group['object_group_id'] : null, |  | ||||||
|             'object_group_order'             => $group ? $group['object_group_order'] : null, |  | ||||||
|             'object_group_title'             => $group ? $group['object_group_title'] : null, |  | ||||||
|             'next_expected_match'            => $nextExpectedMatch->toAtomString(), |  | ||||||
|             'next_expected_match_diff'       => $nextExpectedMatchDiff, |  | ||||||
|             'pay_dates'                      => $payDates, |  | ||||||
|             'paid_dates'                     => $paidData, |  | ||||||
|             'links'                          => [ |  | ||||||
|                 [ |  | ||||||
|                     'rel' => 'self', |  | ||||||
|                     'uri' => sprintf('/bills/%d', $bill->id), |  | ||||||
|                 ], |  | ||||||
|             ], |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Get the data the bill was paid and predict the next expected match. |  | ||||||
|      */ |  | ||||||
|     protected function nextExpectedMatch(Bill $bill, array $dates): Carbon |  | ||||||
|     { |  | ||||||
|         // 2023-07-1 sub one day from the start date to fix a possible bug (see #7704)
 |  | ||||||
|         // 2023-07-18 this particular date is used to search for the last paid date.
 |  | ||||||
|         // 2023-07-18 the cloned $searchDate is used to grab the correct transactions.
 |  | ||||||
| 
 |  | ||||||
|         /** @var null|Carbon $startParam */ |  | ||||||
|         $startParam   = $this->parameters->get('start'); |  | ||||||
| 
 |  | ||||||
|         /** @var null|Carbon $start */ |  | ||||||
|         $start        = null === $startParam ? today() : clone $startParam; |  | ||||||
|         $start->subDay(); |  | ||||||
| 
 |  | ||||||
|         $lastPaidDate = $this->lastPaidDate($dates, $start); |  | ||||||
|         $nextMatch    = clone $bill->date; |  | ||||||
|         while ($nextMatch < $lastPaidDate) { |  | ||||||
|             /* |  | ||||||
|              * As long as this date is smaller than the last time the bill was paid, keep jumping ahead. |  | ||||||
|              * For example: 1 jan, 1 feb, etc. |  | ||||||
|              */ |  | ||||||
|             $nextMatch = app('navigation')->addPeriod($nextMatch, $bill->repeat_freq, $bill->skip); |  | ||||||
|         } |  | ||||||
|         if ($nextMatch->isSameDay($lastPaidDate)) { |  | ||||||
|             // Add another period because it's the same day as the last paid date.
 |  | ||||||
|             return app('navigation')->addPeriod($nextMatch, $bill->repeat_freq, $bill->skip); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $nextMatch; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Returns the latest date in the set, or start when set is empty. |  | ||||||
|      */ |  | ||||||
|     protected function lastPaidDate(array $dates, Carbon $default): Carbon |  | ||||||
|     { |  | ||||||
|         if (0 === count($dates)) { |  | ||||||
|             return $default; |  | ||||||
|         } |  | ||||||
|         $latest = $dates[0]['date']; |  | ||||||
| 
 |  | ||||||
|         /** @var array $row */ |  | ||||||
|         foreach ($dates as $row) { |  | ||||||
|             $carbon = new Carbon($row['date']); |  | ||||||
|             if ($carbon->gte($latest)) { |  | ||||||
|                 $latest = $row['date']; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return new Carbon($latest); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     protected function payDates(Bill $bill): array |  | ||||||
|     { |  | ||||||
|         // app('log')->debug(sprintf('Now in payDates() for bill #%d', $bill->id));
 |  | ||||||
|         if (null === $this->parameters->get('start') || null === $this->parameters->get('end')) { |  | ||||||
|             // app('log')->debug('No start or end date, give empty array.');
 |  | ||||||
| 
 |  | ||||||
|             return []; |  | ||||||
|         } |  | ||||||
|         $set          = new Collection(); |  | ||||||
|         $currentStart = clone $this->parameters->get('start'); |  | ||||||
|         // 2023-06-23 subDay to fix 7655
 |  | ||||||
|         $currentStart->subDay(); |  | ||||||
|         $loop         = 0; |  | ||||||
|         while ($currentStart <= $this->parameters->get('end')) { |  | ||||||
|             $nextExpectedMatch = $this->nextDateMatch($bill, $currentStart); |  | ||||||
|             // If nextExpectedMatch is after end, we continue:
 |  | ||||||
|             if ($nextExpectedMatch > $this->parameters->get('end')) { |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|             // add to set
 |  | ||||||
|             $set->push(clone $nextExpectedMatch); |  | ||||||
|             $nextExpectedMatch->addDay(); |  | ||||||
|             $currentStart      = clone $nextExpectedMatch; |  | ||||||
|             ++$loop; |  | ||||||
|             if ($loop > 4) { |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         $simple       = $set->map( // @phpstan-ignore-line
 |  | ||||||
|             static fn (Carbon $date) => $date->toAtomString() |  | ||||||
|         ); |  | ||||||
| 
 |  | ||||||
|         return $simple->toArray(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Given a bill and a date, this method will tell you at which moment this bill expects its next |  | ||||||
|      * transaction. Whether or not it is there already, is not relevant. |  | ||||||
|      * |  | ||||||
|      * TODO this method is bad compared to the v1 one. |  | ||||||
|      */ |  | ||||||
|     protected function nextDateMatch(Bill $bill, Carbon $date): Carbon |  | ||||||
|     { |  | ||||||
|         // app('log')->debug(sprintf('Now in nextDateMatch(%d, %s)', $bill->id, $date->format('Y-m-d')));
 |  | ||||||
|         $start = clone $bill->date; |  | ||||||
|         // app('log')->debug(sprintf('Bill start date is %s', $start->format('Y-m-d')));
 |  | ||||||
|         while ($start < $date) { |  | ||||||
|             $start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // app('log')->debug(sprintf('End of loop, bill start date is now %s', $start->format('Y-m-d')));
 |  | ||||||
| 
 |  | ||||||
|         return $start; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function getNextExpectedMatchDiff(Carbon $next, array $dates): string |  | ||||||
|     { |  | ||||||
|         if ($next->isToday()) { |  | ||||||
|             return trans('firefly.today'); |  | ||||||
|         } |  | ||||||
|         $current = $dates[0] ?? null; |  | ||||||
|         if (null === $current) { |  | ||||||
|             return trans('firefly.not_expected_period'); |  | ||||||
|         } |  | ||||||
|         $carbon  = new Carbon($current); |  | ||||||
| 
 |  | ||||||
|         return $carbon->diffForHumans(today(config('app.timezone')), CarbonInterface::DIFF_RELATIVE_TO_NOW); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,109 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * BudgetLimitTransformer.php |  | ||||||
|  * Copyright (c) 2019 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use FireflyIII\Models\BudgetLimit; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use League\Fractal\Resource\Item; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class BudgetLimitTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class BudgetLimitTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     protected array $availableIncludes |  | ||||||
|         = [ |  | ||||||
|             'budget', |  | ||||||
|         ]; |  | ||||||
| 
 |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         // TODO: Implement collectMetaData() method.
 |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Include Budget |  | ||||||
|      * |  | ||||||
|      * @return Item |  | ||||||
|      */ |  | ||||||
|     public function includeBudget(BudgetLimit $limit) |  | ||||||
|     { |  | ||||||
|         return $this->item($limit->budget, new BudgetTransformer(), 'budgets'); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform the note. |  | ||||||
|      */ |  | ||||||
|     public function transform(BudgetLimit $budgetLimit): array |  | ||||||
|     { |  | ||||||
|         //        $repository = app(OperationsRepository::class);
 |  | ||||||
|         //        $repository->setUser($budgetLimit->budget->user);
 |  | ||||||
|         //        $expenses              = $repository->sumExpenses(
 |  | ||||||
|         //            $budgetLimit->start_date, $budgetLimit->end_date, null, new Collection([$budgetLimit->budget]), $budgetLimit->transactionCurrency
 |  | ||||||
|         //        );
 |  | ||||||
|         $currency              = $budgetLimit->transactionCurrency; |  | ||||||
|         $amount                = $budgetLimit->amount; |  | ||||||
|         $currencyDecimalPlaces = 2; |  | ||||||
|         $currencyId            = null; |  | ||||||
|         $currencyName          = null; |  | ||||||
|         $currencyCode          = null; |  | ||||||
|         $currencySymbol        = null; |  | ||||||
|         if (null !== $currency) { |  | ||||||
|             $amount                = $budgetLimit->amount; |  | ||||||
|             $currencyId            = $currency->id; |  | ||||||
|             $currencyName          = $currency->name; |  | ||||||
|             $currencyCode          = $currency->code; |  | ||||||
|             $currencySymbol        = $currency->symbol; |  | ||||||
|             $currencyDecimalPlaces = $currency->decimal_places; |  | ||||||
|         } |  | ||||||
|         $amount                = number_format((float) $amount, $currencyDecimalPlaces, '.', ''); |  | ||||||
| 
 |  | ||||||
|         return [ |  | ||||||
|             'id'                      => (string) $budgetLimit->id, |  | ||||||
|             'created_at'              => $budgetLimit->created_at->toAtomString(), |  | ||||||
|             'updated_at'              => $budgetLimit->updated_at->toAtomString(), |  | ||||||
|             'start'                   => $budgetLimit->start_date->toAtomString(), |  | ||||||
|             'end'                     => $budgetLimit->end_date->endOfDay()->toAtomString(), |  | ||||||
|             'budget_id'               => (string) $budgetLimit->budget_id, |  | ||||||
|             'currency_id'             => (string) $currencyId, |  | ||||||
|             'currency_code'           => $currencyCode, |  | ||||||
|             'currency_name'           => $currencyName, |  | ||||||
|             'currency_decimal_places' => $currencyDecimalPlaces, |  | ||||||
|             'currency_symbol'         => $currencySymbol, |  | ||||||
|             'amount'                  => $amount, |  | ||||||
|             'period'                  => $budgetLimit->period, |  | ||||||
|             // 'spent'                   => $expenses[$currencyId]['sum'] ?? '0',
 |  | ||||||
|             'links'                   => [ |  | ||||||
|                 [ |  | ||||||
|                     'rel' => 'self', |  | ||||||
|                     'uri' => sprintf('/budget-limits/%d', $budgetLimit->id), |  | ||||||
|                 ], |  | ||||||
|             ], |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,113 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * BudgetTransformer.php |  | ||||||
|  * Copyright (c) 2019 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use FireflyIII\Models\Budget; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Symfony\Component\HttpFoundation\ParameterBag; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class BudgetTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class BudgetTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     // private OperationsRepositoryInterface $opsRepository;
 |  | ||||||
|     // private BudgetRepositoryInterface     $repository;
 |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * BudgetTransformer constructor. |  | ||||||
|      */ |  | ||||||
|     public function __construct() |  | ||||||
|     { |  | ||||||
|         // $this->opsRepository = app(OperationsRepositoryInterface::class);
 |  | ||||||
|         // $this->repository    = app(BudgetRepositoryInterface::class);
 |  | ||||||
|         $this->parameters = new ParameterBag(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         // TODO: Implement collectMetaData() method.
 |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform a budget. |  | ||||||
|      */ |  | ||||||
|     public function transform(Budget $budget): array |  | ||||||
|     { |  | ||||||
|         // $this->opsRepository->setUser($budget->user);
 |  | ||||||
|         // $start = $this->parameters->get('start');
 |  | ||||||
|         // $end   = $this->parameters->get('end');
 |  | ||||||
|         // $autoBudget = $this->repository->getAutoBudget($budget);
 |  | ||||||
|         //        $spent      = [];
 |  | ||||||
|         //        if (null !== $start && null !== $end) {
 |  | ||||||
|         //            $spent = $this->beautify($this->opsRepository->sumExpenses($start, $end, null, new Collection([$budget])));
 |  | ||||||
|         //        }
 |  | ||||||
| 
 |  | ||||||
|         //        $abCurrencyId   = null;
 |  | ||||||
|         //        $abCurrencyCode = null;
 |  | ||||||
|         //        $abType         = null;
 |  | ||||||
|         //        $abAmount       = null;
 |  | ||||||
|         //        $abPeriod       = null;
 |  | ||||||
|         //        $notes          = $this->repository->getNoteText($budget);
 |  | ||||||
|         //
 |  | ||||||
|         //        $types = [
 |  | ||||||
|         //            AutoBudget::AUTO_BUDGET_RESET    => 'reset',
 |  | ||||||
|         //            AutoBudget::AUTO_BUDGET_ROLLOVER => 'rollover',
 |  | ||||||
|         //        ];
 |  | ||||||
|         //
 |  | ||||||
|         //        if (null !== $autoBudget) {
 |  | ||||||
|         //            $abCurrencyId   = (string) $autoBudget->transactionCurrency->id;
 |  | ||||||
|         //            $abCurrencyCode = $autoBudget->transactionCurrency->code;
 |  | ||||||
|         //            $abType         = $types[$autoBudget->auto_budget_type];
 |  | ||||||
|         //            $abAmount       = number_format((float) $autoBudget->amount, $autoBudget->transactionCurrency->decimal_places, '.', '');
 |  | ||||||
|         //            $abPeriod       = $autoBudget->period;
 |  | ||||||
|         //        }
 |  | ||||||
| 
 |  | ||||||
|         return [ |  | ||||||
|             'id'         => (string) $budget->id, |  | ||||||
|             'created_at' => $budget->created_at->toAtomString(), |  | ||||||
|             'updated_at' => $budget->updated_at->toAtomString(), |  | ||||||
|             'name'       => $budget->name, |  | ||||||
|             'active'     => $budget->active, |  | ||||||
|             'order'      => $budget->order, |  | ||||||
|             //            'notes'                     => $notes,
 |  | ||||||
|             //            'auto_budget_type'          => $abType,
 |  | ||||||
|             //            'auto_budget_period'        => $abPeriod,
 |  | ||||||
|             //            'auto_budget_currency_id'   => $abCurrencyId,
 |  | ||||||
|             //            'auto_budget_currency_code' => $abCurrencyCode,
 |  | ||||||
|             //            'auto_budget_amount'        => $abAmount,
 |  | ||||||
|             //            'spent'                     => $spent,
 |  | ||||||
|             'links'      => [ |  | ||||||
|                 [ |  | ||||||
|                     'rel' => 'self', |  | ||||||
|                     'uri' => sprintf('/budgets/%d', $budget->id), |  | ||||||
|                 ], |  | ||||||
|             ], |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,66 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * CurrencyTransformer.php |  | ||||||
|  * Copyright (c) 2019 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use FireflyIII\Models\TransactionCurrency; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class CurrencyTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class CurrencyTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform the currency. |  | ||||||
|      */ |  | ||||||
|     public function transform(TransactionCurrency $currency): array |  | ||||||
|     { |  | ||||||
|         return [ |  | ||||||
|             'id'             => $currency->id, |  | ||||||
|             'created_at'     => $currency->created_at->toAtomString(), |  | ||||||
|             'updated_at'     => $currency->updated_at->toAtomString(), |  | ||||||
|             'native'         => $currency->userGroupNative, |  | ||||||
|             'default'        => $currency->userGroupNative, |  | ||||||
|             'enabled'        => $currency->userGroupEnabled, |  | ||||||
|             'name'           => $currency->name, |  | ||||||
|             'code'           => $currency->code, |  | ||||||
|             'symbol'         => $currency->symbol, |  | ||||||
|             'decimal_places' => $currency->decimal_places, |  | ||||||
|             'links'          => [ |  | ||||||
|                 [ |  | ||||||
|                     'rel' => 'self', |  | ||||||
|                     'uri' => '/currencies/'.$currency->id, |  | ||||||
|                 ], |  | ||||||
|             ], |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,75 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * AccountTransformer.php |  | ||||||
|  * Copyright (c) 2022 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use FireflyIII\Models\CurrencyExchangeRate; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class AccountTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class ExchangeRateTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     /** |  | ||||||
|      * This method collects meta-data for one or all accounts in the transformer's collection. |  | ||||||
|      */ |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform the account. |  | ||||||
|      */ |  | ||||||
|     public function transform(CurrencyExchangeRate $rate): array |  | ||||||
|     { |  | ||||||
|         return [ |  | ||||||
|             'id'                           => (string) $rate->id, |  | ||||||
|             'created_at'                   => $rate->created_at->toAtomString(), |  | ||||||
|             'updated_at'                   => $rate->updated_at->toAtomString(), |  | ||||||
| 
 |  | ||||||
|             'from_currency_id'             => (string) $rate->fromCurrency->id, |  | ||||||
|             'from_currency_code'           => $rate->fromCurrency->code, |  | ||||||
|             'from_currency_symbol'         => $rate->fromCurrency->symbol, |  | ||||||
|             'from_currency_decimal_places' => $rate->fromCurrency->decimal_places, |  | ||||||
| 
 |  | ||||||
|             'to_currency_id'               => (string) $rate->toCurrency->id, |  | ||||||
|             'to_currency_code'             => $rate->toCurrency->code, |  | ||||||
|             'to_currency_symbol'           => $rate->toCurrency->symbol, |  | ||||||
|             'to_currency_decimal_places'   => $rate->toCurrency->decimal_places, |  | ||||||
| 
 |  | ||||||
|             'rate'                         => $rate->rate, |  | ||||||
|             'date'                         => $rate->date->toAtomString(), |  | ||||||
|             'links'                        => [ |  | ||||||
|                 [ |  | ||||||
|                     'rel' => 'self', |  | ||||||
|                     'uri' => sprintf('/exchange-rates/%s', $rate->id), |  | ||||||
|                 ], |  | ||||||
|             ], |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,273 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * PiggyBankTransformer.php |  | ||||||
|  * Copyright (c) 2019 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use Carbon\Carbon; |  | ||||||
| use FireflyIII\Exceptions\FireflyException; |  | ||||||
| use FireflyIII\Models\Account; |  | ||||||
| use FireflyIII\Models\AccountMeta; |  | ||||||
| use FireflyIII\Models\Note; |  | ||||||
| use FireflyIII\Models\ObjectGroup; |  | ||||||
| use FireflyIII\Models\PiggyBank; |  | ||||||
| use FireflyIII\Models\PiggyBankRepetition; |  | ||||||
| use FireflyIII\Models\TransactionCurrency; |  | ||||||
| use FireflyIII\Models\TransactionJournal; |  | ||||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Illuminate\Support\Facades\DB; |  | ||||||
| use Illuminate\Support\Facades\Log; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class PiggyBankTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class PiggyBankTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     //    private AccountRepositoryInterface   $accountRepos;
 |  | ||||||
|     //    private CurrencyRepositoryInterface  $currencyRepos;
 |  | ||||||
|     //    private PiggyBankRepositoryInterface $piggyRepos;
 |  | ||||||
|     private array                 $accounts; |  | ||||||
|     private ExchangeRateConverter $converter; |  | ||||||
|     private array                 $currencies; |  | ||||||
|     private TransactionCurrency   $default; |  | ||||||
|     private array                 $groups; |  | ||||||
|     private array                 $notes; |  | ||||||
|     private array                 $repetitions; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * PiggyBankTransformer constructor. |  | ||||||
|      */ |  | ||||||
|     public function __construct() |  | ||||||
|     { |  | ||||||
|         $this->notes       = []; |  | ||||||
|         $this->accounts    = []; |  | ||||||
|         $this->groups      = []; |  | ||||||
|         $this->currencies  = []; |  | ||||||
|         $this->repetitions = []; |  | ||||||
|         //        $this->
 |  | ||||||
|         //        $this->currencyRepos = app(CurrencyRepositoryInterface::class);
 |  | ||||||
|         //        $this->piggyRepos    = app(PiggyBankRepositoryInterface::class);
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         // TODO move to repository (does not exist yet)
 |  | ||||||
|         $piggyBanks          = $objects->pluck('id')->toArray(); |  | ||||||
|         $accountInfo         = Account::whereIn('id', $objects->pluck('account_id')->toArray())->get(); |  | ||||||
|         $currencyPreferences = AccountMeta::where('name', '"currency_id"')->whereIn('account_id', $objects->pluck('account_id')->toArray())->get(); |  | ||||||
|         $currencies          = []; |  | ||||||
| 
 |  | ||||||
|         /** @var Account $account */ |  | ||||||
|         foreach ($accountInfo as $account) { |  | ||||||
|             $id                  = $account->id; |  | ||||||
|             $this->accounts[$id] = [ |  | ||||||
|                 'name' => $account->name, |  | ||||||
|             ]; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /** @var AccountMeta $preference */ |  | ||||||
|         foreach ($currencyPreferences as $preference) { |  | ||||||
|             $currencyId                   = (int) $preference->data; |  | ||||||
|             $accountId                    = $preference->account_id; |  | ||||||
|             $currencies[$currencyId] ??= TransactionJournal::find($currencyId); |  | ||||||
|             $this->currencies[$accountId] = $currencies[$currencyId]; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // grab object groups:
 |  | ||||||
|         $set                 = DB::table('object_groupables') |  | ||||||
|             ->leftJoin('object_groups', 'object_groups.id', '=', 'object_groupables.object_group_id') |  | ||||||
|             ->where('object_groupables.object_groupable_type', PiggyBank::class) |  | ||||||
|             ->get(['object_groupables.*', 'object_groups.title', 'object_groups.order']) |  | ||||||
|         ; |  | ||||||
| 
 |  | ||||||
|         /** @var ObjectGroup $entry */ |  | ||||||
|         foreach ($set as $entry) { |  | ||||||
|             $piggyBankId                = (int) $entry->object_groupable_id; |  | ||||||
|             $id                         = (int) $entry->object_group_id; |  | ||||||
|             $order                      = $entry->order; |  | ||||||
|             $this->groups[$piggyBankId] = [ |  | ||||||
|                 'object_group_id'    => (string) $id, |  | ||||||
|                 'object_group_title' => $entry->title, |  | ||||||
|                 'object_group_order' => $order, |  | ||||||
|             ]; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // grab repetitions (for current amount):
 |  | ||||||
|         $repetitions         = PiggyBankRepetition::whereIn('piggy_bank_id', $piggyBanks)->get(); |  | ||||||
|         if ('en_US' === config('app.fallback_locale')) { |  | ||||||
|             throw new FireflyException('[d] Piggy bank repetitions are EOL.'); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /** @var PiggyBankRepetition $repetition */ |  | ||||||
|         foreach ($repetitions as $repetition) { |  | ||||||
|             $this->repetitions[$repetition->piggy_bank_id] = [ |  | ||||||
|                 'amount' => $repetition->current_amount, |  | ||||||
|             ]; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // grab notes
 |  | ||||||
|         // continue with notes
 |  | ||||||
|         $notes               = Note::whereNoteableType(PiggyBank::class)->whereIn('noteable_id', array_keys($piggyBanks))->get(); |  | ||||||
| 
 |  | ||||||
|         /** @var Note $note */ |  | ||||||
|         foreach ($notes as $note) { |  | ||||||
|             $id               = $note->noteable_id; |  | ||||||
|             $this->notes[$id] = $note; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__)); |  | ||||||
|         $this->default       = app('amount')->getPrimaryCurrencyByUserGroup(auth()->user()->userGroup); |  | ||||||
|         $this->converter     = new ExchangeRateConverter(); |  | ||||||
| 
 |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform the piggy bank. |  | ||||||
|      * |  | ||||||
|      * @throws FireflyException |  | ||||||
|      */ |  | ||||||
|     public function transform(PiggyBank $piggyBank): array |  | ||||||
|     { |  | ||||||
|         //        $account = $piggyBank->account;
 |  | ||||||
|         //        $this->accountRepos->setUser($account->user);
 |  | ||||||
|         //        $this->currencyRepos->setUser($account->user);
 |  | ||||||
|         //        $this->piggyRepos->setUser($account->user);
 |  | ||||||
| 
 |  | ||||||
|         // get currency from account, or use default.
 |  | ||||||
|         //        $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getNativeCurrencyByUser($account->user);
 |  | ||||||
| 
 |  | ||||||
|         // note
 |  | ||||||
|         //        $notes = $this->piggyRepos->getNoteText($piggyBank);
 |  | ||||||
|         //        $notes = '' === $notes ? null : $notes;
 |  | ||||||
| 
 |  | ||||||
|         //        $objectGroupId    = null;
 |  | ||||||
|         //        $objectGroupOrder = null;
 |  | ||||||
|         //        $objectGroupTitle = null;
 |  | ||||||
|         //        /** @var ObjectGroup $objectGroup */
 |  | ||||||
|         //        $objectGroup = $piggyBank->objectGroups->first();
 |  | ||||||
|         //        if (null !== $objectGroup) {
 |  | ||||||
|         //            $objectGroupId    = (int)$objectGroup->id;
 |  | ||||||
|         //            $objectGroupOrder = (int)$objectGroup->order;
 |  | ||||||
|         //            $objectGroupTitle = $objectGroup->title;
 |  | ||||||
|         //        }
 |  | ||||||
| 
 |  | ||||||
|         // get currently saved amount:
 |  | ||||||
|         //        $currentAmount = app('steam')->bcround($this->piggyRepos->getCurrentAmount($piggyBank), $currency->decimal_places);
 |  | ||||||
| 
 |  | ||||||
|         $percentage          = null; |  | ||||||
|         $leftToSave          = null; |  | ||||||
|         $nativeLeftToSave    = null; |  | ||||||
|         $savePerMonth        = null; |  | ||||||
|         $nativeSavePerMonth  = null; |  | ||||||
|         $startDate           = $piggyBank->start_date?->format('Y-m-d'); |  | ||||||
|         $targetDate          = $piggyBank->target_date?->format('Y-m-d'); |  | ||||||
|         $accountId           = $piggyBank->account_id; |  | ||||||
|         $accountName         = $this->accounts[$accountId]['name'] ?? null; |  | ||||||
|         $currency            = $this->currencies[$accountId] ?? $this->default; |  | ||||||
|         $currentAmount       = app('steam')->bcround($this->repetitions[$piggyBank->id]['amount'] ?? '0', $currency->decimal_places); |  | ||||||
|         $nativeCurrentAmount = $this->converter->convert($this->default, $currency, today(), $currentAmount); |  | ||||||
|         $targetAmount        = $piggyBank->target_amount; |  | ||||||
|         $nativeTargetAmount  = $this->converter->convert($this->default, $currency, today(), $targetAmount); |  | ||||||
|         $note                = $this->notes[$piggyBank->id] ?? null; |  | ||||||
|         $group               = $this->groups[$piggyBank->id] ?? null; |  | ||||||
| 
 |  | ||||||
|         if (0 !== bccomp($targetAmount, '0')) { // target amount is not 0.00
 |  | ||||||
|             $leftToSave         = bcsub($targetAmount, (string) $currentAmount); |  | ||||||
|             $nativeLeftToSave   = $this->converter->convert($this->default, $currency, today(), $leftToSave); |  | ||||||
|             $percentage         = (int) bcmul(bcdiv((string) $currentAmount, $targetAmount), '100'); |  | ||||||
|             $savePerMonth       = $this->getSuggestedMonthlyAmount($currentAmount, $targetAmount, $piggyBank->start_date, $piggyBank->target_date); |  | ||||||
|             $nativeSavePerMonth = $this->converter->convert($this->default, $currency, today(), $savePerMonth); |  | ||||||
|         } |  | ||||||
|         $this->converter->summarize(); |  | ||||||
| 
 |  | ||||||
|         return [ |  | ||||||
|             'id'                             => (string) $piggyBank->id, |  | ||||||
|             'created_at'                     => $piggyBank->created_at->toAtomString(), |  | ||||||
|             'updated_at'                     => $piggyBank->updated_at->toAtomString(), |  | ||||||
|             'account_id'                     => (string) $piggyBank->account_id, |  | ||||||
|             'account_name'                   => $accountName, |  | ||||||
|             'name'                           => $piggyBank->name, |  | ||||||
|             'currency_id'                    => (string) $currency->id, |  | ||||||
|             'currency_code'                  => $currency->code, |  | ||||||
|             'currency_symbol'                => $currency->symbol, |  | ||||||
|             'currency_decimal_places'        => $currency->decimal_places, |  | ||||||
|             'native_currency_id'             => (string) $this->default->id, |  | ||||||
|             'native_currency_code'           => $this->default->code, |  | ||||||
|             'native_currency_symbol'         => $this->default->symbol, |  | ||||||
|             'native_currency_decimal_places' => $this->default->decimal_places, |  | ||||||
|             'current_amount'                 => $currentAmount, |  | ||||||
|             'native_current_amount'          => $nativeCurrentAmount, |  | ||||||
|             'target_amount'                  => $targetAmount, |  | ||||||
|             'native_target_amount'           => $nativeTargetAmount, |  | ||||||
|             'percentage'                     => $percentage, |  | ||||||
|             'left_to_save'                   => $leftToSave, |  | ||||||
|             'native_left_to_save'            => $nativeLeftToSave, |  | ||||||
|             'save_per_month'                 => $savePerMonth, |  | ||||||
|             'native_save_per_month'          => $nativeSavePerMonth, |  | ||||||
|             'start_date'                     => $startDate, |  | ||||||
|             'target_date'                    => $targetDate, |  | ||||||
|             'order'                          => $piggyBank->order, |  | ||||||
|             'active'                         => $piggyBank->active, |  | ||||||
|             'notes'                          => $note, |  | ||||||
|             'object_group_id'                => $group ? $group['object_group_id'] : null, |  | ||||||
|             'object_group_order'             => $group ? $group['object_group_order'] : null, |  | ||||||
|             'object_group_title'             => $group ? $group['object_group_title'] : null, |  | ||||||
|             'links'                          => [ |  | ||||||
|                 [ |  | ||||||
|                     'rel' => 'self', |  | ||||||
|                     'uri' => '/piggy_banks/'.$piggyBank->id, |  | ||||||
|                 ], |  | ||||||
|             ], |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function getSuggestedMonthlyAmount(string $currentAmount, string $targetAmount, ?Carbon $startDate, ?Carbon $targetDate): string |  | ||||||
|     { |  | ||||||
|         $savePerMonth = '0'; |  | ||||||
|         if (!$targetDate instanceof Carbon) { |  | ||||||
|             return '0'; |  | ||||||
|         } |  | ||||||
|         if (bccomp($currentAmount, $targetAmount) < 1) { |  | ||||||
|             $now             = today(config('app.timezone')); |  | ||||||
|             $startDate       = $startDate instanceof Carbon && $startDate->gte($now) ? $startDate : $now; |  | ||||||
|             $diffInMonths    = (int) $startDate->diffInMonths($targetDate); |  | ||||||
|             $remainingAmount = bcsub($targetAmount, $currentAmount); |  | ||||||
| 
 |  | ||||||
|             // more than 1 month to go and still need money to save:
 |  | ||||||
|             if ($diffInMonths > 0 && 1 === bccomp($remainingAmount, '0')) { |  | ||||||
|                 $savePerMonth = bcdiv($remainingAmount, (string) $diffInMonths); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // less than 1 month to go but still need money to save:
 |  | ||||||
|             if (0 === $diffInMonths && 1 === bccomp($remainingAmount, '0')) { |  | ||||||
|                 $savePerMonth = $remainingAmount; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $savePerMonth; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,56 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * PreferenceTransformer.php |  | ||||||
|  * Copyright (c) 2019 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use FireflyIII\Models\Preference; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class PreferenceTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class PreferenceTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         // TODO: Implement collectMetaData() method.
 |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform the preference |  | ||||||
|      */ |  | ||||||
|     public function transform(Preference $preference): array |  | ||||||
|     { |  | ||||||
|         return [ |  | ||||||
|             'id'         => $preference->id, |  | ||||||
|             'created_at' => $preference->created_at->toAtomString(), |  | ||||||
|             'updated_at' => $preference->updated_at->toAtomString(), |  | ||||||
|             'name'       => $preference->name, |  | ||||||
|             'data'       => $preference->data, |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,625 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * TransactionGroupTransformer.php |  | ||||||
|  * Copyright (c) 2022 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use Carbon\Carbon; |  | ||||||
| use FireflyIII\Enums\TransactionTypeEnum; |  | ||||||
| use FireflyIII\Exceptions\FireflyException; |  | ||||||
| use FireflyIII\Models\Budget; |  | ||||||
| use FireflyIII\Models\Category; |  | ||||||
| use FireflyIII\Models\Location; |  | ||||||
| use FireflyIII\Models\Note; |  | ||||||
| use FireflyIII\Models\Transaction; |  | ||||||
| use FireflyIII\Models\TransactionCurrency; |  | ||||||
| use FireflyIII\Models\TransactionGroup; |  | ||||||
| use FireflyIII\Models\TransactionJournal; |  | ||||||
| use FireflyIII\Models\TransactionJournalMeta; |  | ||||||
| use FireflyIII\Support\Http\Api\ExchangeRateConverter; |  | ||||||
| use FireflyIII\Support\NullArrayObject; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Illuminate\Support\Facades\DB; |  | ||||||
| use stdClass; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class TransactionGroupTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class TransactionGroupTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     private array                 $accountTypes = []; // account types collection.
 |  | ||||||
|     private ExchangeRateConverter $converter;         // collection of all journals and some important meta-data.
 |  | ||||||
|     private array                 $currencies   = []; |  | ||||||
|     private TransactionCurrency   $default; // collection of all currencies for this transformer.
 |  | ||||||
|     private array                 $journals     = []; |  | ||||||
|     private array $meta                         = []; |  | ||||||
| 
 |  | ||||||
|     //    private array                 $currencies        = [];
 |  | ||||||
|     //    private array                 $transactionTypes  = [];
 |  | ||||||
|     private array $notes                        = []; |  | ||||||
|     private array                 $objects      = []; |  | ||||||
|     //    private array                 $locations         = [];
 |  | ||||||
|     private array $tags                         = []; |  | ||||||
|     //    private array                 $amounts           = [];
 |  | ||||||
|     //    private array                 $foreignAmounts    = [];
 |  | ||||||
|     //    private array                 $journalCurrencies = [];
 |  | ||||||
|     //    private array                 $foreignCurrencies = [];
 |  | ||||||
| 
 |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         $collectForObjects = false; |  | ||||||
| 
 |  | ||||||
|         /** @var array|TransactionGroup $object */ |  | ||||||
|         foreach ($objects as $object) { |  | ||||||
|             if (is_array($object)) { |  | ||||||
|                 $this->collectForArray($object); |  | ||||||
|             } |  | ||||||
|             if ($object instanceof TransactionGroup) { |  | ||||||
|                 $this->collectForObject($object); |  | ||||||
|                 $collectForObjects = true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         $this->default     = app('amount')->getPrimaryCurrency(); |  | ||||||
|         $this->converter   = new ExchangeRateConverter(); |  | ||||||
| 
 |  | ||||||
|         $this->collectAllMetaData(); |  | ||||||
|         $this->collectAllNotes(); |  | ||||||
|         $this->collectAllLocations(); |  | ||||||
|         $this->collectAllTags(); |  | ||||||
|         if ($collectForObjects) { |  | ||||||
|             $this->collectAllCurrencies(); |  | ||||||
|             //            $this->collectAllAmounts();
 |  | ||||||
|             //            $this->collectTransactionTypes();
 |  | ||||||
|             //            $this->collectAccounts();
 |  | ||||||
|             // source accounts
 |  | ||||||
|             // destination accounts
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectForArray(array $object): void |  | ||||||
|     { |  | ||||||
|         foreach ($object['sums'] as $sum) { |  | ||||||
|             $this->currencies[(int) $sum['currency_id']] ??= TransactionCurrency::find($sum['currency_id']); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /** @var array $transaction */ |  | ||||||
|         foreach ($object['transactions'] as $transaction) { |  | ||||||
|             $this->journals[(int) $transaction['transaction_journal_id']] = []; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectForObject(TransactionGroup $object): void |  | ||||||
|     { |  | ||||||
|         foreach ($object->transactionJournals as $journal) { |  | ||||||
|             $this->journals[$journal->id] = []; |  | ||||||
|             $this->objects[]              = $journal; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectAllMetaData(): void |  | ||||||
|     { |  | ||||||
|         $meta = TransactionJournalMeta::whereIn('transaction_journal_id', array_keys($this->journals))->get(); |  | ||||||
| 
 |  | ||||||
|         /** @var TransactionJournalMeta $entry */ |  | ||||||
|         foreach ($meta as $entry) { |  | ||||||
|             $id                                        = $entry->transaction_journal_id; |  | ||||||
|             $this->journals[$id]['meta'] ??= []; |  | ||||||
|             $this->journals[$id]['meta'][$entry->name] = $entry->data; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectAllNotes(): void |  | ||||||
|     { |  | ||||||
|         // grab all notes for all journals:
 |  | ||||||
|         $notes = Note::whereNoteableType(TransactionJournal::class)->whereIn('noteable_id', array_keys($this->journals))->get(); |  | ||||||
| 
 |  | ||||||
|         /** @var Note $note */ |  | ||||||
|         foreach ($notes as $note) { |  | ||||||
|             $id                           = $note->noteable_id; |  | ||||||
|             $this->journals[$id]['notes'] = $note->text; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectAllLocations(): void |  | ||||||
|     { |  | ||||||
|         // grab all locations for all journals:
 |  | ||||||
|         $locations = Location::whereLocatableType(TransactionJournal::class)->whereIn('locatable_id', array_keys($this->journals))->get(); |  | ||||||
| 
 |  | ||||||
|         /** @var Location $location */ |  | ||||||
|         foreach ($locations as $location) { |  | ||||||
|             $id                              = $location->locatable_id; |  | ||||||
|             $this->journals[$id]['location'] = [ |  | ||||||
|                 'latitude'   => $location->latitude, |  | ||||||
|                 'longitude'  => $location->longitude, |  | ||||||
|                 'zoom_level' => $location->zoom_level, |  | ||||||
|             ]; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectAllTags(): void |  | ||||||
|     { |  | ||||||
|         // grab all tags for all journals:
 |  | ||||||
|         $tags = DB::table('tag_transaction_journal') |  | ||||||
|             ->leftJoin('tags', 'tags.id', 'tag_transaction_journal.tag_id') |  | ||||||
|             ->whereIn('tag_transaction_journal.transaction_journal_id', array_keys($this->journals)) |  | ||||||
|             ->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag']) |  | ||||||
|         ; |  | ||||||
| 
 |  | ||||||
|         /** @var stdClass $tag */ |  | ||||||
|         foreach ($tags as $tag) { |  | ||||||
|             $id                            = (int) $tag->transaction_journal_id; |  | ||||||
|             $this->journals[$id]['tags'][] = $tag->tag; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function collectAllCurrencies(): void |  | ||||||
|     { |  | ||||||
|         /** @var TransactionJournal $journal */ |  | ||||||
|         foreach ($this->objects as $journal) { |  | ||||||
|             $id                                         = $journal->id; |  | ||||||
|             $this->journals[$id]['reconciled']          = false; |  | ||||||
|             $this->journals[$id]['foreign_amount']      = null; |  | ||||||
|             $this->journals[$id]['foreign_currency_id'] = null; |  | ||||||
|             $this->journals[$id]['amount']              = null; |  | ||||||
|             $this->journals[$id]['currency_id']         = null; |  | ||||||
|             $this->journals[$id]['type']                = $journal->transactionType->type; |  | ||||||
|             $this->journals[$id]['budget_id']           = null; |  | ||||||
|             $this->journals[$id]['budget_name']         = null; |  | ||||||
|             $this->journals[$id]['category_id']         = null; |  | ||||||
|             $this->journals[$id]['category_name']       = null; |  | ||||||
|             $this->journals[$id]['bill_id']             = null; |  | ||||||
|             $this->journals[$id]['bill_name']           = null; |  | ||||||
| 
 |  | ||||||
|             // collect budget:
 |  | ||||||
|             /** @var null|Budget $budget */ |  | ||||||
|             $budget                                     = $journal->budgets()->first(); |  | ||||||
|             if (null !== $budget) { |  | ||||||
|                 $this->journals[$id]['budget_id']   = (string) $budget->id; |  | ||||||
|                 $this->journals[$id]['budget_name'] = $budget->name; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // collect category:
 |  | ||||||
|             /** @var null|Category $category */ |  | ||||||
|             $category                                   = $journal->categories()->first(); |  | ||||||
|             if (null !== $category) { |  | ||||||
|                 $this->journals[$id]['category_id']   = (string) $category->id; |  | ||||||
|                 $this->journals[$id]['category_name'] = $category->name; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // collect bill:
 |  | ||||||
|             if (null !== $journal->bill_id) { |  | ||||||
|                 $bill                             = $journal->bill; |  | ||||||
|                 $this->journals[$id]['bill_id']   = (string) $bill->id; |  | ||||||
|                 $this->journals[$id]['bill_name'] = $bill->name; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             /** @var Transaction $transaction */ |  | ||||||
|             foreach ($journal->transactions as $transaction) { |  | ||||||
|                 if (-1 === bccomp((string) $transaction->amount, '0')) { |  | ||||||
|                     // only collect source account info
 |  | ||||||
|                     $account                                    = $transaction->account; |  | ||||||
|                     $this->accountTypes[$account->account_type_id] ??= $account->accountType->type; |  | ||||||
|                     $this->journals[$id]['source_account_name'] = $account->name; |  | ||||||
|                     $this->journals[$id]['source_account_iban'] = $account->iban; |  | ||||||
|                     $this->journals[$id]['source_account_type'] = $this->accountTypes[$account->account_type_id]; |  | ||||||
|                     $this->journals[$id]['source_account_id']   = $transaction->account_id; |  | ||||||
|                     $this->journals[$id]['reconciled']          = $transaction->reconciled; |  | ||||||
| 
 |  | ||||||
|                     continue; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 // add account
 |  | ||||||
|                 $account                                         = $transaction->account; |  | ||||||
|                 $this->accountTypes[$account->account_type_id] ??= $account->accountType->type; |  | ||||||
|                 $this->journals[$id]['destination_account_name'] = $account->name; |  | ||||||
|                 $this->journals[$id]['destination_account_iban'] = $account->iban; |  | ||||||
|                 $this->journals[$id]['destination_account_type'] = $this->accountTypes[$account->account_type_id]; |  | ||||||
|                 $this->journals[$id]['destination_account_id']   = $transaction->account_id; |  | ||||||
| 
 |  | ||||||
|                 // find and set currency
 |  | ||||||
|                 $currencyId                                      = $transaction->transaction_currency_id; |  | ||||||
|                 $this->currencies[$currencyId]                 ??= $transaction->transactionCurrency; |  | ||||||
|                 $this->journals[$id]['currency_id']              = $currencyId; |  | ||||||
|                 $this->journals[$id]['amount']                   = $transaction->amount; |  | ||||||
|                 // find and set foreign currency
 |  | ||||||
|                 if (null !== $transaction->foreign_currency_id) { |  | ||||||
|                     $foreignCurrencyId                          = $transaction->foreign_currency_id; |  | ||||||
|                     $this->currencies[$foreignCurrencyId] ??= $transaction->foreignCurrency; |  | ||||||
|                     $this->journals[$id]['foreign_currency_id'] = $foreignCurrencyId; |  | ||||||
|                     $this->journals[$id]['foreign_amount']      = $transaction->foreign_amount; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 // find and set destination account info.
 |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public function transform(array|TransactionGroup $group): array |  | ||||||
|     { |  | ||||||
|         if (is_array($group)) { |  | ||||||
|             $first = reset($group['transactions']); |  | ||||||
| 
 |  | ||||||
|             return [ |  | ||||||
|                 'id'           => (string) $group['id'], |  | ||||||
|                 'created_at'   => $group['created_at']->toAtomString(), |  | ||||||
|                 'updated_at'   => $group['updated_at']->toAtomString(), |  | ||||||
|                 'user'         => (string) $first['user_id'], |  | ||||||
|                 'user_group'   => (string) $first['user_group_id'], |  | ||||||
|                 'group_title'  => $group['title'] ?? null, |  | ||||||
|                 'transactions' => $this->transformTransactions($group['transactions'] ?? []), |  | ||||||
|                 'links'        => [ |  | ||||||
|                     [ |  | ||||||
|                         'rel' => 'self', |  | ||||||
|                         'uri' => sprintf('/transactions/%d', $group['id']), |  | ||||||
|                     ], |  | ||||||
|                 ], |  | ||||||
|             ]; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return [ |  | ||||||
|             'id'           => (string) $group->id, |  | ||||||
|             'created_at'   => $group->created_at->toAtomString(), |  | ||||||
|             'updated_at'   => $group->created_at->toAtomString(), |  | ||||||
|             'user'         => (string) $group->user_id, |  | ||||||
|             'user_group'   => (string) $group->user_group_id, |  | ||||||
|             'group_title'  => $group->title ?? null, |  | ||||||
|             'transactions' => $this->transformJournals($group), |  | ||||||
|             'links'        => [ |  | ||||||
|                 [ |  | ||||||
|                     'rel' => 'self', |  | ||||||
|                     'uri' => sprintf('/transactions/%d', $group->id), |  | ||||||
|                 ], |  | ||||||
|             ], |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function transformTransactions(array $transactions): array |  | ||||||
|     { |  | ||||||
|         $return = []; |  | ||||||
| 
 |  | ||||||
|         /** @var array $transaction */ |  | ||||||
|         foreach ($transactions as $transaction) { |  | ||||||
|             $return[] = $this->transformTransaction($transaction); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @throws FireflyException |  | ||||||
|      * |  | ||||||
|      * @SuppressWarnings("PHPMD.ExcessiveMethodLength") |  | ||||||
|      */ |  | ||||||
|     private function transformTransaction(array $transaction): array |  | ||||||
|     { |  | ||||||
|         $transaction         = new NullArrayObject($transaction); |  | ||||||
|         $type                = $this->stringFromArray($transaction, 'transaction_type_type', TransactionTypeEnum::WITHDRAWAL->value); |  | ||||||
|         $journalId           = (int) $transaction['transaction_journal_id']; |  | ||||||
|         $meta                = new NullArrayObject($this->meta[$journalId] ?? []); |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Convert and use amount: |  | ||||||
|          */ |  | ||||||
|         $amount              = app('steam')->positive((string) ($transaction['amount'] ?? '0')); |  | ||||||
|         $currencyId          = (int) $transaction['currency_id']; |  | ||||||
|         $nativeAmount        = $this->converter->convert($this->default, $this->currencies[$currencyId], $transaction['date'], $amount); |  | ||||||
|         $foreignAmount       = null; |  | ||||||
|         $nativeForeignAmount = null; |  | ||||||
|         if (null !== $transaction['foreign_amount']) { |  | ||||||
|             $foreignCurrencyId   = (int) $transaction['foreign_currency_id']; |  | ||||||
|             $foreignAmount       = app('steam')->positive($transaction['foreign_amount']); |  | ||||||
|             $nativeForeignAmount = $this->converter->convert($this->default, $this->currencies[$foreignCurrencyId], $transaction['date'], $foreignAmount); |  | ||||||
|         } |  | ||||||
|         $this->converter->summarize(); |  | ||||||
| 
 |  | ||||||
|         $longitude           = null; |  | ||||||
|         $latitude            = null; |  | ||||||
|         $zoomLevel           = null; |  | ||||||
|         if (array_key_exists('location', $this->journals[$journalId])) { |  | ||||||
|             $latitude  = (string) $this->journals[$journalId]['location']['latitude']; |  | ||||||
|             $longitude = (string) $this->journals[$journalId]['location']['longitude']; |  | ||||||
|             $zoomLevel = $this->journals[$journalId]['location']['zoom_level']; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return [ |  | ||||||
|             'user'                            => (string) $transaction['user_id'], |  | ||||||
|             'user_group'                      => (string) $transaction['user_group_id'], |  | ||||||
|             'transaction_journal_id'          => (string) $transaction['transaction_journal_id'], |  | ||||||
|             'type'                            => strtolower((string) $type), |  | ||||||
|             'date'                            => $transaction['date']->toAtomString(), |  | ||||||
|             'order'                           => $transaction['order'], |  | ||||||
|             'amount'                          => $amount, |  | ||||||
|             'native_amount'                   => $nativeAmount, |  | ||||||
|             'foreign_amount'                  => $foreignAmount, |  | ||||||
|             'native_foreign_amount'           => $nativeForeignAmount, |  | ||||||
|             'currency_id'                     => (string) $transaction['currency_id'], |  | ||||||
|             'currency_code'                   => $transaction['currency_code'], |  | ||||||
|             'currency_name'                   => $transaction['currency_name'], |  | ||||||
|             'currency_symbol'                 => $transaction['currency_symbol'], |  | ||||||
|             'currency_decimal_places'         => (int) $transaction['currency_decimal_places'], |  | ||||||
| 
 |  | ||||||
|             // converted to native currency
 |  | ||||||
|             'native_currency_id'              => (string) $this->default->id, |  | ||||||
|             'native_currency_code'            => $this->default->code, |  | ||||||
|             'native_currency_name'            => $this->default->name, |  | ||||||
|             'native_currency_symbol'          => $this->default->symbol, |  | ||||||
|             'native_currency_decimal_places'  => $this->default->decimal_places, |  | ||||||
| 
 |  | ||||||
|             // foreign currency amount:
 |  | ||||||
|             'foreign_currency_id'             => $this->stringFromArray($transaction, 'foreign_currency_id', null), |  | ||||||
|             'foreign_currency_code'           => $transaction['foreign_currency_code'], |  | ||||||
|             'foreign_currency_name'           => $transaction['foreign_currency_name'], |  | ||||||
|             'foreign_currency_symbol'         => $transaction['foreign_currency_symbol'], |  | ||||||
|             'foreign_currency_decimal_places' => $transaction['foreign_currency_decimal_places'], |  | ||||||
| 
 |  | ||||||
|             // foreign converted to native:
 |  | ||||||
|             'description'                     => $transaction['description'], |  | ||||||
|             'source_id'                       => (string) $transaction['source_account_id'], |  | ||||||
|             'source_name'                     => $transaction['source_account_name'], |  | ||||||
|             'source_iban'                     => $transaction['source_account_iban'], |  | ||||||
|             'source_type'                     => $transaction['source_account_type'], |  | ||||||
|             'destination_id'                  => (string) $transaction['destination_account_id'], |  | ||||||
|             'destination_name'                => $transaction['destination_account_name'], |  | ||||||
|             'destination_iban'                => $transaction['destination_account_iban'], |  | ||||||
|             'destination_type'                => $transaction['destination_account_type'], |  | ||||||
|             'budget_id'                       => $this->stringFromArray($transaction, 'budget_id', null), |  | ||||||
|             'budget_name'                     => $transaction['budget_name'], |  | ||||||
|             'category_id'                     => $this->stringFromArray($transaction, 'category_id', null), |  | ||||||
|             'category_name'                   => $transaction['category_name'], |  | ||||||
|             'bill_id'                         => $this->stringFromArray($transaction, 'bill_id', null), |  | ||||||
|             'bill_name'                       => $transaction['bill_name'], |  | ||||||
|             'reconciled'                      => $transaction['reconciled'], |  | ||||||
|             'notes'                           => $this->notes[$journalId] ?? null, |  | ||||||
|             'tags'                            => $this->tags[$journalId] ?? [], |  | ||||||
|             'internal_reference'              => $meta['internal_reference'], |  | ||||||
|             'external_id'                     => $meta['external_id'], |  | ||||||
|             'original_source'                 => $meta['original_source'], |  | ||||||
|             'recurrence_id'                   => $meta['recurrence_id'], |  | ||||||
|             'recurrence_total'                => $meta['recurrence_total'], |  | ||||||
|             'recurrence_count'                => $meta['recurrence_count'], |  | ||||||
|             'external_url'                    => $meta['external_url'], |  | ||||||
|             'import_hash_v2'                  => $meta['import_hash_v2'], |  | ||||||
|             'sepa_cc'                         => $meta['sepa_cc'], |  | ||||||
|             'sepa_ct_op'                      => $meta['sepa_ct_op'], |  | ||||||
|             'sepa_ct_id'                      => $meta['sepa_ct_id'], |  | ||||||
|             'sepa_db'                         => $meta['sepa_db'], |  | ||||||
|             'sepa_country'                    => $meta['sepa_country'], |  | ||||||
|             'sepa_ep'                         => $meta['sepa_ep'], |  | ||||||
|             'sepa_ci'                         => $meta['sepa_ci'], |  | ||||||
|             'sepa_batch_id'                   => $meta['sepa_batch_id'], |  | ||||||
|             'interest_date'                   => $this->date($meta['interest_date']), |  | ||||||
|             'book_date'                       => $this->date($meta['book_date']), |  | ||||||
|             'process_date'                    => $this->date($meta['process_date']), |  | ||||||
|             'due_date'                        => $this->date($meta['due_date']), |  | ||||||
|             'payment_date'                    => $this->date($meta['payment_date']), |  | ||||||
|             'invoice_date'                    => $this->date($meta['invoice_date']), |  | ||||||
| 
 |  | ||||||
|             // location data
 |  | ||||||
|             'longitude'                       => $longitude, |  | ||||||
|             'latitude'                        => $latitude, |  | ||||||
|             'zoom_level'                      => $zoomLevel, |  | ||||||
|             //
 |  | ||||||
|             //            'has_attachments' => $this->hasAttachments((int) $row['transaction_journal_id']),
 |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * TODO also in the old transformer. |  | ||||||
|      * |  | ||||||
|      * Used to extract a value from the given array, and fall back on a sensible default or NULL |  | ||||||
|      * if it can't be helped. |  | ||||||
|      */ |  | ||||||
|     private function stringFromArray(NullArrayObject $array, string $key, ?string $default): ?string |  | ||||||
|     { |  | ||||||
|         // app('log')->debug(sprintf('%s: %s', $key, var_export($array[$key], true)));
 |  | ||||||
|         if (null === $array[$key] && null === $default) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         if (0 === $array[$key]) { |  | ||||||
|             return $default; |  | ||||||
|         } |  | ||||||
|         if ('0' === $array[$key]) { |  | ||||||
|             return $default; |  | ||||||
|         } |  | ||||||
|         if (null !== $array[$key]) { |  | ||||||
|             return (string) $array[$key]; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (null !== $default) { |  | ||||||
|             return $default; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function date(?string $string): ?Carbon |  | ||||||
|     { |  | ||||||
|         if (null === $string) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         //        app('log')->debug(sprintf('Now in date("%s")', $string));
 |  | ||||||
|         if (10 === strlen($string)) { |  | ||||||
|             $res = Carbon::createFromFormat('Y-m-d', $string, config('app.timezone')); |  | ||||||
|             if (!$res instanceof Carbon) { |  | ||||||
|                 return null; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return $res; |  | ||||||
|         } |  | ||||||
|         if (25 === strlen($string)) { |  | ||||||
|             return Carbon::parse($string, config('app.timezone')); |  | ||||||
|         } |  | ||||||
|         if (19 === strlen($string) && str_contains($string, 'T')) { |  | ||||||
|             $res = Carbon::createFromFormat('Y-m-d\TH:i:s', substr($string, 0, 19), config('app.timezone')); |  | ||||||
|             if (!$res instanceof Carbon) { |  | ||||||
|                 return null; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             return $res; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // 2022-01-01 01:01:01
 |  | ||||||
|         $res = Carbon::createFromFormat('Y-m-d H:i:s', substr($string, 0, 19), config('app.timezone')); |  | ||||||
|         if (!$res instanceof Carbon) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $res; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function transformJournals(TransactionGroup $group): array |  | ||||||
|     { |  | ||||||
|         $return = []; |  | ||||||
| 
 |  | ||||||
|         /** @var TransactionJournal $journal */ |  | ||||||
|         foreach ($group->transactionJournals as $journal) { |  | ||||||
|             $return[] = $this->transformJournal($journal); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @throws FireflyException |  | ||||||
|      * |  | ||||||
|      * @SuppressWarnings("PHPMD.ExcessiveMethodLength") |  | ||||||
|      */ |  | ||||||
|     private function transformJournal(TransactionJournal $journal): array |  | ||||||
|     { |  | ||||||
|         $id                  = $journal->id; |  | ||||||
| 
 |  | ||||||
|         /** @var null|TransactionCurrency $foreignCurrency */ |  | ||||||
|         $foreignCurrency     = null; |  | ||||||
| 
 |  | ||||||
|         /** @var TransactionCurrency $currency */ |  | ||||||
|         $currency            = $this->currencies[$this->journals[$id]['currency_id']]; |  | ||||||
|         $nativeForeignAmount = null; |  | ||||||
|         $amount              = $this->journals[$journal->id]['amount']; |  | ||||||
|         $foreignAmount       = $this->journals[$journal->id]['foreign_amount']; |  | ||||||
|         $meta                = new NullArrayObject($this->meta[$id] ?? []); |  | ||||||
| 
 |  | ||||||
|         // has foreign amount?
 |  | ||||||
|         if (null !== $foreignAmount) { |  | ||||||
|             $foreignCurrency     = $this->currencies[$this->journals[$id]['foreign_currency_id']]; |  | ||||||
|             $nativeForeignAmount = $this->converter->convert($this->default, $foreignCurrency, $journal->date, $foreignAmount); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         $nativeAmount        = $this->converter->convert($this->default, $currency, $journal->date, $amount); |  | ||||||
| 
 |  | ||||||
|         $longitude           = null; |  | ||||||
|         $latitude            = null; |  | ||||||
|         $zoomLevel           = null; |  | ||||||
|         if (array_key_exists('location', $this->journals[$id])) { |  | ||||||
|             $latitude  = (string) $this->journals[$id]['location']['latitude']; |  | ||||||
|             $longitude = (string) $this->journals[$id]['location']['longitude']; |  | ||||||
|             $zoomLevel = $this->journals[$id]['location']['zoom_level']; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return [ |  | ||||||
|             'user'                            => (string) $journal->user_id, |  | ||||||
|             'user_group'                      => (string) $journal->user_group_id, |  | ||||||
|             'transaction_journal_id'          => (string) $journal->id, |  | ||||||
|             'type'                            => $this->journals[$journal->id]['type'], |  | ||||||
|             'date'                            => $journal->date->toAtomString(), |  | ||||||
|             'order'                           => $journal->order, |  | ||||||
|             'amount'                          => $amount, |  | ||||||
|             'native_amount'                   => $nativeAmount, |  | ||||||
|             'foreign_amount'                  => $foreignAmount, |  | ||||||
|             'native_foreign_amount'           => $nativeForeignAmount, |  | ||||||
|             'currency_id'                     => (string) $currency->id, |  | ||||||
|             'currency_code'                   => $currency->code, |  | ||||||
|             'currency_name'                   => $currency->name, |  | ||||||
|             'currency_symbol'                 => $currency->symbol, |  | ||||||
|             'currency_decimal_places'         => $currency->decimal_places, |  | ||||||
| 
 |  | ||||||
|             // converted to native currency
 |  | ||||||
|             'native_currency_id'              => (string) $this->default->id, |  | ||||||
|             'native_currency_code'            => $this->default->code, |  | ||||||
|             'native_currency_name'            => $this->default->name, |  | ||||||
|             'native_currency_symbol'          => $this->default->symbol, |  | ||||||
|             'native_currency_decimal_places'  => $this->default->decimal_places, |  | ||||||
| 
 |  | ||||||
|             // foreign currency amount:
 |  | ||||||
|             'foreign_currency_id'             => $foreignCurrency?->id, |  | ||||||
|             'foreign_currency_code'           => $foreignCurrency?->code, |  | ||||||
|             'foreign_currency_name'           => $foreignCurrency?->name, |  | ||||||
|             'foreign_currency_symbol'         => $foreignCurrency?->symbol, |  | ||||||
|             'foreign_currency_decimal_places' => $foreignCurrency?->decimal_places, |  | ||||||
| 
 |  | ||||||
|             'description'                     => $journal->description, |  | ||||||
|             'source_id'                       => (string) $this->journals[$id]['source_account_id'], |  | ||||||
|             'source_name'                     => $this->journals[$id]['source_account_name'], |  | ||||||
|             'source_iban'                     => $this->journals[$id]['source_account_iban'], |  | ||||||
|             'source_type'                     => $this->journals[$id]['source_account_type'], |  | ||||||
| 
 |  | ||||||
|             'destination_id'                  => (string) $this->journals[$id]['destination_account_id'], |  | ||||||
|             'destination_name'                => $this->journals[$id]['destination_account_name'], |  | ||||||
|             'destination_iban'                => $this->journals[$id]['destination_account_iban'], |  | ||||||
|             'destination_type'                => $this->journals[$id]['destination_account_type'], |  | ||||||
| 
 |  | ||||||
|             'budget_id'                       => $this->journals[$id]['budget_id'], |  | ||||||
|             'budget_name'                     => $this->journals[$id]['budget_name'], |  | ||||||
|             'category_id'                     => $this->journals[$id]['category_id'], |  | ||||||
|             'category_name'                   => $this->journals[$id]['category_name'], |  | ||||||
|             'bill_id'                         => $this->journals[$id]['bill_id'], |  | ||||||
|             'bill_name'                       => $this->journals[$id]['bill_name'], |  | ||||||
|             'reconciled'                      => $this->journals[$id]['reconciled'], |  | ||||||
|             'notes'                           => $this->journals[$id]['notes'] ?? null, |  | ||||||
|             'tags'                            => $this->journals[$id]['tags'] ?? [], |  | ||||||
|             'internal_reference'              => $meta['internal_reference'], |  | ||||||
|             'external_id'                     => $meta['external_id'], |  | ||||||
|             'original_source'                 => $meta['original_source'], |  | ||||||
|             'recurrence_id'                   => $meta['recurrence_id'], |  | ||||||
|             'recurrence_total'                => $meta['recurrence_total'], |  | ||||||
|             'recurrence_count'                => $meta['recurrence_count'], |  | ||||||
|             'external_url'                    => $meta['external_url'], |  | ||||||
|             'import_hash_v2'                  => $meta['import_hash_v2'], |  | ||||||
|             'sepa_cc'                         => $meta['sepa_cc'], |  | ||||||
|             'sepa_ct_op'                      => $meta['sepa_ct_op'], |  | ||||||
|             'sepa_ct_id'                      => $meta['sepa_ct_id'], |  | ||||||
|             'sepa_db'                         => $meta['sepa_db'], |  | ||||||
|             'sepa_country'                    => $meta['sepa_country'], |  | ||||||
|             'sepa_ep'                         => $meta['sepa_ep'], |  | ||||||
|             'sepa_ci'                         => $meta['sepa_ci'], |  | ||||||
|             'sepa_batch_id'                   => $meta['sepa_batch_id'], |  | ||||||
|             'interest_date'                   => $this->date($meta['interest_date']), |  | ||||||
|             'book_date'                       => $this->date($meta['book_date']), |  | ||||||
|             'process_date'                    => $this->date($meta['process_date']), |  | ||||||
|             'due_date'                        => $this->date($meta['due_date']), |  | ||||||
|             'payment_date'                    => $this->date($meta['payment_date']), |  | ||||||
|             'invoice_date'                    => $this->date($meta['invoice_date']), |  | ||||||
| 
 |  | ||||||
|             // location data
 |  | ||||||
|             'longitude'                       => $longitude, |  | ||||||
|             'latitude'                        => $latitude, |  | ||||||
|             'zoom_level'                      => $zoomLevel, |  | ||||||
|             //
 |  | ||||||
|             //            'has_attachments' => $this->hasAttachments((int) $row['transaction_journal_id']),
 |  | ||||||
|         ]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,120 +0,0 @@ | |||||||
| <?php |  | ||||||
| 
 |  | ||||||
| /* |  | ||||||
|  * UserGroupTransformer.php |  | ||||||
|  * Copyright (c) 2023 james@firefly-iii.org |  | ||||||
|  * |  | ||||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). |  | ||||||
|  * |  | ||||||
|  * This program is free software: you can redistribute it and/or modify |  | ||||||
|  * it under the terms of the GNU Affero General Public License as |  | ||||||
|  * published by the Free Software Foundation, either version 3 of the |  | ||||||
|  * License, or (at your option) any later version. |  | ||||||
|  * |  | ||||||
|  * This program is distributed in the hope that it will be useful, |  | ||||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|  * GNU Affero General Public License for more details. |  | ||||||
|  * |  | ||||||
|  * You should have received a copy of the GNU Affero General Public License |  | ||||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| declare(strict_types=1); |  | ||||||
| 
 |  | ||||||
| namespace FireflyIII\Transformers\V2; |  | ||||||
| 
 |  | ||||||
| use FireflyIII\Enums\UserRoleEnum; |  | ||||||
| use FireflyIII\Models\GroupMembership; |  | ||||||
| use FireflyIII\Models\UserGroup; |  | ||||||
| use FireflyIII\User; |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Class UserGroupTransformer |  | ||||||
|  * |  | ||||||
|  * @deprecated |  | ||||||
|  */ |  | ||||||
| class UserGroupTransformer extends AbstractTransformer |  | ||||||
| { |  | ||||||
|     private array $inUse; |  | ||||||
|     private array $memberships; |  | ||||||
|     private array $membershipsVisible; |  | ||||||
| 
 |  | ||||||
|     public function __construct() |  | ||||||
|     { |  | ||||||
|         $this->memberships        = []; |  | ||||||
|         $this->membershipsVisible = []; |  | ||||||
|         $this->inUse              = []; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public function collectMetaData(Collection $objects): Collection |  | ||||||
|     { |  | ||||||
|         if (auth()->check()) { |  | ||||||
|             // collect memberships so they can be listed in the group.
 |  | ||||||
|             /** @var User $user */ |  | ||||||
|             $user = auth()->user(); |  | ||||||
| 
 |  | ||||||
|             /** @var UserGroup $userGroup */ |  | ||||||
|             foreach ($objects as $userGroup) { |  | ||||||
|                 $userGroupId                            = $userGroup->id; |  | ||||||
|                 $this->inUse[$userGroupId]              = $user->user_group_id === $userGroupId; |  | ||||||
|                 $access                                 = $user->hasRoleInGroupOrOwner($userGroup, UserRoleEnum::VIEW_MEMBERSHIPS) || $user->hasRole('owner'); |  | ||||||
|                 $this->membershipsVisible[$userGroupId] = $access; |  | ||||||
|                 if ($access) { |  | ||||||
|                     $groupMemberships = $userGroup->groupMemberships()->get(); |  | ||||||
| 
 |  | ||||||
|                     /** @var GroupMembership $groupMembership */ |  | ||||||
|                     foreach ($groupMemberships as $groupMembership) { |  | ||||||
|                         $this->memberships[$userGroupId][] = [ |  | ||||||
|                             'user_id'    => (string) $groupMembership->user_id, |  | ||||||
|                             'user_email' => $groupMembership->user->email, |  | ||||||
|                             'role'       => $groupMembership->userRole->title, |  | ||||||
|                             'you'        => $groupMembership->user_id === $user->id, |  | ||||||
|                         ]; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             $this->mergeMemberships(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $objects; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function mergeMemberships(): void |  | ||||||
|     { |  | ||||||
|         $new               = []; |  | ||||||
|         foreach ($this->memberships as $groupId => $members) { |  | ||||||
|             $new[$groupId] ??= []; |  | ||||||
| 
 |  | ||||||
|             foreach ($members as $member) { |  | ||||||
|                 $mail                            = $member['user_email']; |  | ||||||
|                 $new[$groupId][$mail] ??= [ |  | ||||||
|                     'user_id'    => $member['user_id'], |  | ||||||
|                     'user_email' => $member['user_email'], |  | ||||||
|                     'you'        => $member['you'], |  | ||||||
|                     'roles'      => [], |  | ||||||
|                 ]; |  | ||||||
|                 $new[$groupId][$mail]['roles'][] = $member['role']; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         $this->memberships = $new; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Transform the user group. |  | ||||||
|      */ |  | ||||||
|     public function transform(UserGroup $userGroup): array |  | ||||||
|     { |  | ||||||
|         return [ |  | ||||||
|             'id'              => $userGroup->id, |  | ||||||
|             'created_at'      => $userGroup->created_at->toAtomString(), |  | ||||||
|             'updated_at'      => $userGroup->updated_at->toAtomString(), |  | ||||||
|             'in_use'          => $this->inUse[$userGroup->id] ?? false, |  | ||||||
|             'title'           => $userGroup->title, |  | ||||||
|             'can_see_members' => $this->membershipsVisible[$userGroup->id] ?? false, |  | ||||||
|             'members'         => array_values($this->memberships[$userGroup->id] ?? []), |  | ||||||
|         ]; |  | ||||||
|         // if the user has a specific role in this group, then collect the memberships.
 |  | ||||||
|     } |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user