mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	🤖 Auto commit for release 'develop' on 2025-08-03
This commit is contained in:
		| @@ -72,12 +72,12 @@ class ShowController extends Controller | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|         $manager = $this->getManager(); | ||||
|         $manager          = $this->getManager(); | ||||
| 
 | ||||
|         // types to get, page size:
 | ||||
|         $pageSize = $this->parameters->get('limit'); | ||||
|         $start    = $this->parameters->get('start'); | ||||
|         $end      = $this->parameters->get('end'); | ||||
|         $pageSize         = $this->parameters->get('limit'); | ||||
|         $start            = $this->parameters->get('start'); | ||||
|         $end              = $this->parameters->get('end'); | ||||
| 
 | ||||
|         // get list of available budgets. Count it and split it.
 | ||||
|         $collection       = $this->abRepository->getAvailableBudgetsByDate($start, $end); | ||||
| @@ -86,20 +86,20 @@ class ShowController extends Controller | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin      = auth()->user(); | ||||
|         $enrichment = new AvailableBudgetEnrichment(); | ||||
|         $admin            = auth()->user(); | ||||
|         $enrichment       = new AvailableBudgetEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $availableBudgets = $enrichment->enrich($availableBudgets); | ||||
| 
 | ||||
|         // make paginator:
 | ||||
|         $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.available-budgets.index') . $this->buildParams()); | ||||
|         $paginator        = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.available-budgets.index').$this->buildParams()); | ||||
| 
 | ||||
|         /** @var AvailableBudgetTransformer $transformer */ | ||||
|         $transformer = app(AvailableBudgetTransformer::class); | ||||
|         $transformer      = app(AvailableBudgetTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         $resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets'); | ||||
|         $resource         = new FractalCollection($availableBudgets, $transformer, 'available_budgets'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
| 
 | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
| @@ -113,25 +113,25 @@ class ShowController extends Controller | ||||
|      */ | ||||
|     public function show(AvailableBudget $availableBudget): JsonResponse | ||||
|     { | ||||
|         $manager = $this->getManager(); | ||||
|         $start   = $this->parameters->get('start'); | ||||
|         $end     = $this->parameters->get('end'); | ||||
|         $manager         = $this->getManager(); | ||||
|         $start           = $this->parameters->get('start'); | ||||
|         $end             = $this->parameters->get('end'); | ||||
| 
 | ||||
|         /** @var AvailableBudgetTransformer $transformer */ | ||||
|         $transformer = app(AvailableBudgetTransformer::class); | ||||
|         $transformer     = app(AvailableBudgetTransformer::class); | ||||
|         $transformer->setParameters($this->parameters); | ||||
| 
 | ||||
|         // enrich
 | ||||
|         /** @var User $admin */ | ||||
|         $admin      = auth()->user(); | ||||
|         $enrichment = new AvailableBudgetEnrichment(); | ||||
|         $admin           = auth()->user(); | ||||
|         $enrichment      = new AvailableBudgetEnrichment(); | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setStart($start); | ||||
|         $enrichment->setEnd($end); | ||||
|         $availableBudget = $enrichment->enrichSingle($availableBudget); | ||||
| 
 | ||||
| 
 | ||||
|         $resource = new Item($availableBudget, $transformer, 'available_budgets'); | ||||
|         $resource        = new Item($availableBudget, $transformer, 'available_budgets'); | ||||
| 
 | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); | ||||
|     } | ||||
|   | ||||
| @@ -25,7 +25,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Api\V1\Requests\Models\PiggyBank; | ||||
| 
 | ||||
| use Illuminate\Contracts\Validation\Validator; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Rules\IsValidZeroOrMoreAmount; | ||||
| @@ -97,7 +96,7 @@ class StoreRequest extends FormRequest | ||||
|                 // validate start before end only if both are there.
 | ||||
|                 $data          = $validator->getData(); | ||||
|                 $currency      = $this->getCurrencyFromData($validator, $data); | ||||
|                 if(null === $currency) { | ||||
|                 if (null === $currency) { | ||||
|                     return; | ||||
|                 } | ||||
|                 $targetAmount  = (string) ($data['target_amount'] ?? '0'); | ||||
| @@ -148,6 +147,7 @@ class StoreRequest extends FormRequest | ||||
|             } | ||||
|         } | ||||
|         $validator->errors()->add('transaction_currency_id', trans('validation.require_currency_id_code')); | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -32,7 +32,6 @@ use FireflyIII\Models\TransactionGroup; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\Webhook; | ||||
| use FireflyIII\Models\WebhookMessage; | ||||
| use FireflyIII\Support\Facades\Amount; | ||||
| use FireflyIII\Support\JsonApi\Enrichments\AccountEnrichment; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\Transformers\TransactionGroupTransformer; | ||||
|   | ||||
| @@ -151,6 +151,7 @@ class ShowController extends Controller | ||||
|         $enrichment->setUser($admin); | ||||
|         $enrichment->setStart($start); | ||||
|         $enrichment->setEnd($end); | ||||
| 
 | ||||
|         /** @var Bill $bill */ | ||||
|         $bill                       = $enrichment->enrichSingle($bill); | ||||
| 
 | ||||
|   | ||||
| @@ -32,7 +32,7 @@ use FireflyIII\Support\Report\Summarizer\TransactionSummarizer; | ||||
| use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface; | ||||
| use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Override; | ||||
| 
 | ||||
