From 05f1819f7dcde926daa62921a5d2bdc05b2b498b Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 29 Dec 2024 14:24:20 +0100 Subject: [PATCH] Fix API convert to native. Still needs refactoring. --- .../Insight/Expense/PeriodController.php | 66 +++++++----- .../Insight/Expense/TagController.php | 79 ++++++++------ .../Insight/Income/AccountController.php | 1 + .../Insight/Income/PeriodController.php | 56 +++++----- .../Insight/Income/TagController.php | 41 +++---- .../Insight/Transfer/PeriodController.php | 39 +++---- .../Insight/Transfer/TagController.php | 72 +++++++------ .../Account/OperationsRepository.php | 48 +++++---- .../Budget/NoBudgetRepository.php | 100 ++++++++---------- .../Budget/NoBudgetRepositoryInterface.php | 5 - 10 files changed, 262 insertions(+), 245 deletions(-) diff --git a/app/Api/V1/Controllers/Insight/Expense/PeriodController.php b/app/Api/V1/Controllers/Insight/Expense/PeriodController.php index 9f091b8501..28a4fd25e7 100644 --- a/app/Api/V1/Controllers/Insight/Expense/PeriodController.php +++ b/app/Api/V1/Controllers/Insight/Expense/PeriodController.php @@ -28,7 +28,9 @@ use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\Insight\GenericRequest; use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Helpers\Collector\GroupCollectorInterface; +use FireflyIII\Support\Facades\Amount; use Illuminate\Http\JsonResponse; +use Illuminate\Support\Facades\Log; /** * Class PeriodController @@ -41,39 +43,49 @@ class PeriodController extends Controller */ public function total(GenericRequest $request): JsonResponse { - $accounts = $request->getAssetAccounts(); - $start = $request->getStart(); - $end = $request->getEnd(); - $response = []; + $accounts = $request->getAssetAccounts(); + $start = $request->getStart(); + $end = $request->getEnd(); + $response = []; + $convertToNative = Amount::convertToNative(); + $default = Amount::getDefaultCurrency(); // collect all expenses in this period (regardless of type) - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts); $genericSet = $collector->getExtractedJournals(); foreach ($genericSet as $journal) { - $currencyId = (int) $journal['currency_id']; - $foreignCurrencyId = (int) $journal['foreign_currency_id']; + // same code as many other sumExpense methods. I think this needs some kind of generic method. + $amount = '0'; + $currencyId = (int) $journal['currency_id']; + $currencyCode = $journal['currency_code']; + if ($convertToNative) { + $amount = Amount::getAmountFromJournal($journal); + if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) { + $currencyId = $default->id; + $currencyCode = $default->code; + } + if ($default->id !== (int) $journal['currency_id'] && $default->id === (int) $journal['foreign_currency_id']) { + $currencyId = $journal['foreign_currency_id']; + $currencyCode = $journal['foreign_currency_code']; + } + Log::debug(sprintf('[a] Add amount %s %s', $currencyCode, $amount)); + } + if (!$convertToNative) { + // ignore the amount in foreign currency. + Log::debug(sprintf('[b] Add amount %s %s', $currencyCode, $journal['amount'])); + $amount = $journal['amount']; + } - if (0 !== $currencyId) { - $response[$currencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $currencyId, - 'currency_code' => $journal['currency_code'], - ]; - $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']); - $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float - } - if (0 !== $foreignCurrencyId) { - $response[$foreignCurrencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $foreignCurrencyId, - 'currency_code' => $journal['foreign_currency_code'], - ]; - $response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']); - $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // intentional float - } + + $response[$currencyId] ??= [ + 'difference' => '0', + 'difference_float' => 0, + 'currency_id' => (string) $currencyId, + 'currency_code' => $currencyCode, + ]; + $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $amount); + $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // intentional float } return response()->json(array_values($response)); diff --git a/app/Api/V1/Controllers/Insight/Expense/TagController.php b/app/Api/V1/Controllers/Insight/Expense/TagController.php index b76dcc776a..b39105ada0 100644 --- a/app/Api/V1/Controllers/Insight/Expense/TagController.php +++ b/app/Api/V1/Controllers/Insight/Expense/TagController.php @@ -29,7 +29,9 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest; use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface; +use FireflyIII\Support\Facades\Amount; use Illuminate\Http\JsonResponse; +use Illuminate\Support\Facades\Log; /** * Class TagController @@ -62,42 +64,51 @@ class TagController extends Controller */ public function noTag(GenericRequest $request): JsonResponse { - $accounts = $request->getAssetAccounts(); - $start = $request->getStart(); - $end = $request->getEnd(); - $response = []; + $accounts = $request->getAssetAccounts(); + $start = $request->getStart(); + $end = $request->getEnd(); + $response = []; + $convertToNative = Amount::convertToNative(); + $default = Amount::getDefaultCurrency(); // collect all expenses in this period (regardless of type) by the given bills and accounts. - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts); $collector->withoutTags(); $genericSet = $collector->getExtractedJournals(); foreach ($genericSet as $journal) { - $currencyId = (int) $journal['currency_id']; - $foreignCurrencyId = (int) $journal['foreign_currency_id']; + // same code as many other sumExpense methods. I think this needs some kind of generic method. + $amount = '0'; + $currencyId = (int) $journal['currency_id']; + $currencyCode = $journal['currency_code']; + if ($convertToNative) { + $amount = Amount::getAmountFromJournal($journal); + if ($default->id !== (int) $journal['currency_id'] && $default->id !== (int) $journal['foreign_currency_id']) { + $currencyId = $default->id; + $currencyCode = $default->code; + } + if ($default->id !== (int) $journal['currency_id'] && $default->id === (int) $journal['foreign_currency_id']) { + $currencyId = $journal['foreign_currency_id']; + $currencyCode = $journal['foreign_currency_code']; + } + Log::debug(sprintf('[a] Add amount %s %s', $currencyCode, $amount)); + } + if (!$convertToNative) { + // ignore the amount in foreign currency. + Log::debug(sprintf('[b] Add amount %s %s', $currencyCode, $journal['amount'])); + $amount = $journal['amount']; + } - if (0 !== $currencyId) { - $response[$currencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $currencyId, - 'currency_code' => $journal['currency_code'], - ]; - $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $journal['amount']); - $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose. - } - if (0 !== $foreignCurrencyId) { - $response[$foreignCurrencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $foreignCurrencyId, - 'currency_code' => $journal['foreign_currency_code'], - ]; - $response[$foreignCurrencyId]['difference'] = bcadd($response[$foreignCurrencyId]['difference'], $journal['foreign_amount']); - $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // float but on purpose. - } + $response[$currencyId] ??= [ + 'difference' => '0', + 'difference_float' => 0, + 'currency_id' => (string) $currencyId, + 'currency_code' => $currencyCode, + ]; + $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], $amount); + $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose. } return response()->json(array_values($response)); @@ -111,11 +122,11 @@ class TagController extends Controller */ public function tag(GenericRequest $request): JsonResponse { - $accounts = $request->getAssetAccounts(); - $tags = $request->getTags(); - $start = $request->getStart(); - $end = $request->getEnd(); - $response = []; + $accounts = $request->getAssetAccounts(); + $tags = $request->getTags(); + $start = $request->getStart(); + $end = $request->getEnd(); + $response = []; // get all tags: if (0 === $tags->count()) { @@ -123,7 +134,7 @@ class TagController extends Controller } // collect all expenses in this period (regardless of type) by the given bills and accounts. - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value])->setRange($start, $end)->setSourceAccounts($accounts); $collector->setTags($tags); $genericSet = $collector->getExtractedJournals(); @@ -141,7 +152,7 @@ class TagController extends Controller // on currency ID if (0 !== $currencyId) { - $response[$key] ??= [ + $response[$key] ??= [ 'id' => (string) $tagId, 'name' => $tag['name'], 'difference' => '0', diff --git a/app/Api/V1/Controllers/Insight/Income/AccountController.php b/app/Api/V1/Controllers/Insight/Income/AccountController.php index 5c7b28231e..87cff7be5c 100644 --- a/app/Api/V1/Controllers/Insight/Income/AccountController.php +++ b/app/Api/V1/Controllers/Insight/Income/AccountController.php @@ -73,6 +73,7 @@ class AccountController extends Controller $start = $request->getStart(); $end = $request->getEnd(); $assetAccounts = $request->getAssetAccounts(); + $income = $this->opsRepository->sumIncomeByDestination($start, $end, $assetAccounts); $result = []; diff --git a/app/Api/V1/Controllers/Insight/Income/PeriodController.php b/app/Api/V1/Controllers/Insight/Income/PeriodController.php index 970ffa2e52..360abf4664 100644 --- a/app/Api/V1/Controllers/Insight/Income/PeriodController.php +++ b/app/Api/V1/Controllers/Insight/Income/PeriodController.php @@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\Insight\GenericRequest; use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Helpers\Collector\GroupCollectorInterface; +use FireflyIII\Support\Facades\Amount; use Illuminate\Http\JsonResponse; /** @@ -41,42 +42,41 @@ class PeriodController extends Controller */ public function total(GenericRequest $request): JsonResponse { - $accounts = $request->getAssetAccounts(); - $start = $request->getStart(); - $end = $request->getEnd(); - $response = []; + $accounts = $request->getAssetAccounts(); + $start = $request->getStart(); + $end = $request->getEnd(); + $response = []; + $convertToNative = Amount::convertToNative(); + $default = Amount::getDefaultCurrency(); // collect all expenses in this period (regardless of type) - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTypes([TransactionTypeEnum::DEPOSIT->value])->setRange($start, $end)->setDestinationAccounts($accounts); $genericSet = $collector->getExtractedJournals(); foreach ($genericSet as $journal) { - $currencyId = (int) $journal['currency_id']; - $foreignCurrencyId = (int) $journal['foreign_currency_id']; + // currency + $currencyId = $journal['currency_id']; + $currencyCode = $journal['currency_code']; + $field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount'; - if (0 !== $currencyId) { - $response[$currencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $currencyId, - 'currency_code' => $journal['currency_code'], - ]; - $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount'])); - $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose. + // perhaps use default currency instead? + if ($convertToNative && $journal['currency_id'] !== $default->id) { + $currencyId = $default->id; + $currencyCode = $default->code; } - if (0 !== $foreignCurrencyId) { - $response[$foreignCurrencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $foreignCurrencyId, - 'currency_code' => $journal['foreign_currency_code'], - ]; - $response[$foreignCurrencyId]['difference'] = bcadd( - $response[$foreignCurrencyId]['difference'], - app('steam')->positive($journal['foreign_amount']) - ); - $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; // float but on purpose. + // use foreign amount when the foreign currency IS the default currency. + if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) { + $field = 'foreign_amount'; } + + $response[$currencyId] ??= [ + 'difference' => '0', + 'difference_float' => 0, + 'currency_id' => (string) $currencyId, + 'currency_code' => $currencyCode, + ]; + $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); + $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; // float but on purpose. } return response()->json(array_values($response)); diff --git a/app/Api/V1/Controllers/Insight/Income/TagController.php b/app/Api/V1/Controllers/Insight/Income/TagController.php index e0eece3e90..3a3a5f67b6 100644 --- a/app/Api/V1/Controllers/Insight/Income/TagController.php +++ b/app/Api/V1/Controllers/Insight/Income/TagController.php @@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest; use FireflyIII\Enums\TransactionTypeEnum; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface; +use FireflyIII\Support\Facades\Amount; use Illuminate\Http\JsonResponse; /** @@ -67,6 +68,8 @@ class TagController extends Controller $start = $request->getStart(); $end = $request->getEnd(); $response = []; + $convertToNative = Amount::convertToNative(); + $default = Amount::getDefaultCurrency(); // collect all expenses in this period (regardless of type) by the given bills and accounts. $collector = app(GroupCollectorInterface::class); @@ -76,32 +79,30 @@ class TagController extends Controller $genericSet = $collector->getExtractedJournals(); foreach ($genericSet as $journal) { - $currencyId = (int) $journal['currency_id']; - $foreignCurrencyId = (int) $journal['foreign_currency_id']; + // currency + $currencyId = $journal['currency_id']; + $currencyCode = $journal['currency_code']; + $field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount'; - if (0 !== $currencyId) { - $response[$currencyId] ??= [ + // perhaps use default currency instead? + if ($convertToNative && $journal['currency_id'] !== $default->id) { + $currencyId = $default->id; + $currencyCode = $default->code; + } + // use foreign amount when the foreign currency IS the default currency. + if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) { + $field = 'foreign_amount'; + } + + $response[$currencyId] ??= [ 'difference' => '0', 'difference_float' => 0, 'currency_id' => (string) $currencyId, - 'currency_code' => $journal['currency_code'], + 'currency_code' => $currencyCode, ]; - $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount'])); + $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; - } - if (0 !== $foreignCurrencyId) { - $response[$foreignCurrencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $foreignCurrencyId, - 'currency_code' => $journal['foreign_currency_code'], - ]; - $response[$foreignCurrencyId]['difference'] = bcadd( - $response[$foreignCurrencyId]['difference'], - app('steam')->positive($journal['foreign_amount']) - ); - $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; - } + } return response()->json(array_values($response)); diff --git a/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php b/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php index f66f9776ee..5d0b5a22d5 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php @@ -28,6 +28,7 @@ use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\Insight\GenericRequest; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\TransactionType; +use FireflyIII\Support\Facades\Amount; use Illuminate\Http\JsonResponse; /** @@ -45,38 +46,38 @@ class PeriodController extends Controller $start = $request->getStart(); $end = $request->getEnd(); $response = []; + $convertToNative = Amount::convertToNative(); + $default = Amount::getDefaultCurrency(); // collect all expenses in this period (regardless of type) $collector = app(GroupCollectorInterface::class); $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts); $genericSet = $collector->getExtractedJournals(); foreach ($genericSet as $journal) { - $currencyId = (int) $journal['currency_id']; - $foreignCurrencyId = (int) $journal['foreign_currency_id']; + // currency + $currencyId = $journal['currency_id']; + $currencyCode = $journal['currency_code']; + $field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount'; + + // perhaps use default currency instead? + if ($convertToNative && $journal['currency_id'] !== $default->id) { + $currencyId = $default->id; + $currencyCode = $default->code; + } + // use foreign amount when the foreign currency IS the default currency. + if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) { + $field = 'foreign_amount'; + } - if (0 !== $currencyId) { $response[$currencyId] ??= [ 'difference' => '0', 'difference_float' => 0, 'currency_id' => (string) $currencyId, - 'currency_code' => $journal['currency_code'], + 'currency_code' => $currencyCode, ]; - $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount'])); + $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; - } - if (0 !== $foreignCurrencyId) { - $response[$foreignCurrencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $foreignCurrencyId, - 'currency_code' => $journal['foreign_currency_code'], - ]; - $response[$foreignCurrencyId]['difference'] = bcadd( - $response[$foreignCurrencyId]['difference'], - app('steam')->positive($journal['foreign_amount']) - ); - $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; - } + } return response()->json(array_values($response)); diff --git a/app/Api/V1/Controllers/Insight/Transfer/TagController.php b/app/Api/V1/Controllers/Insight/Transfer/TagController.php index 6fa1fbdedd..001a4ca5f1 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/TagController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/TagController.php @@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\Insight\GenericRequest; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Tag\TagRepositoryInterface; +use FireflyIII\Support\Facades\Amount; use Illuminate\Http\JsonResponse; /** @@ -61,45 +62,46 @@ class TagController extends Controller */ public function noTag(GenericRequest $request): JsonResponse { - $accounts = $request->getAssetAccounts(); - $start = $request->getStart(); - $end = $request->getEnd(); - $response = []; + $accounts = $request->getAssetAccounts(); + $start = $request->getStart(); + $end = $request->getEnd(); + $response = []; + $convertToNative = Amount::convertToNative(); + $default = Amount::getDefaultCurrency(); + // collect all expenses in this period (regardless of type) by the given bills and accounts. - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts); $collector->withoutTags(); $genericSet = $collector->getExtractedJournals(); foreach ($genericSet as $journal) { - $currencyId = (int) $journal['currency_id']; - $foreignCurrencyId = (int) $journal['foreign_currency_id']; + // currency + $currencyId = $journal['currency_id']; + $currencyCode = $journal['currency_code']; + $field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount'; - if (0 !== $currencyId) { - $response[$currencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $currencyId, - 'currency_code' => $journal['currency_code'], - ]; - $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal['amount'])); - $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; + // perhaps use default currency instead? + if ($convertToNative && $journal['currency_id'] !== $default->id) { + $currencyId = $default->id; + $currencyCode = $default->code; } - if (0 !== $foreignCurrencyId) { - $response[$foreignCurrencyId] ??= [ - 'difference' => '0', - 'difference_float' => 0, - 'currency_id' => (string) $foreignCurrencyId, - 'currency_code' => $journal['foreign_currency_code'], - ]; - $response[$foreignCurrencyId]['difference'] = bcadd( - $response[$foreignCurrencyId]['difference'], - app('steam')->positive($journal['foreign_amount']) - ); - $response[$foreignCurrencyId]['difference_float'] = (float) $response[$foreignCurrencyId]['difference']; + // use foreign amount when the foreign currency IS the default currency. + if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) { + $field = 'foreign_amount'; } + + $response[$currencyId] ??= [ + 'difference' => '0', + 'difference_float' => 0, + 'currency_id' => (string) $currencyId, + 'currency_code' => $currencyCode, + ]; + $response[$currencyId]['difference'] = bcadd($response[$currencyId]['difference'], app('steam')->positive($journal[$field])); + $response[$currencyId]['difference_float'] = (float) $response[$currencyId]['difference']; + } return response()->json(array_values($response)); @@ -113,11 +115,11 @@ class TagController extends Controller */ public function tag(GenericRequest $request): JsonResponse { - $accounts = $request->getAssetAccounts(); - $tags = $request->getTags(); - $start = $request->getStart(); - $end = $request->getEnd(); - $response = []; + $accounts = $request->getAssetAccounts(); + $tags = $request->getTags(); + $start = $request->getStart(); + $end = $request->getEnd(); + $response = []; // get all tags: if (0 === $tags->count()) { @@ -125,7 +127,7 @@ class TagController extends Controller } // collect all expenses in this period (regardless of type) by the given bills and accounts. - $collector = app(GroupCollectorInterface::class); + $collector = app(GroupCollectorInterface::class); $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts); $collector->setTags($tags); $genericSet = $collector->getExtractedJournals(); @@ -143,7 +145,7 @@ class TagController extends Controller // on currency ID if (0 !== $currencyId) { - $response[$key] ??= [ + $response[$key] ??= [ 'id' => (string) $tagId, 'name' => $tag['name'], 'difference' => '0', diff --git a/app/Repositories/Account/OperationsRepository.php b/app/Repositories/Account/OperationsRepository.php index 3656222061..b214e45d76 100644 --- a/app/Repositories/Account/OperationsRepository.php +++ b/app/Repositories/Account/OperationsRepository.php @@ -220,32 +220,40 @@ class OperationsRepository implements OperationsRepositoryInterface private function groupByCurrency(array $journals, string $direction): array { $array = []; + $convertToNative = Amount::convertToNative($this->user); + $default = Amount::getDefaultCurrencyByUserGroup($this->user->userGroup); foreach ($journals as $journal) { - $currencyId = (int) $journal['currency_id']; + // currency + $currencyId = $journal['currency_id']; + $currencyName = $journal['currency_name']; + $currencySymbol = $journal['currency_symbol']; + $currencyCode = $journal['currency_code']; + $currencyDecimalPlaces = $journal['currency_decimal_places']; + $field = $convertToNative && $currencyId !== $default->id ? 'native_amount' : 'amount'; + + // perhaps use default currency instead? + if ($convertToNative && $journal['currency_id'] !== $default->id) { + $currencyId = $default->id; + $currencyName = $default->name; + $currencySymbol = $default->symbol; + $currencyCode = $default->code; + $currencyDecimalPlaces = $default->decimal_places; + } + // use foreign amount when the foreign currency IS the default currency. + if ($convertToNative && $journal['currency_id'] !== $default->id && $default->id === $journal['foreign_currency_id']) { + $field = 'foreign_amount'; + } + $array[$currencyId] ??= [ 'sum' => '0', 'currency_id' => $currencyId, - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], + 'currency_name' => $currencyName, + 'currency_symbol' => $currencySymbol, + 'currency_code' => $currencyCode, + 'currency_decimal_places' => $currencyDecimalPlaces, ]; - $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->{$direction}($journal['amount'])); // @phpstan-ignore-line - - // also do foreign amount: - $foreignId = (int) $journal['foreign_currency_id']; - if (0 !== $foreignId) { - $array[$foreignId] ??= [ - 'sum' => '0', - 'currency_id' => $foreignId, - 'currency_name' => $journal['foreign_currency_name'], - 'currency_symbol' => $journal['foreign_currency_symbol'], - 'currency_code' => $journal['foreign_currency_code'], - 'currency_decimal_places' => $journal['foreign_currency_decimal_places'], - ]; - $array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->{$direction}($journal['foreign_amount'])); // @phpstan-ignore-line - } + $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->{$direction}($journal[$field])); // @phpstan-ignore-line } return $array; diff --git a/app/Repositories/Budget/NoBudgetRepository.php b/app/Repositories/Budget/NoBudgetRepository.php index ebe62ac894..7630d50881 100644 --- a/app/Repositories/Budget/NoBudgetRepository.php +++ b/app/Repositories/Budget/NoBudgetRepository.php @@ -28,9 +28,11 @@ use Carbon\Carbon; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionType; +use FireflyIII\Support\Facades\Amount; use FireflyIII\User; use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Log; /** * Class NoBudgetRepository @@ -79,54 +81,6 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface return $data; } - /** - * @deprecated - */ - public function spentInPeriodWoBudgetMc(Collection $accounts, Carbon $start, Carbon $end): array - { - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - - $collector->setUser($this->user); - $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withoutBudget(); - - if ($accounts->count() > 0) { - $collector->setAccounts($accounts); - } - $journals = $collector->getExtractedJournals(); - $return = []; - $total = []; - $currencies = []; - - /** @var array $journal */ - foreach ($journals as $journal) { - $code = $journal['currency_code']; - if (!array_key_exists($code, $currencies)) { - $currencies[$code] = [ - 'id' => $journal['currency_id'], - 'name' => $journal['currency_name'], - 'symbol' => $journal['currency_symbol'], - 'decimal_places' => $journal['currency_decimal_places'], - ]; - } - $total[$code] = array_key_exists($code, $total) ? bcadd($total[$code], $journal['amount']) : $journal['amount']; - } - foreach ($total as $code => $spent) { - /** @var TransactionCurrency $currency */ - $currency = $currencies[$code]; - $return[] = [ - 'currency_id' => (string) $currency['id'], - 'currency_code' => $code, - 'currency_name' => $currency['name'], - 'currency_symbol' => $currency['symbol'], - 'currency_decimal_places' => $currency['decimal_places'], - 'amount' => app('steam')->bcround($spent, $currency['decimal_places']), - ]; - } - - return $return; - } - public function setUser(null|Authenticatable|User $user): void { if ($user instanceof User) { @@ -134,10 +88,6 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface } } - /** - * TODO this method does not include multi currency. It just counts. - * TODO this probably also applies to the other "sumExpenses" methods. - */ public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array { /** @var GroupCollectorInterface $collector */ @@ -154,18 +104,54 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface $collector->withBudgetInformation(); $journals = $collector->getExtractedJournals(); $array = []; + $convertToNative = Amount::convertToNative($this->user); + $default = Amount::getDefaultCurrency(); foreach ($journals as $journal) { + // same as in the other methods. + $amount = '0'; $currencyId = (int) $journal['currency_id']; + $currencyName = $journal['currency_name']; + $currencySymbol = $journal['currency_symbol']; + $currencyCode = $journal['currency_code']; + $currencyDecimalPlaces = $journal['currency_decimal_places']; + + if ($convertToNative) { + $useNative = $default->id !== (int) $journal['currency_id']; + $amount = Amount::getAmountFromJournal($journal); + if ($useNative) { + Log::debug(sprintf('Journal #%d switches to native amount (original is %s)', $journal['transaction_journal_id'], $journal['currency_code'])); + $currencyId = $default->id; + $currencyName = $default->name; + $currencySymbol = $default->symbol; + $currencyCode = $default->code; + $currencyDecimalPlaces = $default->decimal_places; + } + } + if (!$convertToNative) { + $amount = $journal['amount']; + // if the amount is not in $currency (but should be), use the foreign_amount if that one is correct. + // otherwise, ignore the transaction all together. + if (null !== $currency && $currencyId !== $currency->id && $currency->id === (int) $journal['foreign_currency_id']) { + Log::debug(sprintf('Journal #%d switches to foreign amount because it matches native.', $journal['transaction_journal_id'])); + $amount = $journal['foreign_amount']; + $currencyId = (int) $journal['foreign_currency_id']; + $currencyName = $journal['foreign_currency_name']; + $currencySymbol = $journal['foreign_currency_symbol']; + $currencyCode = $journal['foreign_currency_code']; + $currencyDecimalPlaces = $journal['foreign_currency_decimal_places']; + } + } + $array[$currencyId] ??= [ 'sum' => '0', 'currency_id' => $currencyId, - 'currency_name' => $journal['currency_name'], - 'currency_symbol' => $journal['currency_symbol'], - 'currency_code' => $journal['currency_code'], - 'currency_decimal_places' => $journal['currency_decimal_places'], + 'currency_name' => $currencyName, + 'currency_symbol' => $currencySymbol, + 'currency_code' => $currencyCode, + 'currency_decimal_places' => $currencyDecimalPlaces, ]; - $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount'])); + $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($amount)); } return $array; diff --git a/app/Repositories/Budget/NoBudgetRepositoryInterface.php b/app/Repositories/Budget/NoBudgetRepositoryInterface.php index e430d6e8cd..01b4d6d1f1 100644 --- a/app/Repositories/Budget/NoBudgetRepositoryInterface.php +++ b/app/Repositories/Budget/NoBudgetRepositoryInterface.php @@ -42,10 +42,5 @@ interface NoBudgetRepositoryInterface public function setUser(null|Authenticatable|User $user): void; - /** - * @deprecated - */ - public function spentInPeriodWoBudgetMc(Collection $accounts, Carbon $start, Carbon $end): array; - public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array; }