| /** | ||||
|  * Class NoBudgetRepository | ||||
| @@ -100,10 +100,11 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface, UserGroupInterf | ||||
|         return $summarizer->groupByCurrencyId($journals); | ||||
|     } | ||||
| 
 | ||||
|     #[\Override] public function collectExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array
 | ||||
|     #[Override]
 | ||||
|     public function collectExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array | ||||
|     { | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector  = app(GroupCollectorInterface::class); | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); | ||||
| 
 | ||||
|         if ($accounts instanceof Collection && $accounts->count() > 0) { | ||||
| @@ -114,7 +115,7 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface, UserGroupInterf | ||||
|         } | ||||
|         $collector->withoutBudget(); | ||||
|         $collector->withBudgetInformation(); | ||||
| 
 | ||||
|         return $collector->getExtractedJournals(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|   | ||||
| @@ -39,6 +39,7 @@ use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface; | ||||
| use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Override; | ||||
| 
 | ||||
| /** | ||||
|  * Class OperationsRepository | ||||
| @@ -65,7 +66,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|             ++$count; | ||||
|             app('log')->debug(sprintf('Found %d budget limits. Per day is %s, total is %s', $count, $perDay, $total)); | ||||
|         } | ||||
|         $avg = $total; | ||||
|         $avg   = $total; | ||||
|         if ($count > 0) { | ||||
|             $avg = bcdiv($total, (string) $count); | ||||
|         } | ||||
| @@ -86,21 +87,21 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
| 
 | ||||
|         // get all transactions:
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector    = app(GroupCollectorInterface::class); | ||||
|         $collector->setAccounts($accounts)->setRange($start, $end); | ||||
|         $collector->setBudgets($budgets); | ||||
|         $journals = $collector->getExtractedJournals(); | ||||
|         $journals     = $collector->getExtractedJournals(); | ||||
| 
 | ||||
|         // loop transactions:
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             // prep data array for currency:
 | ||||
|             $budgetId   = (int) $journal['budget_id']; | ||||
|             $budgetName = $journal['budget_name']; | ||||
|             $currencyId = (int) $journal['currency_id']; | ||||
|             $key        = sprintf('%d-%d', $budgetId, $currencyId); | ||||
|             $budgetId                     = (int) $journal['budget_id']; | ||||
|             $budgetName                   = $journal['budget_name']; | ||||
|             $currencyId                   = (int) $journal['currency_id']; | ||||
|             $key                          = sprintf('%d-%d', $budgetId, $currencyId); | ||||
| 
 | ||||
|             $data[$key]                   ??= [ | ||||
|             $data[$key] ??= [ | ||||
|                 'id'                      => $budgetId, | ||||
|                 'name'                    => sprintf('%s (%s)', $budgetName, $journal['currency_name']), | ||||
|                 'sum'                     => '0', | ||||
| @@ -126,7 +127,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|     public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null): array | ||||
|     { | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector             = app(GroupCollectorInterface::class); | ||||
|         $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); | ||||
|         if ($accounts instanceof Collection && $accounts->count() > 0) { | ||||
|             $collector->setAccounts($accounts); | ||||
| @@ -138,8 +139,8 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|             $collector->setBudgets($this->getBudgets()); | ||||
|         } | ||||
|         $collector->withBudgetInformation()->withAccountInformation()->withCategoryInformation(); | ||||
|         $journals = $collector->getExtractedJournals(); | ||||
|         $array    = []; | ||||
|         $journals              = $collector->getExtractedJournals(); | ||||
|         $array                 = []; | ||||
| 
 | ||||
|         // if needs conversion to primary.
 | ||||
|         $convertToPrimary      = Amount::convertToPrimary($this->user); | ||||
| @@ -155,8 +156,8 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|         ]; | ||||
| 
 | ||||
|         foreach ($journals as $journal) { | ||||
|             $amount            = app('steam')->negative($journal['amount']); | ||||
|             $journalCurrencyId = (int) $journal['currency_id']; | ||||
|             $amount                                                                       = app('steam')->negative($journal['amount']); | ||||
|             $journalCurrencyId                                                            = (int) $journal['currency_id']; | ||||
|             if (false === $convertToPrimary) { | ||||
|                 $currencyId            = $journalCurrencyId; | ||||
|                 $currencyName          = $journal['currency_name']; | ||||
| @@ -166,11 +167,11 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|             } | ||||
|             if (true === $convertToPrimary && $journalCurrencyId !== $currencyId) { | ||||
|                 $currencies[$journalCurrencyId] ??= TransactionCurrency::find($journalCurrencyId); | ||||
|                 $amount                         = $converter->convert($currencies[$journalCurrencyId], $primaryCurrency, $journal['date'], $amount); | ||||
|                 $amount = $converter->convert($currencies[$journalCurrencyId], $primaryCurrency, $journal['date'], $amount); | ||||
|             } | ||||
| 
 | ||||
|             $budgetId   = (int) $journal['budget_id']; | ||||
|             $budgetName = (string) $journal['budget_name']; | ||||
|             $budgetId                                                                     = (int) $journal['budget_id']; | ||||
|             $budgetName                                                                   = (string) $journal['budget_name']; | ||||
| 
 | ||||
|             // catch "no budget" entries.
 | ||||
|             if (0 === $budgetId) { | ||||
| @@ -178,7 +179,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|             } | ||||
| 
 | ||||
|             // info about the currency:
 | ||||
|             $array[$currencyId] ??= [ | ||||
|             $array[$currencyId]                       ??= [ | ||||
|                 'budgets'                 => [], | ||||
|                 'currency_id'             => $currencyId, | ||||
|                 'currency_name'           => $currencyName, | ||||
| @@ -231,8 +232,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|         ?Collection          $budgets = null, | ||||
|         ?TransactionCurrency $currency = null, | ||||
|         bool                 $convertToPrimary = false | ||||
|     ): array | ||||
|     { | ||||
|     ): array { | ||||
|         Log::debug(sprintf('Start of %s(date, date, array, array, "%s", %s).', __METHOD__, $currency?->code, var_export($convertToPrimary, true))); | ||||
|         // this collector excludes all transfers TO liabilities (which are also withdrawals)
 | ||||
|         // because those expenses only become expenses once they move from the liability to the friend.
 | ||||
| @@ -240,8 +240,8 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
| 
 | ||||
|         $repository = app(AccountRepositoryInterface::class); | ||||
|         $repository->setUser($this->user); | ||||
|         $subset    = $repository->getAccountsByType(config('firefly.valid_liabilities')); | ||||
|         $selection = new Collection(); | ||||
|         $subset     = $repository->getAccountsByType(config('firefly.valid_liabilities')); | ||||
|         $selection  = new Collection(); | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($subset as $account) { | ||||
| @@ -251,11 +251,12 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|         } | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector  = app(GroupCollectorInterface::class); | ||||
|         $collector->setUser($this->user) | ||||
|                   ->setRange($start, $end) | ||||
|             ->setRange($start, $end) | ||||
|             // ->excludeDestinationAccounts($selection)
 | ||||
|                   ->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); | ||||
|             ->setTypes([TransactionTypeEnum::WITHDRAWAL->value]) | ||||
|         ; | ||||
| 
 | ||||
|         if ($accounts instanceof Collection) { | ||||
|             $collector->setAccounts($accounts); | ||||
| @@ -270,7 +271,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|         if ($budgets->count() > 0) { | ||||
|             $collector->setBudgets($budgets); | ||||
|         } | ||||
|         $journals = $collector->getExtractedJournals(); | ||||
|         $journals   = $collector->getExtractedJournals(); | ||||
| 
 | ||||
|         // same but for transactions in the foreign currency:
 | ||||
|         if ($currency instanceof TransactionCurrency) { | ||||
| @@ -290,14 +291,15 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|         $summarizer->setConvertToPrimary($convertToPrimary); | ||||
| 
 | ||||
|         // filter $journals by range.
 | ||||
|         $expenses = array_filter($expenses, static function (array $expense) use ($start, $end, $transactionCurrency): bool { | ||||
|         $expenses   = array_filter($expenses, static function (array $expense) use ($start, $end, $transactionCurrency): bool { | ||||
|             return $expense['date']->between($start, $end) && $expense['currency_id'] === $transactionCurrency->id; | ||||
|         }); | ||||
| 
 | ||||
|         return $summarizer->groupByCurrencyId($expenses, 'negative', false); | ||||
|     } | ||||
| 
 | ||||
|     #[\Override] public function collectExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null, ?TransactionCurrency $currency = null): array
 | ||||
|     #[Override]
 | ||||
|     public function collectExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null, ?TransactionCurrency $currency = null): array | ||||
|     { | ||||
|         Log::debug(sprintf('Start of %s(date, date, array, array, "%s").', __METHOD__, $currency?->code)); | ||||
|         // this collector excludes all transfers TO liabilities (which are also withdrawals)
 | ||||
| @@ -306,8 +308,8 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
| 
 | ||||
|         $repository = app(AccountRepositoryInterface::class); | ||||
|         $repository->setUser($this->user); | ||||
|         $subset    = $repository->getAccountsByType(config('firefly.valid_liabilities')); | ||||
|         $selection = new Collection(); | ||||
|         $subset     = $repository->getAccountsByType(config('firefly.valid_liabilities')); | ||||
|         $selection  = new Collection(); | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($subset as $account) { | ||||
| @@ -317,11 +319,12 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|         } | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector  = app(GroupCollectorInterface::class); | ||||
|         $collector->setUser($this->user) | ||||
|                   ->setRange($start, $end) | ||||
|             ->setRange($start, $end) | ||||
|             // ->excludeDestinationAccounts($selection)
 | ||||
|                   ->setTypes([TransactionTypeEnum::WITHDRAWAL->value]); | ||||
|             ->setTypes([TransactionTypeEnum::WITHDRAWAL->value]) | ||||
|         ; | ||||
| 
 | ||||
|         if ($accounts instanceof Collection) { | ||||
|             $collector->setAccounts($accounts); | ||||
| @@ -336,6 +339,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn | ||||
|         if ($budgets->count() > 0) { | ||||
|             $collector->setBudgets($budgets); | ||||
|         } | ||||
| 
 | ||||
|         return $collector->getExtractedJournals(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -142,7 +142,7 @@ class Amount | ||||
|         $cache->addProperty('getPrimaryCurrencyByGroup'); | ||||
|         $cache->addProperty($userGroup->id); | ||||
|         if ($cache->has()) { | ||||
|              return $cache->get(); | ||||
|             return $cache->get(); | ||||
|         } | ||||
| 
 | ||||
|         /** @var null|TransactionCurrency $primary */ | ||||
|   | ||||
| @@ -86,7 +86,7 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|     } | ||||
| 
 | ||||
|     #[Override]
 | ||||
|     public function enrichSingle(array | Model $model): Account | array | ||||
|     public function enrichSingle(array|Model $model): Account|array | ||||
|     { | ||||
|         Log::debug(__METHOD__); | ||||
|         $collection = new Collection([$model]); | ||||
| @@ -141,9 +141,10 @@ class AccountEnrichment implements EnrichmentInterface | ||||
| 
 | ||||
|     private function collectMetaData(): void | ||||
|     { | ||||
|         $set = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'BIC', 'liability_direction', 'interest', 'interest_period', 'current_debt']) | ||||
|                           ->whereIn('account_id', $this->accountIds) | ||||
|                           ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray(); | ||||
|         $set                 = AccountMeta::whereIn('name', ['is_multi_currency', 'include_net_worth', 'currency_id', 'account_role', 'account_number', 'BIC', 'liability_direction', 'interest', 'interest_period', 'current_debt']) | ||||
|             ->whereIn('account_id', $this->accountIds) | ||||
|             ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])->toArray() | ||||
|         ; | ||||
| 
 | ||||
|         /** @var array $entry */ | ||||
|         foreach ($set as $entry) { | ||||
| @@ -152,7 +153,7 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|                 $this->currencies[(int) $entry['data']] = true; | ||||
|             } | ||||
|         } | ||||
|         $currencies = TransactionCurrency::whereIn('id', array_keys($this->currencies))->get(); | ||||
|         $currencies          = TransactionCurrency::whereIn('id', array_keys($this->currencies))->get(); | ||||
|         foreach ($currencies as $currency) { | ||||
|             $this->currencies[(int) $currency->id] = $currency; | ||||
|         } | ||||
| @@ -167,9 +168,10 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|     private function collectNotes(): void | ||||
|     { | ||||
|         $notes = Note::query()->whereIn('noteable_id', $this->accountIds) | ||||
|                      ->whereNotNull('notes.text') | ||||
|                      ->where('notes.text', '!=', '') | ||||
|                      ->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); | ||||
|             ->whereNotNull('notes.text') | ||||
|             ->where('notes.text', '!=', '') | ||||
|             ->where('noteable_type', Account::class)->get(['notes.noteable_id', 'notes.text'])->toArray() | ||||
|         ; | ||||
|         foreach ($notes as $note) { | ||||
|             $this->notes[(int) $note['noteable_id']] = (string) $note['text']; | ||||
|         } | ||||
| @@ -179,14 +181,15 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|     private function collectLocations(): void | ||||
|     { | ||||
|         $locations = Location::query()->whereIn('locatable_id', $this->accountIds) | ||||
|                              ->where('locatable_type', Account::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray(); | ||||
|             ->where('locatable_type', Account::class)->get(['locations.locatable_id', 'locations.latitude', 'locations.longitude', 'locations.zoom_level'])->toArray() | ||||
|         ; | ||||
|         foreach ($locations as $location) { | ||||
|             $this->locations[(int) $location['locatable_id']] | ||||
|                 = [ | ||||
|                 'latitude'   => (float) $location['latitude'], | ||||
|                 'longitude'  => (float) $location['longitude'], | ||||
|                 'zoom_level' => (int) $location['zoom_level'], | ||||
|             ]; | ||||
|                     'latitude'   => (float) $location['latitude'], | ||||
|                     'longitude'  => (float) $location['longitude'], | ||||
|                     'zoom_level' => (int) $location['zoom_level'], | ||||
|                 ]; | ||||
|         } | ||||
|         Log::debug(sprintf('Enrich with %d locations(s)', count($this->locations))); | ||||
|     } | ||||
| @@ -201,19 +204,20 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|             ->setUserGroup($this->userGroup) | ||||
|             ->setAccounts($this->collection) | ||||
|             ->withAccountInformation() | ||||
|             ->setTypes([TransactionTypeEnum::OPENING_BALANCE->value]); | ||||
|         $journals = $collector->getExtractedJournals(); | ||||
|             ->setTypes([TransactionTypeEnum::OPENING_BALANCE->value]) | ||||
|         ; | ||||
|         $journals  = $collector->getExtractedJournals(); | ||||
|         foreach ($journals as $journal) { | ||||
|             $this->openingBalances[(int) $journal['source_account_id']] | ||||
|                 = [ | ||||
|                 'amount' => Steam::negative($journal['amount']), | ||||
|                 'date'   => $journal['date'], | ||||
|             ]; | ||||
|                     'amount' => Steam::negative($journal['amount']), | ||||
|                     'date'   => $journal['date'], | ||||
|                 ]; | ||||
|             $this->openingBalances[(int) $journal['destination_account_id']] | ||||
|                 = [ | ||||
|                 'amount' => Steam::positive($journal['amount']), | ||||
|                 'date'   => $journal['date'], | ||||
|             ]; | ||||
|                     'amount' => Steam::positive($journal['amount']), | ||||
|                     'date'   => $journal['date'], | ||||
|                 ]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -268,27 +272,27 @@ class AccountEnrichment implements EnrichmentInterface | ||||
| 
 | ||||
|             // add balances
 | ||||
|             // get currencies:
 | ||||
|             $currency = $this->primaryCurrency; // assume primary currency
 | ||||
|             $currency                = $this->primaryCurrency; // assume primary currency
 | ||||
|             if (null !== $accountMeta['currency']) { | ||||
|                 $currency = $accountMeta['currency']; | ||||
|             } | ||||
| 
 | ||||
|             // get the current balance:
 | ||||
|             $date         = $this->getDate(); | ||||
|             $finalBalance = Steam::finalAccountBalance($item, $date, $this->primaryCurrency, $this->convertToPrimary); | ||||
|             $date                    = $this->getDate(); | ||||
|             $finalBalance            = Steam::finalAccountBalance($item, $date, $this->primaryCurrency, $this->convertToPrimary); | ||||
|             Log::debug(sprintf('Call finalAccountBalance(%s) with date/time "%s"', var_export($this->convertToPrimary, true), $date->toIso8601String()), $finalBalance); | ||||
| 
 | ||||
|             // collect current balances:
 | ||||
|             $currentBalance = Steam::bcround($finalBalance[$currency->code] ?? '0', $currency->decimal_places); | ||||
|             $openingBalance = Steam::bcround($accountMeta['opening_balance_amount'] ?? '0', $currency->decimal_places); | ||||
|             $virtualBalance = Steam::bcround($account->virtual_balance ?? '0', $currency->decimal_places); | ||||
|             $debtAmount     = $accountMeta['current_debt'] ?? null; | ||||
|             $currentBalance          = Steam::bcround($finalBalance[$currency->code] ?? '0', $currency->decimal_places); | ||||
|             $openingBalance          = Steam::bcround($accountMeta['opening_balance_amount'] ?? '0', $currency->decimal_places); | ||||
|             $virtualBalance          = Steam::bcround($account->virtual_balance ?? '0', $currency->decimal_places); | ||||
|             $debtAmount              = $accountMeta['current_debt'] ?? null; | ||||
| 
 | ||||
|             // set some pc_ default values to NULL:
 | ||||
|             $pcCurrentBalance = null; | ||||
|             $pcOpeningBalance = null; | ||||
|             $pcVirtualBalance = null; | ||||
|             $pcDebtAmount     = null; | ||||
|             $pcCurrentBalance        = null; | ||||
|             $pcOpeningBalance        = null; | ||||
|             $pcVirtualBalance        = null; | ||||
|             $pcDebtAmount            = null; | ||||
| 
 | ||||
|             // convert to primary currency if needed:
 | ||||
|             if ($this->convertToPrimary && $currency->id !== $this->primaryCurrency->id) { | ||||
| @@ -331,7 +335,7 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|             if (array_key_exists($item->id, $lastActivities)) { | ||||
|                 $accountMeta['last_activity'] = $lastActivities[$item->id]; | ||||
|             } | ||||
|             $item->meta = $accountMeta; | ||||
|             $item->meta              = $accountMeta; | ||||
| 
 | ||||
|             return $item; | ||||
|         }); | ||||
| @@ -354,8 +358,7 @@ class AccountEnrichment implements EnrichmentInterface | ||||
|         if (null === $this->date) { | ||||
|             return today(); | ||||
|         } | ||||
| 
 | ||||
|         return $this->date; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| <?php | ||||
| 
 | ||||
| /* | ||||
|  * AvailableBudgetEnrichment.php | ||||
|  * Copyright (c) 2025 james@firefly-iii.org. | ||||
| @@ -35,6 +36,7 @@ use FireflyIII\User; | ||||
| use Illuminate\Database\Eloquent\Model; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| use Override; | ||||
| 
 | ||||
| class AvailableBudgetEnrichment implements EnrichmentInterface | ||||
| { | ||||
| @@ -53,8 +55,8 @@ class AvailableBudgetEnrichment implements EnrichmentInterface | ||||
|     private readonly BudgetRepositoryInterface     $repository; | ||||
| 
 | ||||
| 
 | ||||
|     private ?Carbon $start = null; | ||||
|     private ?Carbon $end   = null; | ||||
|     private ?Carbon $start                                                = null; | ||||
|     private ?Carbon $end                                                  = null; | ||||
| 
 | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,7 +67,8 @@ class AvailableBudgetEnrichment implements EnrichmentInterface | ||||
|         $this->repository         = app(BudgetRepositoryInterface::class); | ||||
|     } | ||||
| 
 | ||||
|     #[\Override] public function enrich(Collection $collection): Collection
 | ||||
|     #[Override]
 | ||||
|     public function enrich(Collection $collection): Collection | ||||
|     { | ||||
|         $this->collection = $collection; | ||||
|         $this->collectIds(); | ||||
| @@ -75,7 +78,8 @@ class AvailableBudgetEnrichment implements EnrichmentInterface | ||||
|         return $this->collection; | ||||
|     } | ||||
| 
 | ||||
|     #[\Override] public function enrichSingle(Model | array $model): array | Model
 | ||||
|     #[Override]
 | ||||
|     public function enrichSingle(array|Model $model): array|Model | ||||
|     { | ||||
|         Log::debug(__METHOD__); | ||||
|         $collection = new Collection([$model]); | ||||
| @@ -84,13 +88,15 @@ class AvailableBudgetEnrichment implements EnrichmentInterface | ||||
|         return $collection->first(); | ||||
|     } | ||||
| 
 | ||||
|     #[\Override] public function setUser(User $user): void
 | ||||
|     #[Override]
 | ||||
|     public function setUser(User $user): void | ||||
|     { | ||||
|         $this->user = $user; | ||||
|         $this->setUserGroup($user->userGroup); | ||||
|     } | ||||
| 
 | ||||
|     #[\Override] public function setUserGroup(UserGroup $userGroup): void
 | ||||
|     #[Override]
 | ||||
|     public function setUserGroup(UserGroup $userGroup): void | ||||
|     { | ||||
|         $this->userGroup = $userGroup; | ||||
|         $this->noBudgetRepository->setUserGroup($userGroup); | ||||
| @@ -115,9 +121,9 @@ class AvailableBudgetEnrichment implements EnrichmentInterface | ||||
|         $spentInBudgets      = $this->opsRepository->collectExpenses($start, $end, null, $allActive, null); | ||||
|         $spentOutsideBudgets = $this->noBudgetRepository->collectExpenses($start, $end, null, null, null); | ||||
|         foreach ($this->collection as $availableBudget) { | ||||
|             $id                          = (int) $availableBudget->id; | ||||
|             $filteredSpentInBudgets      = $this->opsRepository->sumCollectedExpenses($spentInBudgets, $availableBudget->start_date, $availableBudget->end_date, $availableBudget->transactionCurrency, false); | ||||
|             $filteredSpentOutsideBudgets = $this->opsRepository->sumCollectedExpenses($spentOutsideBudgets, $availableBudget->start_date, $availableBudget->end_date, $availableBudget->transactionCurrency, false); | ||||
|             $id                             = (int) $availableBudget->id; | ||||
|             $filteredSpentInBudgets         = $this->opsRepository->sumCollectedExpenses($spentInBudgets, $availableBudget->start_date, $availableBudget->end_date, $availableBudget->transactionCurrency, false); | ||||
|             $filteredSpentOutsideBudgets    = $this->opsRepository->sumCollectedExpenses($spentOutsideBudgets, $availableBudget->start_date, $availableBudget->end_date, $availableBudget->transactionCurrency, false); | ||||
|             $this->spentInBudgets[$id]      = array_values($filteredSpentInBudgets); | ||||
|             $this->spentOutsideBudgets[$id] = array_values($filteredSpentOutsideBudgets); | ||||
| 
 | ||||
| @@ -153,9 +159,8 @@ class AvailableBudgetEnrichment implements EnrichmentInterface | ||||
|                 'pc_spent_outside_budgets' => $pcSpentOutsideBudgets[$id] ?? [], | ||||
|             ]; | ||||
|             $item->meta = $meta; | ||||
| 
 | ||||
|             return $item; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|   | ||||
| @@ -61,11 +61,11 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|         $paidDates        = $this->paidDates; | ||||
|         $payDates         = $this->payDates; | ||||
|         $this->collection = $this->collection->map(function (Bill $item) use ($notes, $objectGroups, $paidDates, $payDates) { | ||||
|             $id       = (int) $item->id; | ||||
|             $currency = $item->transactionCurrency; | ||||
|             $nem      = $this->getNextExpectedMatch($payDates[$id] ?? []); | ||||
|             $id            = (int) $item->id; | ||||
|             $currency      = $item->transactionCurrency; | ||||
|             $nem           = $this->getNextExpectedMatch($payDates[$id] ?? []); | ||||
| 
 | ||||
|             $meta    = [ | ||||
|             $meta          = [ | ||||
|                 'notes'              => null, | ||||
|                 'object_group_id'    => null, | ||||
|                 'object_group_title' => null, | ||||
| @@ -76,7 +76,7 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|                 'nem'                => $nem, | ||||
|                 'nem_diff'           => $this->getNextExpectedMatchDiff($nem, $payDates[$id] ?? []), | ||||
|             ]; | ||||
|             $amounts = [ | ||||
|             $amounts       = [ | ||||
|                 'amount_min'    => Steam::bcround($item->amount_min, $currency->decimal_places), | ||||
|                 'amount_max'    => Steam::bcround($item->amount_max, $currency->decimal_places), | ||||
|                 'average'       => Steam::bcround(bcdiv(bcadd($item->amount_min, $item->amount_max), '2'), $currency->decimal_places), | ||||
| @@ -117,7 +117,7 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|         return $collection; | ||||
|     } | ||||
| 
 | ||||
|     public function enrichSingle(array | Model $model): array | Model | ||||
|     public function enrichSingle(array|Model $model): array|Model | ||||
|     { | ||||
|         Log::debug(__METHOD__); | ||||
|         $collection = new Collection([$model]); | ||||
| @@ -129,9 +129,10 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|     private function collectNotes(): void | ||||
|     { | ||||
|         $notes = Note::query()->whereIn('noteable_id', $this->subscriptionIds) | ||||
|                      ->whereNotNull('notes.text') | ||||
|                      ->where('notes.text', '!=', '') | ||||
|                      ->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray(); | ||||
|             ->whereNotNull('notes.text') | ||||
|             ->where('notes.text', '!=', '') | ||||
|             ->where('noteable_type', Bill::class)->get(['notes.noteable_id', 'notes.text'])->toArray() | ||||
|         ; | ||||
|         foreach ($notes as $note) { | ||||
|             $this->notes[(int) $note['noteable_id']] = (string) $note['text']; | ||||
|         } | ||||
| @@ -160,12 +161,13 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
| 
 | ||||
|     private function collectObjectGroups(): void | ||||
|     { | ||||
|         $set = DB::table('object_groupables') | ||||
|                  ->whereIn('object_groupable_id', $this->subscriptionIds) | ||||
|                  ->where('object_groupable_type', Bill::class) | ||||
|                  ->get(['object_groupable_id', 'object_group_id']); | ||||
|         $set    = DB::table('object_groupables') | ||||
|             ->whereIn('object_groupable_id', $this->subscriptionIds) | ||||
|             ->where('object_groupable_type', Bill::class) | ||||
|             ->get(['object_groupable_id', 'object_group_id']) | ||||
|         ; | ||||
| 
 | ||||
|         $ids = array_unique($set->pluck('object_group_id')->toArray()); | ||||
|         $ids    = array_unique($set->pluck('object_group_id')->toArray()); | ||||
| 
 | ||||
|         foreach ($set as $entry) { | ||||
|             $this->mappedObjects[(int) $entry->object_groupable_id] = (int) $entry->object_group_id; | ||||
| @@ -193,13 +195,13 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|         // 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 Carbon $start */ | ||||
|         $start       = clone $this->start; | ||||
|         $searchStart = clone $start; | ||||
|         $start           = clone $this->start; | ||||
|         $searchStart     = clone $start; | ||||
|         $start->subDay(); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end       = clone $this->end; | ||||
|         $searchEnd = clone $end; | ||||
|         $end             = clone $this->end; | ||||
|         $searchEnd       = clone $end; | ||||
| 
 | ||||
|         // move the search dates to the start of the day.
 | ||||
|         $searchStart->startOfDay(); | ||||
| @@ -208,13 +210,13 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|         Log::debug(sprintf('Search parameters are: start: %s, end: %s', $searchStart->format('Y-m-d H:i:s'), $searchEnd->format('Y-m-d H:i:s'))); | ||||
| 
 | ||||
|         // Get from database when bills were paid.
 | ||||
|         $set = $this->user->transactionJournals() | ||||
|                           ->whereIn('bill_id', $this->subscriptionIds) | ||||
|                           ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|                           ->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id') | ||||
|                           ->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id') | ||||
|                           ->where('transactions.amount', '>', 0) | ||||
|                           ->before($searchEnd)->after($searchStart)->get( | ||||
|         $set             = $this->user->transactionJournals() | ||||
|             ->whereIn('bill_id', $this->subscriptionIds) | ||||
|             ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') | ||||
|             ->leftJoin('transaction_currencies AS currency', 'currency.id', '=', 'transactions.transaction_currency_id') | ||||
|             ->leftJoin('transaction_currencies AS foreign_currency', 'foreign_currency.id', '=', 'transactions.foreign_currency_id') | ||||
|             ->where('transactions.amount', '>', 0) | ||||
|             ->before($searchEnd)->after($searchStart)->get( | ||||
|                 [ | ||||
|                     'transaction_journals.id', | ||||
|                     'transaction_journals.date', | ||||
| @@ -231,43 +233,44 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|                     'transactions.amount', | ||||
|                     'transactions.foreign_amount', | ||||
|                 ] | ||||
|             ); | ||||
|             ) | ||||
|         ; | ||||
|         Log::debug(sprintf('Count %d entries in set', $set->count())); | ||||
| 
 | ||||
|         // for each bill, do a loop.
 | ||||
|         $converter = new ExchangeRateConverter(); | ||||
|         $converter       = new ExchangeRateConverter(); | ||||
| 
 | ||||
|         /** @var Bill $subscription */ | ||||
|         foreach ($this->collection as $subscription) { | ||||
|             // Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
 | ||||
|             Log::debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d'))); | ||||
|             $lastPaidDate = $this->lastPaidDate($subscription, $set, $start); | ||||
|             $lastPaidDate                             = $this->lastPaidDate($subscription, $set, $start); | ||||
|             Log::debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d'))); | ||||
| 
 | ||||
|             // At this point the "next match" is exactly after the last time the bill was paid.
 | ||||
|             $result   = []; | ||||
|             $filtered = $set->filter(function (TransactionJournal $journal) use ($subscription) { | ||||
|             $result                                   = []; | ||||
|             $filtered                                 = $set->filter(function (TransactionJournal $journal) use ($subscription) { | ||||
|                 return (int) $journal->bill_id === (int) $subscription->id; | ||||
|             }); | ||||
|             foreach ($filtered as $entry) { | ||||
|                 $array = [ | ||||
|                     'transaction_group_id'            => (string) $entry->transaction_group_id, | ||||
|                     'transaction_journal_id'          => (string) $entry->id, | ||||
|                     'date'                            => $entry->date->toAtomString(), | ||||
|                     'date_object'                     => $entry->date, | ||||
|                 $array    = [ | ||||
|                     'transaction_group_id'                    => (string) $entry->transaction_group_id, | ||||
|                     'transaction_journal_id'                  => (string) $entry->id, | ||||
|                     'date'                                    => $entry->date->toAtomString(), | ||||
|                     'date_object'                             => $entry->date, | ||||
|                     'subscription_id'                         => (string) $entry->bill_id, | ||||
|                     'currency_id'                     => (string) $entry->transaction_currency_id, | ||||
|                     'currency_code'                   => $entry->transaction_currency_code, | ||||
|                     'currency_symbol'                 => $entry->transaction_currency_symbol, | ||||
|                     'currency_decimal_places'         => $entry->transaction_currency_decimal_places, | ||||
|                     'primary_currency_id'             => (string) $this->primaryCurrency->id, | ||||
|                     'primary_currency_code'           => $this->primaryCurrency->code, | ||||
|                     'primary_currency_symbol'         => $this->primaryCurrency->symbol, | ||||
|                     'primary_currency_decimal_places' => $this->primaryCurrency->decimal_places, | ||||
|                     'amount'                          => Steam::bcround($entry->amount, $entry->transaction_currency_decimal_places), | ||||
|                     'pc_amount'                       => null, | ||||
|                     'foreign_amount'                  => null, | ||||
|                     'pc_foreign_amount'               => null, | ||||
|                     'currency_id'                             => (string) $entry->transaction_currency_id, | ||||
|                     'currency_code'                           => $entry->transaction_currency_code, | ||||
|                     'currency_symbol'                         => $entry->transaction_currency_symbol, | ||||
|                     'currency_decimal_places'                 => $entry->transaction_currency_decimal_places, | ||||
|                     'primary_currency_id'                     => (string) $this->primaryCurrency->id, | ||||
|                     'primary_currency_code'                   => $this->primaryCurrency->code, | ||||
|                     'primary_currency_symbol'                 => $this->primaryCurrency->symbol, | ||||
|                     'primary_currency_decimal_places'         => $this->primaryCurrency->decimal_places, | ||||
|                     'amount'                                  => Steam::bcround($entry->amount, $entry->transaction_currency_decimal_places), | ||||
|                     'pc_amount'                               => null, | ||||
|                     'foreign_amount'                          => null, | ||||
|                     'pc_foreign_amount'                       => null, | ||||
| 
 | ||||
|                 ]; | ||||
|                 if (null !== $entry->foreign_amount && null !== $entry->foreign_currency_code) { | ||||
| @@ -292,7 +295,7 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|                 // convert to primary, but foreign is NOT already primary.
 | ||||
|                 if ($this->convertToPrimary && null !== $entry->foreign_currency_id && (int) $entry->foreign_currency_id !== $this->primaryCurrency->id) { | ||||
|                     // TODO this is very database intensive.
 | ||||
|                     $foreignCurrency = TransactionCurrency::find($entry->foreign_currency_id); | ||||
|                     $foreignCurrency            = TransactionCurrency::find($entry->foreign_currency_id); | ||||
|                     $array['pc_foreign_amount'] = $converter->convert($foreignCurrency, $this->primaryCurrency, $entry->date, $entry->amount); | ||||
|                 } | ||||
|                 $result[] = $array; | ||||
| @@ -325,7 +328,7 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|             return $default; | ||||
|         } | ||||
| 
 | ||||
|         $latest = $filtered->first()->date; | ||||
|         $latest   = $filtered->first()->date; | ||||
| 
 | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($filtered as $journal) { | ||||
| @@ -371,12 +374,12 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
| 
 | ||||
|         /** @var Bill $subscription */ | ||||
|         foreach ($this->collection as $subscription) { | ||||
|             $id                = (int) $subscription->id; | ||||
|             $lastPaidDate      = $this->getLastPaidDate($paidDates[$id] ?? []); | ||||
|             $payDates          = $this->calculator->getPayDates($this->start, $this->end, $subscription->date, $subscription->repeat_freq, $subscription->skip, $lastPaidDate); | ||||
|             $payDatesFormatted = []; | ||||
|             $id                  = (int) $subscription->id; | ||||
|             $lastPaidDate        = $this->getLastPaidDate($paidDates[$id] ?? []); | ||||
|             $payDates            = $this->calculator->getPayDates($this->start, $this->end, $subscription->date, $subscription->repeat_freq, $subscription->skip, $lastPaidDate); | ||||
|             $payDatesFormatted   = []; | ||||
|             foreach ($payDates as $string) { | ||||
|                 $date = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone')); | ||||
|                 $date                = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone')); | ||||
|                 if (!$date instanceof Carbon) { | ||||
|                     $date = today(config('app.timezone')); | ||||
|                 } | ||||
| @@ -406,7 +409,7 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
|             if (!$nemDate instanceof Carbon) { | ||||
|                 $nemDate = today(config('app.timezone')); | ||||
|             } | ||||
|             $nem = $nemDate; | ||||
|             $nem     = $nemDate; | ||||
| 
 | ||||
|             // nullify again when it's outside the current view range.
 | ||||
|             if ( | ||||
| @@ -435,7 +438,7 @@ class SubscriptionEnrichment implements EnrichmentInterface | ||||
| 
 | ||||
|         $current = $payDates[0] ?? null; | ||||
|         if (null !== $current && !$nem->isToday()) { | ||||
|             $temp2 = Carbon::parse($current, config('app.timezone')); | ||||
|             $temp2   = Carbon::parse($current, config('app.timezone')); | ||||
|             if (!$temp2 instanceof Carbon) { | ||||
|                 $temp2 = today(config('app.timezone')); | ||||
|             } | ||||
|   | ||||
| @@ -66,24 +66,24 @@ class AccountTransformer extends AbstractTransformer | ||||
|         } | ||||
| 
 | ||||
|         // get account type:
 | ||||
|         $accountType         = (string) config(sprintf('firefly.shortNamesByFullName.%s', $account->full_account_type)); | ||||
|         $liabilityType       = (string) config(sprintf('firefly.shortLiabilityNameByFullName.%s', $account->full_account_type)); | ||||
|         $liabilityType       = '' === $liabilityType ? null : strtolower($liabilityType); | ||||
|         $liabilityDirection  = $account->meta['liability_direction'] ?? null; | ||||
|         $accountRole         = $this->getAccountRole($account, $accountType); | ||||
|         $hasCurrencySettings = null !== $account->meta['currency']; | ||||
|         $includeNetWorth     = 1 === (int) ($account->meta['include_net_worth'] ?? 0); | ||||
|         $longitude           = $account->meta['location']['longitude'] ?? null; | ||||
|         $latitude            = $account->meta['location']['latitude'] ?? null; | ||||
|         $zoomLevel           = $account->meta['location']['zoom_level'] ?? null; | ||||
|         $order               = $account->order; | ||||
|         $accountType                           = (string) config(sprintf('firefly.shortNamesByFullName.%s', $account->full_account_type)); | ||||
|         $liabilityType                         = (string) config(sprintf('firefly.shortLiabilityNameByFullName.%s', $account->full_account_type)); | ||||
|         $liabilityType                         = '' === $liabilityType ? null : strtolower($liabilityType); | ||||
|         $liabilityDirection                    = $account->meta['liability_direction'] ?? null; | ||||
|         $accountRole                           = $this->getAccountRole($account, $accountType); | ||||
|         $hasCurrencySettings                   = null !== $account->meta['currency']; | ||||
|         $includeNetWorth                       = 1 === (int) ($account->meta['include_net_worth'] ?? 0); | ||||
|         $longitude                             = $account->meta['location']['longitude'] ?? null; | ||||
|         $latitude                              = $account->meta['location']['latitude'] ?? null; | ||||
|         $zoomLevel                             = $account->meta['location']['zoom_level'] ?? null; | ||||
|         $order                                 = $account->order; | ||||
| 
 | ||||
|         // date (for balance etc.)
 | ||||
|         $date = $this->getDate(); | ||||
|         $date                                  = $this->getDate(); | ||||
|         $date->endOfDay(); | ||||
| 
 | ||||
|         // get primary currency as fallback:
 | ||||
|         $currency = $this->primary; // assume primary currency
 | ||||
|         $currency                              = $this->primary; // assume primary currency
 | ||||
|         if ($hasCurrencySettings) { | ||||
|             $currency = $account->meta['currency']; | ||||
|         } | ||||
| @@ -95,8 +95,8 @@ class AccountTransformer extends AbstractTransformer | ||||
| 
 | ||||
|         // get some listed information from the account meta-data:
 | ||||
|         [$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType); | ||||
|         $openingBalanceDate = $this->getOpeningBalance($account, $accountType); | ||||
|         [$interest, $interestPeriod] = $this->getInterest($account, $accountType); | ||||
|         $openingBalanceDate                    = $this->getOpeningBalance($account, $accountType); | ||||
|         [$interest, $interestPeriod]           = $this->getInterest($account, $accountType); | ||||
| 
 | ||||
|         return [ | ||||
|             'id'                              => (string) $account->id, | ||||
| @@ -125,33 +125,33 @@ class AccountTransformer extends AbstractTransformer | ||||
|             'current_balance'                 => $account->meta['balances']['current_balance'], | ||||
|             'pc_current_balance'              => $account->meta['balances']['pc_current_balance'], | ||||
| 
 | ||||
|             'opening_balance'    => $account->meta['balances']['opening_balance'], | ||||
|             'pc_opening_balance' => $account->meta['balances']['pc_opening_balance'], | ||||
|             'opening_balance'                 => $account->meta['balances']['opening_balance'], | ||||
|             'pc_opening_balance'              => $account->meta['balances']['pc_opening_balance'], | ||||
| 
 | ||||
|             'virtual_balance'    => $account->meta['balances']['virtual_balance'], | ||||
|             'pc_virtual_balance' => $account->meta['balances']['pc_virtual_balance'], | ||||
|             'virtual_balance'                 => $account->meta['balances']['virtual_balance'], | ||||
|             'pc_virtual_balance'              => $account->meta['balances']['pc_virtual_balance'], | ||||
| 
 | ||||
|             'debt_amount'    => $account->meta['balances']['debt_amount'], | ||||
|             'pc_debt_amount' => $account->meta['balances']['pc_debt_amount'], | ||||
|             'debt_amount'                     => $account->meta['balances']['debt_amount'], | ||||
|             'pc_debt_amount'                  => $account->meta['balances']['pc_debt_amount'], | ||||
| 
 | ||||
|             'current_balance_date' => $date->toAtomString(), | ||||
|             'notes'                => $account->meta['notes'] ?? null, | ||||
|             'monthly_payment_date' => $monthlyPaymentDate, | ||||
|             'credit_card_type'     => $creditCardType, | ||||
|             'account_number'       => $account->meta['account_number'] ?? null, | ||||
|             'iban'                 => '' === $account->iban ? null : $account->iban, | ||||
|             'bic'                  => $account->meta['BIC'] ?? null, | ||||
|             'opening_balance_date' => $openingBalanceDate, | ||||
|             'liability_type'       => $liabilityType, | ||||
|             'liability_direction'  => $liabilityDirection, | ||||
|             'interest'             => $interest, | ||||
|             'interest_period'      => $interestPeriod, | ||||
|             'include_net_worth'    => $includeNetWorth, | ||||
|             'longitude'            => $longitude, | ||||
|             'latitude'             => $latitude, | ||||
|             'zoom_level'           => $zoomLevel, | ||||
|             'last_activity'        => array_key_exists('last_activity', $account->meta) ? $account->meta['last_activity']->toAtomString() : null, | ||||
|             'links'                => [ | ||||
|             'current_balance_date'            => $date->toAtomString(), | ||||
|             'notes'                           => $account->meta['notes'] ?? null, | ||||
|             'monthly_payment_date'            => $monthlyPaymentDate, | ||||
|             'credit_card_type'                => $creditCardType, | ||||
|             'account_number'                  => $account->meta['account_number'] ?? null, | ||||
|             'iban'                            => '' === $account->iban ? null : $account->iban, | ||||
|             'bic'                             => $account->meta['BIC'] ?? null, | ||||
|             'opening_balance_date'            => $openingBalanceDate, | ||||
|             'liability_type'                  => $liabilityType, | ||||
|             'liability_direction'             => $liabilityDirection, | ||||
|             'interest'                        => $interest, | ||||
|             'interest_period'                 => $interestPeriod, | ||||
|             'include_net_worth'               => $includeNetWorth, | ||||
|             'longitude'                       => $longitude, | ||||
|             'latitude'                        => $latitude, | ||||
|             'zoom_level'                      => $zoomLevel, | ||||
|             'last_activity'                   => array_key_exists('last_activity', $account->meta) ? $account->meta['last_activity']->toAtomString() : null, | ||||
|             'links'                           => [ | ||||
|                 [ | ||||
|                     'rel' => 'self', | ||||
|                     'uri' => sprintf('/accounts/%d', $account->id), | ||||
| @@ -193,7 +193,7 @@ class AccountTransformer extends AbstractTransformer | ||||
|         if (null !== $monthlyPaymentDate) { | ||||
|             // try classic date:
 | ||||
|             if (10 === strlen($monthlyPaymentDate)) { | ||||
|                 $object = Carbon::createFromFormat('!Y-m-d', $monthlyPaymentDate, config('app.timezone')); | ||||
|                 $object             = Carbon::createFromFormat('!Y-m-d', $monthlyPaymentDate, config('app.timezone')); | ||||
|                 if (!$object instanceof Carbon) { | ||||
|                     $object = today(config('app.timezone')); | ||||
|                 } | ||||
| @@ -214,7 +214,7 @@ class AccountTransformer extends AbstractTransformer | ||||
|             $openingBalanceDate = $account->meta['opening_balance_date'] ?? null; | ||||
|         } | ||||
|         if (null !== $openingBalanceDate) { | ||||
|             $object = Carbon::createFromFormat('Y-m-d H:i:s', $openingBalanceDate, config('app.timezone')); | ||||
|             $object             = Carbon::createFromFormat('Y-m-d H:i:s', $openingBalanceDate, config('app.timezone')); | ||||
|             if (!$object instanceof Carbon) { | ||||
|                 $object = today(config('app.timezone')); | ||||
|             } | ||||
|   | ||||
| @@ -58,17 +58,17 @@ class AvailableBudgetTransformer extends AbstractTransformer | ||||
|             $pcAmount = app('steam')->bcround($availableBudget->native_amount, $this->primary->decimal_places); | ||||
|         } | ||||
| 
 | ||||
|         $data = [ | ||||
|             'id'                      => (string) $availableBudget->id, | ||||
|             'created_at'              => $availableBudget->created_at->toAtomString(), | ||||
|             'updated_at'              => $availableBudget->updated_at->toAtomString(), | ||||
|         return [ | ||||
|             'id'                              => (string) $availableBudget->id, | ||||
|             'created_at'                      => $availableBudget->created_at->toAtomString(), | ||||
|             'updated_at'                      => $availableBudget->updated_at->toAtomString(), | ||||
| 
 | ||||
|             // currencies according to 6.3.0
 | ||||
|             'object_has_currency_setting'     => true, | ||||
|             'currency_id'             => (string) $currency->id, | ||||
|             'currency_code'           => $currency->code, | ||||
|             'currency_symbol'         => $currency->symbol, | ||||
|             'currency_decimal_places' => $currency->decimal_places, | ||||
|             'currency_id'                     => (string) $currency->id, | ||||
|             'currency_code'                   => $currency->code, | ||||
|             'currency_symbol'                 => $currency->symbol, | ||||
|             'currency_decimal_places'         => $currency->decimal_places, | ||||
| 
 | ||||
|             'primary_currency_id'             => (string) $this->primary->id, | ||||
|             'primary_currency_code'           => $this->primary->code, | ||||
| @@ -76,23 +76,20 @@ class AvailableBudgetTransformer extends AbstractTransformer | ||||
|             'primary_currency_decimal_places' => $this->primary->decimal_places, | ||||
| 
 | ||||
| 
 | ||||
|             'amount'                   => $amount, | ||||
|             'pc_amount'                => $pcAmount, | ||||
|             'start'                    => $availableBudget->start_date->toAtomString(), | ||||
|             'end'                      => $availableBudget->end_date->endOfDay()->toAtomString(), | ||||
|             'spent_in_budgets'         => $availableBudget->meta['spent_in_budgets'], | ||||
|             'pc_spent_in_budgets'      => $availableBudget->meta['pc_spent_in_budgets'], | ||||
|             'spent_outside_budgets'    => $availableBudget->meta['spent_outside_budgets'], | ||||
|             'pc_spent_outside_budgets' => $availableBudget->meta['pc_spent_outside_budgets'], | ||||
|             'links'                    => [ | ||||
|             'amount'                          => $amount, | ||||
|             'pc_amount'                       => $pcAmount, | ||||
|             'start'                           => $availableBudget->start_date->toAtomString(), | ||||
|             'end'                             => $availableBudget->end_date->endOfDay()->toAtomString(), | ||||
|             'spent_in_budgets'                => $availableBudget->meta['spent_in_budgets'], | ||||
|             'pc_spent_in_budgets'             => $availableBudget->meta['pc_spent_in_budgets'], | ||||
|             'spent_outside_budgets'           => $availableBudget->meta['spent_outside_budgets'], | ||||
|             'pc_spent_outside_budgets'        => $availableBudget->meta['pc_spent_outside_budgets'], | ||||
|             'links'                           => [ | ||||
|                 [ | ||||
|                     'rel' => 'self', | ||||
|                     'uri' => '/available_budgets/' . $availableBudget->id, | ||||
|                     'uri' => '/available_budgets/'.$availableBudget->id, | ||||
|                 ], | ||||
|             ], | ||||
|         ]; | ||||
|         return $data; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|   | ||||
| @@ -52,17 +52,17 @@ class BillTransformer extends AbstractTransformer | ||||
| 
 | ||||
| 
 | ||||
|         return [ | ||||
|             'id'                      => $bill->id, | ||||
|             'created_at'              => $bill->created_at->toAtomString(), | ||||
|             'updated_at'              => $bill->updated_at->toAtomString(), | ||||
|             'name'                    => $bill->name, | ||||
|             'id'                              => $bill->id, | ||||
|             'created_at'                      => $bill->created_at->toAtomString(), | ||||
|             'updated_at'                      => $bill->updated_at->toAtomString(), | ||||
|             'name'                            => $bill->name, | ||||
| 
 | ||||
|             // currencies according to 6.3.0
 | ||||
|             'object_has_currency_setting'     => true, | ||||
|             'currency_id'             => (string) $bill->transaction_currency_id, | ||||
|             'currency_code'           => $currency->code, | ||||
|             'currency_symbol'         => $currency->symbol, | ||||
|             'currency_decimal_places' => $currency->decimal_places, | ||||
|             'currency_id'                     => (string) $bill->transaction_currency_id, | ||||
|             'currency_code'                   => $currency->code, | ||||
|             'currency_symbol'                 => $currency->symbol, | ||||
|             'currency_decimal_places'         => $currency->decimal_places, | ||||
| 
 | ||||
|             'primary_currency_id'             => (string) $this->primary->id, | ||||
|             'primary_currency_code'           => $this->primary->code, | ||||
| @@ -73,34 +73,34 @@ class BillTransformer extends AbstractTransformer | ||||
|             'amount_min'                      => $bill->amounts['amount_min'], | ||||
|             'pc_amount_min'                   => $bill->amounts['pc_amount_min'], | ||||
| 
 | ||||
|             'amount_max'    => $bill->amounts['amount_max'], | ||||
|             'pc_amount_max' => $bill->amounts['pc_amount_max'], | ||||
|             'amount_max'                      => $bill->amounts['amount_max'], | ||||
|             'pc_amount_max'                   => $bill->amounts['pc_amount_max'], | ||||
| 
 | ||||
|             'amount_avg'    => $bill->amounts['average'], | ||||
|             'pc_amount_avg' => $bill->amounts['pc_average'], | ||||
|             'amount_avg'                      => $bill->amounts['average'], | ||||
|             'pc_amount_avg'                   => $bill->amounts['pc_average'], | ||||
| 
 | ||||
|             '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'              => $bill->meta['notes'], | ||||
|             'object_group_id'    => $bill->meta['object_group_id'], | ||||
|             'object_group_order' => $bill->meta['object_group_order'], | ||||
|             'object_group_title' => $bill->meta['object_group_title'], | ||||
|             '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'                           => $bill->meta['notes'], | ||||
|             'object_group_id'                 => $bill->meta['object_group_id'], | ||||
|             'object_group_order'              => $bill->meta['object_group_order'], | ||||
|             'object_group_title'              => $bill->meta['object_group_title'], | ||||
| 
 | ||||
| 
 | ||||
|             'paid_dates'               => $bill->meta['paid_dates'], | ||||
|             'pay_dates'                => $bill->meta['pay_dates'], | ||||
|             'next_expected_match'      => $bill->meta['nem']?->toAtomString(), | ||||
|             'next_expected_match_diff' => $bill->meta['nem_diff'], | ||||
|             'paid_dates'                      => $bill->meta['paid_dates'], | ||||
|             'pay_dates'                       => $bill->meta['pay_dates'], | ||||
|             'next_expected_match'             => $bill->meta['nem']?->toAtomString(), | ||||
|             'next_expected_match_diff'        => $bill->meta['nem_diff'], | ||||
| 
 | ||||
|             'links'                    => [ | ||||
|             'links'                           => [ | ||||
|                 [ | ||||
|                     'rel' => 'self', | ||||
|                     'uri' => '/bills/' . $bill->id, | ||||
|                     'uri' => '/bills/'.$bill->id, | ||||
|                 ], | ||||
|             ], | ||||
|         ]; | ||||
|   | ||||
| @@ -94,7 +94,7 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
|             'links'        => [ | ||||
|                 [ | ||||
|                     'rel' => 'self', | ||||
|                     'uri' => '/transactions/' . $first['transaction_group_id'], | ||||
|                     'uri' => '/transactions/'.$first['transaction_group_id'], | ||||
|                 ], | ||||
|             ], | ||||
|         ]; | ||||
| @@ -117,8 +117,8 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
|     private function transformTransaction(array $transaction): array | ||||
|     { | ||||
|         // amount:
 | ||||
|         $amount        = Steam::positive((string) ($transaction['amount'] ?? '0')); | ||||
|         $foreignAmount = null; | ||||
|         $amount          = Steam::positive((string) ($transaction['amount'] ?? '0')); | ||||
|         $foreignAmount   = null; | ||||
|         if (null !== $transaction['foreign_amount'] && '' !== $transaction['foreign_amount'] && 0 !== bccomp('0', (string) $transaction['foreign_amount'])) { | ||||
|             $foreignAmount = Steam::positive($transaction['foreign_amount']); | ||||
|         } | ||||
| @@ -131,7 +131,7 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
|         if (array_key_exists('pc_amount', $transaction) && null !== $transaction['pc_amount']) { | ||||
|             $transaction['pc_amount'] = Steam::positive($transaction['pc_amount']); | ||||
|         } | ||||
|         $type = $this->stringFromArray($transaction, 'transaction_type_type', TransactionTypeEnum::WITHDRAWAL->value); | ||||
|         $type            = $this->stringFromArray($transaction, 'transaction_type_type', TransactionTypeEnum::WITHDRAWAL->value); | ||||
| 
 | ||||
|         // must be 0 (int) or NULL
 | ||||
|         $recurrenceTotal = $transaction['meta']['recurrence_total'] ?? null; | ||||
| @@ -140,20 +140,20 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
|         $recurrenceCount = null !== $recurrenceCount ? (int) $recurrenceCount : null; | ||||
| 
 | ||||
|         return [ | ||||
|             'user'                        => (string) $transaction['user_id'], | ||||
|             'transaction_journal_id'      => (string) $transaction['transaction_journal_id'], | ||||
|             'type'                        => strtolower((string) $type), | ||||
|             'date'                        => $transaction['date']->toAtomString(), | ||||
|             'order'                       => $transaction['order'], | ||||
|             'user'                            => (string) $transaction['user_id'], | ||||
|             'transaction_journal_id'          => (string) $transaction['transaction_journal_id'], | ||||
|             'type'                            => strtolower((string) $type), | ||||
|             'date'                            => $transaction['date']->toAtomString(), | ||||
|             'order'                           => $transaction['order'], | ||||
| 
 | ||||
|             // currency information, structured for 6.3.0.
 | ||||
|             'object_has_currency_setting' => true, | ||||
|             'object_has_currency_setting'     => true, | ||||
| 
 | ||||
|             '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'], | ||||
|             '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'], | ||||
| 
 | ||||
|             'foreign_currency_id'             => $this->stringFromArray($transaction, 'foreign_currency_id', null), | ||||
|             'foreign_currency_code'           => $transaction['foreign_currency_code'], | ||||
| @@ -171,76 +171,76 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
|             'amount'                          => $amount, | ||||
|             'pc_amount'                       => $transaction['pc_amount'] ?? null, | ||||
| 
 | ||||
|             'foreign_amount'    => $foreignAmount, | ||||
|             'pc_foreign_amount' => null, | ||||
|             'foreign_amount'                  => $foreignAmount, | ||||
|             'pc_foreign_amount'               => null, | ||||
| 
 | ||||
|             'source_balance_after'         => $transaction['source_balance_after'] ?? null, | ||||
|             'pc_source_balance_after'      => null, | ||||
|             'source_balance_after'            => $transaction['source_balance_after'] ?? null, | ||||
|             'pc_source_balance_after'         => null, | ||||
| 
 | ||||
|             // destination balance after
 | ||||
|             'destination_balance_after'    => $transaction['destination_balance_after'] ?? null, | ||||
|             'pc_destination_balance_after' => null, | ||||
|             'destination_balance_after'       => $transaction['destination_balance_after'] ?? null, | ||||
|             'pc_destination_balance_after'    => null, | ||||
| 
 | ||||
|             'source_balance_dirty'      => $transaction['source_balance_dirty'], | ||||
|             'destination_balance_dirty' => $transaction['destination_balance_dirty'], | ||||
|             'source_balance_dirty'            => $transaction['source_balance_dirty'], | ||||
|             'destination_balance_dirty'       => $transaction['destination_balance_dirty'], | ||||
| 
 | ||||
|             'description' => $transaction['description'], | ||||
|             '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'], | ||||
|             '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'], | ||||
|             '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'], | ||||
|             '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'], | ||||
|             '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'], | ||||
|             'subscription_id'   => $this->stringFromArray($transaction, 'bill_id', null), | ||||
|             'subscription_name' => $transaction['bill_name'], | ||||
|             'bill_id'                         => $this->stringFromArray($transaction, 'bill_id', null), | ||||
|             'bill_name'                       => $transaction['bill_name'], | ||||
|             'subscription_id'                 => $this->stringFromArray($transaction, 'bill_id', null), | ||||
|             'subscription_name'               => $transaction['bill_name'], | ||||
| 
 | ||||
|             'reconciled' => $transaction['reconciled'], | ||||
|             'notes'      => $transaction['notes'], | ||||
|             'tags'       => $transaction['tags'], | ||||
|             'reconciled'                      => $transaction['reconciled'], | ||||
|             'notes'                           => $transaction['notes'], | ||||
|             'tags'                            => $transaction['tags'], | ||||
| 
 | ||||
|             'internal_reference' => $transaction['meta']['internal_reference'] ?? null, | ||||
|             'external_id'        => $transaction['meta']['external_id'] ?? null, | ||||
|             'original_source'    => $transaction['meta']['original_source'] ?? null, | ||||
|             'recurrence_id'      => $transaction['meta']['recurrence_id'] ?? null, | ||||
|             'recurrence_total'   => $recurrenceTotal, | ||||
|             'recurrence_count'   => $recurrenceCount, | ||||
|             'external_url'       => $transaction['meta']['external_url'] ?? null, | ||||
|             'import_hash_v2'     => $transaction['meta']['import_hash_v2'] ?? null, | ||||
|             'internal_reference'              => $transaction['meta']['internal_reference'] ?? null, | ||||
|             'external_id'                     => $transaction['meta']['external_id'] ?? null, | ||||
|             'original_source'                 => $transaction['meta']['original_source'] ?? null, | ||||
|             'recurrence_id'                   => $transaction['meta']['recurrence_id'] ?? null, | ||||
|             'recurrence_total'                => $recurrenceTotal, | ||||
|             'recurrence_count'                => $recurrenceCount, | ||||
|             'external_url'                    => $transaction['meta']['external_url'] ?? null, | ||||
|             'import_hash_v2'                  => $transaction['meta']['import_hash_v2'] ?? null, | ||||
| 
 | ||||
|             'sepa_cc'       => $transaction['meta']['sepa_cc'] ?? null, | ||||
|             'sepa_ct_op'    => $transaction['meta']['sepa_ct_op'] ?? null, | ||||
|             'sepa_ct_id'    => $transaction['meta']['sepa_ct_id'] ?? null, | ||||
|             'sepa_db'       => $transaction['meta']['sepa_db'] ?? null, | ||||
|             'sepa_country'  => $transaction['meta']['sepa_country'] ?? null, | ||||
|             'sepa_ep'       => $transaction['meta']['sepa_ep'] ?? null, | ||||
|             'sepa_ci'       => $transaction['meta']['sepa_ci'] ?? null, | ||||
|             'sepa_batch_id' => $transaction['meta']['sepa_batch_id'] ?? null, | ||||
|             'sepa_cc'                         => $transaction['meta']['sepa_cc'] ?? null, | ||||
|             'sepa_ct_op'                      => $transaction['meta']['sepa_ct_op'] ?? null, | ||||
|             'sepa_ct_id'                      => $transaction['meta']['sepa_ct_id'] ?? null, | ||||
|             'sepa_db'                         => $transaction['meta']['sepa_db'] ?? null, | ||||
|             'sepa_country'                    => $transaction['meta']['sepa_country'] ?? null, | ||||
|             'sepa_ep'                         => $transaction['meta']['sepa_ep'] ?? null, | ||||
|             'sepa_ci'                         => $transaction['meta']['sepa_ci'] ?? null, | ||||
|             'sepa_batch_id'                   => $transaction['meta']['sepa_batch_id'] ?? null, | ||||
| 
 | ||||
|             'interest_date'   => array_key_exists('interest_date', $transaction['meta_date']) ? $transaction['meta_date']['interest_date']->toW3CString() : null, | ||||
|             'book_date'       => array_key_exists('book_date', $transaction['meta_date']) ? $transaction['meta_date']['book_date']->toW3CString() : null, | ||||
|             'process_date'    => array_key_exists('process_date', $transaction['meta_date']) ? $transaction['meta_date']['process_date']->toW3CString() : null, | ||||
|             'due_date'        => array_key_exists('due_date', $transaction['meta_date']) ? $transaction['meta_date']['due_date']->toW3CString() : null, | ||||
|             'payment_date'    => array_key_exists('payment_date', $transaction['meta_date']) ? $transaction['meta_date']['payment_date']->toW3CString() : null, | ||||
|             'invoice_date'    => array_key_exists('invoice_date', $transaction['meta_date']) ? $transaction['meta_date']['invoice_date']->toW3CString() : null, | ||||
|             'interest_date'                   => array_key_exists('interest_date', $transaction['meta_date']) ? $transaction['meta_date']['interest_date']->toW3CString() : null, | ||||
|             'book_date'                       => array_key_exists('book_date', $transaction['meta_date']) ? $transaction['meta_date']['book_date']->toW3CString() : null, | ||||
|             'process_date'                    => array_key_exists('process_date', $transaction['meta_date']) ? $transaction['meta_date']['process_date']->toW3CString() : null, | ||||
|             'due_date'                        => array_key_exists('due_date', $transaction['meta_date']) ? $transaction['meta_date']['due_date']->toW3CString() : null, | ||||
|             'payment_date'                    => array_key_exists('payment_date', $transaction['meta_date']) ? $transaction['meta_date']['payment_date']->toW3CString() : null, | ||||
|             'invoice_date'                    => array_key_exists('invoice_date', $transaction['meta_date']) ? $transaction['meta_date']['invoice_date']->toW3CString() : null, | ||||
| 
 | ||||
|             // location data
 | ||||
|             'longitude'       => $transaction['location']['longitude'], | ||||
|             'latitude'        => $transaction['location']['latitude'], | ||||
|             'zoom_level'      => $transaction['location']['zoom_level'], | ||||
|             'has_attachments' => $transaction['attachment_count'] > 0, | ||||
|             'longitude'                       => $transaction['location']['longitude'], | ||||
|             'latitude'                        => $transaction['location']['latitude'], | ||||
|             'zoom_level'                      => $transaction['location']['zoom_level'], | ||||
|             'has_attachments'                 => $transaction['attachment_count'] > 0, | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
| @@ -283,7 +283,7 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
|                 'links'        => [ | ||||
|                     [ | ||||
|                         'rel' => 'self', | ||||
|                         'uri' => '/transactions/' . $group->id, | ||||
|                         'uri' => '/transactions/'.$group->id, | ||||
|                     ], | ||||
|                 ], | ||||
|             ]; | ||||
| @@ -338,10 +338,10 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
|             $foreignAmount = Steam::bcround($foreignAmount, $foreignCurrency['decimal_places'] ?? 0); | ||||
|         } | ||||
| 
 | ||||
|         $longitude = null; | ||||
|         $latitude  = null; | ||||
|         $zoomLevel = null; | ||||
|         $location  = $this->getLocation($journal); | ||||
|         $longitude       = null; | ||||
|         $latitude        = null; | ||||
|         $zoomLevel       = null; | ||||
|         $location        = $this->getLocation($journal); | ||||
|         if ($location instanceof Location) { | ||||
|             $longitude = $location->longitude; | ||||
|             $latitude  = $location->latitude; | ||||
| @@ -349,77 +349,77 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
|         } | ||||
| 
 | ||||
|         return [ | ||||
|             'user'                   => $journal->user_id, | ||||
|             'transaction_journal_id' => (string) $journal->id, | ||||
|             'type'                   => strtolower((string) $type), | ||||
|             'date'                   => $journal->date->toAtomString(), | ||||
|             'order'                  => $journal->order, | ||||
|             'user'                            => $journal->user_id, | ||||
|             'transaction_journal_id'          => (string) $journal->id, | ||||
|             'type'                            => strtolower((string) $type), | ||||
|             'date'                            => $journal->date->toAtomString(), | ||||
|             'order'                           => $journal->order, | ||||
| 
 | ||||
|             'currency_id'             => (string) $currency->id, | ||||
|             'currency_code'           => $currency->code, | ||||
|             'currency_symbol'         => $currency->symbol, | ||||
|             'currency_decimal_places' => $currency->decimal_places, | ||||
|             'currency_id'                     => (string) $currency->id, | ||||
|             'currency_code'                   => $currency->code, | ||||
|             'currency_symbol'                 => $currency->symbol, | ||||
|             'currency_decimal_places'         => $currency->decimal_places, | ||||
| 
 | ||||
|             'foreign_currency_id'             => (string) $foreignCurrency['id'], | ||||
|             'foreign_currency_code'           => $foreignCurrency['code'], | ||||
|             'foreign_currency_symbol'         => $foreignCurrency['symbol'], | ||||
|             'foreign_currency_decimal_places' => $foreignCurrency['decimal_places'], | ||||
| 
 | ||||
|             'amount'         => Steam::bcround($amount, $currency->decimal_places), | ||||
|             'foreign_amount' => $foreignAmount, | ||||
|             'amount'                          => Steam::bcround($amount, $currency->decimal_places), | ||||
|             'foreign_amount'                  => $foreignAmount, | ||||
| 
 | ||||
|             'description' => $journal->description, | ||||
|             'description'                     => $journal->description, | ||||
| 
 | ||||
|             'source_id'   => (string) $source->account_id, | ||||
|             'source_name' => $source->account->name, | ||||
|             'source_iban' => $source->account->iban, | ||||
|             'source_type' => $source->account->accountType->type, | ||||
|             'source_id'                       => (string) $source->account_id, | ||||
|             'source_name'                     => $source->account->name, | ||||
|             'source_iban'                     => $source->account->iban, | ||||
|             'source_type'                     => $source->account->accountType->type, | ||||
| 
 | ||||
|             'destination_id'   => (string) $destination->account_id, | ||||
|             'destination_name' => $destination->account->name, | ||||
|             'destination_iban' => $destination->account->iban, | ||||
|             'destination_type' => $destination->account->accountType->type, | ||||
|             'destination_id'                  => (string) $destination->account_id, | ||||
|             'destination_name'                => $destination->account->name, | ||||
|             'destination_iban'                => $destination->account->iban, | ||||
|             'destination_type'                => $destination->account->accountType->type, | ||||
| 
 | ||||
|             'budget_id'   => (string) $budget['id'], | ||||
|             'budget_name' => $budget['name'], | ||||
|             'budget_id'                       => (string) $budget['id'], | ||||
|             'budget_name'                     => $budget['name'], | ||||
| 
 | ||||
|             'category_id'   => (string) $category['id'], | ||||
|             'category_name' => $category['name'], | ||||
|             'category_id'                     => (string) $category['id'], | ||||
|             'category_name'                   => $category['name'], | ||||
| 
 | ||||
|             'bill_id'   => (string) $bill['id'], | ||||
|             'bill_name' => $bill['name'], | ||||
|             'bill_id'                         => (string) $bill['id'], | ||||
|             'bill_name'                       => $bill['name'], | ||||
| 
 | ||||
|             'reconciled' => $source->reconciled, | ||||
|             'notes'      => $this->groupRepos->getNoteText($journal->id), | ||||
|             'tags'       => $this->groupRepos->getTags($journal->id), | ||||
|             'reconciled'                      => $source->reconciled, | ||||
|             'notes'                           => $this->groupRepos->getNoteText($journal->id), | ||||
|             'tags'                            => $this->groupRepos->getTags($journal->id), | ||||
| 
 | ||||
|             'internal_reference' => $metaFieldData['internal_reference'], | ||||
|             'external_id'        => $metaFieldData['external_id'], | ||||
|             'original_source'    => $metaFieldData['original_source'], | ||||
|             'recurrence_id'      => $metaFieldData['recurrence_id'], | ||||
|             'bunq_payment_id'    => $metaFieldData['bunq_payment_id'], | ||||
|             'import_hash_v2'     => $metaFieldData['import_hash_v2'], | ||||
|             'internal_reference'              => $metaFieldData['internal_reference'], | ||||
|             'external_id'                     => $metaFieldData['external_id'], | ||||
|             'original_source'                 => $metaFieldData['original_source'], | ||||
|             'recurrence_id'                   => $metaFieldData['recurrence_id'], | ||||
|             'bunq_payment_id'                 => $metaFieldData['bunq_payment_id'], | ||||
|             'import_hash_v2'                  => $metaFieldData['import_hash_v2'], | ||||
| 
 | ||||
|             'sepa_cc'       => $metaFieldData['sepa_cc'], | ||||
|             'sepa_ct_op'    => $metaFieldData['sepa_ct_op'], | ||||
|             'sepa_ct_id'    => $metaFieldData['sepa_ct_id'], | ||||
|             'sepa_db'       => $metaFieldData['sepa_db'], | ||||
|             'sepa_country'  => $metaFieldData['sepa_country'], | ||||
|             'sepa_ep'       => $metaFieldData['sepa_ep'], | ||||
|             'sepa_ci'       => $metaFieldData['sepa_ci'], | ||||
|             'sepa_batch_id' => $metaFieldData['sepa_batch_id'], | ||||
|             'sepa_cc'                         => $metaFieldData['sepa_cc'], | ||||
|             'sepa_ct_op'                      => $metaFieldData['sepa_ct_op'], | ||||
|             'sepa_ct_id'                      => $metaFieldData['sepa_ct_id'], | ||||
|             'sepa_db'                         => $metaFieldData['sepa_db'], | ||||
|             'sepa_country'                    => $metaFieldData['sepa_country'], | ||||
|             'sepa_ep'                         => $metaFieldData['sepa_ep'], | ||||
|             'sepa_ci'                         => $metaFieldData['sepa_ci'], | ||||
|             'sepa_batch_id'                   => $metaFieldData['sepa_batch_id'], | ||||
| 
 | ||||
|             'interest_date' => $metaDates['interest_date'], | ||||
|             'book_date'     => $metaDates['book_date'], | ||||
|             'process_date'  => $metaDates['process_date'], | ||||
|             'due_date'      => $metaDates['due_date'], | ||||
|             'payment_date'  => $metaDates['payment_date'], | ||||
|             'invoice_date'  => $metaDates['invoice_date'], | ||||
|             'interest_date'                   => $metaDates['interest_date'], | ||||
|             'book_date'                       => $metaDates['book_date'], | ||||
|             'process_date'                    => $metaDates['process_date'], | ||||
|             'due_date'                        => $metaDates['due_date'], | ||||
|             'payment_date'                    => $metaDates['payment_date'], | ||||
|             'invoice_date'                    => $metaDates['invoice_date'], | ||||
| 
 | ||||
|             // location data
 | ||||
|             'longitude'     => $longitude, | ||||
|             'latitude'      => $latitude, | ||||
|             'zoom_level'    => $zoomLevel, | ||||
|             'longitude'                       => $longitude, | ||||
|             'latitude'                        => $latitude, | ||||
|             'zoom_level'                      => $zoomLevel, | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
| @@ -494,7 +494,7 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
| 
 | ||||
|     private function getForeignCurrency(?TransactionCurrency $currency): array | ||||
|     { | ||||
|         $array = [ | ||||
|         $array                   = [ | ||||
|             'id'             => null, | ||||
|             'code'           => null, | ||||
|             'symbol'         => null, | ||||
| @@ -513,7 +513,7 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
| 
 | ||||
|     private function getBudget(?Budget $budget): array | ||||
|     { | ||||
|         $array = [ | ||||
|         $array         = [ | ||||
|             'id'   => null, | ||||
|             'name' => null, | ||||
|         ]; | ||||
| @@ -528,7 +528,7 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
| 
 | ||||
|     private function getCategory(?Category $category): array | ||||
|     { | ||||
|         $array = [ | ||||
|         $array         = [ | ||||
|             'id'   => null, | ||||
|             'name' => null, | ||||
|         ]; | ||||
| @@ -543,7 +543,7 @@ class TransactionGroupTransformer extends AbstractTransformer | ||||
| 
 | ||||
|     private function getBill(?Bill $bill): array | ||||
|     { | ||||
|         $array = [ | ||||
|         $array         = [ | ||||
|             'id'   => null, | ||||
|             'name' => null, | ||||
|         ]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user