mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	Add some routes for transfers.
This commit is contained in:
		| @@ -0,0 +1,85 @@ | ||||
| <?php | ||||
| /* | ||||
|  * AccountController.php | ||||
|  * Copyright (c) 2021 james@firefly-iii.org | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers\Insight\Transfer; | ||||
|  | ||||
|  | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Insight\GenericRequest; | ||||
| use FireflyIII\Repositories\Account\OperationsRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Api\ApiSupport; | ||||
| use Illuminate\Http\JsonResponse; | ||||
|  | ||||
| /** | ||||
|  * Class AccountController | ||||
|  */ | ||||
| class AccountController extends Controller | ||||
| { | ||||
|     use ApiSupport; | ||||
|  | ||||
|     private OperationsRepositoryInterface $opsRepository; | ||||
|  | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 $user                = auth()->user(); | ||||
|                 $this->opsRepository = app(OperationsRepositoryInterface::class); | ||||
|                 $this->opsRepository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO same code as Expense/AccountController. | ||||
|      * | ||||
|      * @param GenericRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function asset(GenericRequest $request): JsonResponse | ||||
|     { | ||||
|         $start         = $request->getStart(); | ||||
|         $end           = $request->getEnd(); | ||||
|         $assetAccounts = $request->getAssetAccounts(); | ||||
|         $income        = $this->opsRepository->sumTransfers($start, $end, $assetAccounts); | ||||
|         $result        = []; | ||||
|         /** @var array $entry */ | ||||
|         foreach ($income as $entry) { | ||||
|             $result[] = [ | ||||
|                 'difference'       => $entry['sum'], | ||||
|                 'difference_float' => (float)$entry['sum'], | ||||
|                 'currency_id'      => (string)$entry['currency_id'], | ||||
|                 'currency_code'    => $entry['currency_code'], | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return response()->json($result); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										125
									
								
								app/Api/V1/Controllers/Insight/Transfer/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								app/Api/V1/Controllers/Insight/Transfer/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| <?php | ||||
| /* | ||||
|  * CategoryController.php | ||||
|  * Copyright (c) 2021 james@firefly-iii.org | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers\Insight\Transfer; | ||||
|  | ||||
|  | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Insight\GenericRequest; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use FireflyIII\Repositories\Category\NoCategoryRepositoryInterface; | ||||
| use FireflyIII\Repositories\Category\OperationsRepositoryInterface; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryController | ||||
|  */ | ||||
| class CategoryController extends Controller | ||||
| { | ||||
|     private OperationsRepositoryInterface $opsRepository; | ||||
|     private CategoryRepositoryInterface   $repository; | ||||
|     private NoCategoryRepositoryInterface $noRepository; | ||||
|  | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      * | ||||
|      * @codeCoverageIgnore | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 $this->opsRepository = app(OperationsRepositoryInterface::class); | ||||
|                 $this->repository    = app(CategoryRepositoryInterface::class); | ||||
|                 $this->noRepository  = app(NoCategoryRepositoryInterface::class); | ||||
|                 $user                = auth()->user(); | ||||
|                 $this->opsRepository->setUser($user); | ||||
|                 $this->repository->setUser($user); | ||||
|                 $this->noRepository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GenericRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function category(GenericRequest $request): JsonResponse | ||||
|     { | ||||
|         $start         = $request->getStart(); | ||||
|         $end           = $request->getEnd(); | ||||
|         $categories    = $request->getCategories(); | ||||
|         $assetAccounts = $request->getAssetAccounts(); | ||||
|         $result        = []; | ||||
|         if (0 === $categories->count()) { | ||||
|             $categories = $this->repository->getCategories(); | ||||
|         } | ||||
|         /** @var Category $category */ | ||||
|         foreach ($categories as $category) { | ||||
|             $expenses = $this->opsRepository->sumTransfers($start, $end, $assetAccounts, new Collection([$category])); | ||||
|             /** @var array $expense */ | ||||
|             foreach ($expenses as $expense) { | ||||
|                 $result[] = [ | ||||
|                     'id'               => (string)$category->id, | ||||
|                     'name'             => $category->name, | ||||
|                     'difference'       => $expense['sum'], | ||||
|                     'difference_float' => (float)$expense['sum'], | ||||
|                     'currency_id'      => (string)$expense['currency_id'], | ||||
|                     'currency_code'    => $expense['currency_code'], | ||||
|                 ]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return response()->json($result); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param GenericRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function noCategory(GenericRequest $request): JsonResponse | ||||
|     { | ||||
|         $start         = $request->getStart(); | ||||
|         $end           = $request->getEnd(); | ||||
|         $assetAccounts = $request->getAssetAccounts(); | ||||
|         $result        = []; | ||||
|         $expenses      = $this->noRepository->sumTransfers($start, $end, $assetAccounts); | ||||
|         /** @var array $expense */ | ||||
|         foreach ($expenses as $expense) { | ||||
|             $result[] = [ | ||||
|                 'difference'       => $expense['sum'], | ||||
|                 'difference_float' => (float)$expense['sum'], | ||||
|                 'currency_id'      => (string)$expense['currency_id'], | ||||
|                 'currency_code'    => $expense['currency_code'], | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return response()->json($result); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										82
									
								
								app/Api/V1/Controllers/Insight/Transfer/PeriodController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								app/Api/V1/Controllers/Insight/Transfer/PeriodController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| <?php | ||||
| /* | ||||
|  * PeriodController.php | ||||
|  * Copyright (c) 2021 james@firefly-iii.org | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers\Insight\Transfer; | ||||
|  | ||||
|  | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Insight\GenericRequest; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use Illuminate\Http\JsonResponse; | ||||
|  | ||||
| /** | ||||
|  * Class PeriodController | ||||
|  */ | ||||
| class PeriodController extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param GenericRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function total(GenericRequest $request): JsonResponse | ||||
|     { | ||||
|         $accounts = $request->getAssetAccounts(); | ||||
|         $start    = $request->getStart(); | ||||
|         $end      = $request->getEnd(); | ||||
|         $response = []; | ||||
|  | ||||
|         // 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']; | ||||
|  | ||||
|             if (0 !== $currencyId) { | ||||
|                 $response[$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']; | ||||
|             } | ||||
|             if (0 !== $foreignCurrencyId) { | ||||
|                 $response[$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)); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										173
									
								
								app/Api/V1/Controllers/Insight/Transfer/TagController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								app/Api/V1/Controllers/Insight/Transfer/TagController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| <?php | ||||
| /* | ||||
|  * TagController.php | ||||
|  * Copyright (c) 2021 james@firefly-iii.org | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers\Insight\Transfer; | ||||
|  | ||||
|  | ||||
| use FireflyIII\Api\V1\Controllers\Controller; | ||||
| use FireflyIII\Api\V1\Requests\Insight\GenericRequest; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Tag\TagRepositoryInterface; | ||||
| use Illuminate\Http\JsonResponse; | ||||
|  | ||||
| /** | ||||
|  * Class TagController | ||||
|  */ | ||||
| class TagController extends Controller | ||||
| { | ||||
|     private TagRepositoryInterface $repository; | ||||
|  | ||||
|     /** | ||||
|      * TagController constructor. | ||||
|      * TODO lots of copying and pasting here. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 $user             = auth()->user(); | ||||
|                 $this->repository = app(TagRepositoryInterface::class); | ||||
|                 $this->repository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Transfers per tag, possibly filtered by tag and account. | ||||
|      * | ||||
|      * @param GenericRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function tag(GenericRequest $request): JsonResponse | ||||
|     { | ||||
|         $accounts = $request->getAssetAccounts(); | ||||
|         $tags     = $request->getTags(); | ||||
|         $start    = $request->getStart(); | ||||
|         $end      = $request->getEnd(); | ||||
|         $response = []; | ||||
|  | ||||
|         // get all tags: | ||||
|         if (0 === $tags->count()) { | ||||
|             $tags = $this->repository->get(); | ||||
|         } | ||||
|  | ||||
|         // collect all expenses in this period (regardless of type) by the given bills and accounts. | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts); | ||||
|         $collector->setTags($tags); | ||||
|         $genericSet = $collector->getExtractedJournals(); | ||||
|         /** @var array $entry */ | ||||
|         foreach ($genericSet as $journal) { | ||||
|             $currencyId        = (int)$journal['currency_id']; | ||||
|             $foreignCurrencyId = (int)$journal['foreign_currency_id']; | ||||
|  | ||||
|             /** @var array $tag */ | ||||
|             foreach ($journal['tags'] as $tag) { | ||||
|                 $tagId      = $tag['id']; | ||||
|                 $key        = sprintf('%d-%d', $tagId, $currencyId); | ||||
|                 $foreignKey = sprintf('%d-%d', $tagId, $foreignCurrencyId); | ||||
|  | ||||
|                 // on currency ID | ||||
|                 if (0 !== $currencyId) { | ||||
|                     $response[$key]                     = $response[$key] ?? [ | ||||
|                             'id'               => (string)$tagId, | ||||
|                             'name'             => $tag['name'], | ||||
|                             'difference'       => '0', | ||||
|                             'difference_float' => 0, | ||||
|                             'currency_id'      => (string)$currencyId, | ||||
|                             'currency_code'    => $journal['currency_code'], | ||||
|                         ]; | ||||
|                     $response[$key]['difference']       = bcadd($response[$key]['difference'], app('steam')->positive($journal['amount'])); | ||||
|                     $response[$key]['difference_float'] = (float)$response[$key]['difference']; | ||||
|                 } | ||||
|  | ||||
|                 // on foreign ID | ||||
|                 if (0 !== $foreignCurrencyId) { | ||||
|                     $response[$foreignKey]                     = $journal[$foreignKey] ?? [ | ||||
|                             'difference'       => '0', | ||||
|                             'difference_float' => 0, | ||||
|                             'currency_id'      => (string)$foreignCurrencyId, | ||||
|                             'currency_code'    => $journal['foreign_currency_code'], | ||||
|                         ]; | ||||
|                     $response[$foreignKey]['difference']       = bcadd($response[$foreignKey]['difference'], app('steam')->positive($journal['foreign_amount'])); | ||||
|                     $response[$foreignKey]['difference_float'] = (float)$response[$foreignKey]['difference']; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return response()->json(array_values($response)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Expenses for no tag filtered by account. | ||||
|      * | ||||
|      * @param GenericRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function noTag(GenericRequest $request): JsonResponse | ||||
|     { | ||||
|         $accounts = $request->getAssetAccounts(); | ||||
|         $start    = $request->getStart(); | ||||
|         $end      = $request->getEnd(); | ||||
|         $response = []; | ||||
|  | ||||
|         // collect all expenses in this period (regardless of type) by the given bills and accounts. | ||||
|         $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']; | ||||
|  | ||||
|             if (0 !== $currencyId) { | ||||
|                 $response[$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']; | ||||
|             } | ||||
|             if (0 !== $foreignCurrencyId) { | ||||
|                 $response[$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)); | ||||
|     } | ||||
| } | ||||
| @@ -247,7 +247,7 @@ class GenericRequest extends FormRequest | ||||
|         if (is_array($array)) { | ||||
|             foreach ($array as $billId) { | ||||
|                 $billId = (int)$billId; | ||||
|                 $bill   = $repository->findNull($billId); | ||||
|                 $bill   = $repository->find($billId); | ||||
|                 if (null !== $billId) { | ||||
|                     $this->bills->push($bill); | ||||
|                 } | ||||
|   | ||||
| @@ -61,13 +61,13 @@ class WebhookEventHandler | ||||
|         // kick off the job! | ||||
|         $messages = WebhookMessage | ||||
|             ::where('webhook_messages.sent', 0) | ||||
|             ->where('webhook_messages.errored', 0) | ||||
|             //->where('webhook_messages.errored', 0) | ||||
|             ->get(['webhook_messages.*']) | ||||
|             ->filter( | ||||
|                 function (WebhookMessage $message) { | ||||
|                     return $message->webhookAttempts()->count() <= 2; | ||||
|                 } | ||||
|             )->splice(0, 3); | ||||
|             )->splice(0, 5); | ||||
|         Log::debug(sprintf('Found %d webhook message(s) ready to be send.', $messages->count())); | ||||
|         foreach ($messages as $message) { | ||||
|             SendWebhookMessage::dispatch($message)->afterResponse(); | ||||
|   | ||||
| @@ -311,4 +311,70 @@ class OperationsRepository implements OperationsRepositoryInterface | ||||
|         } | ||||
|         return $array; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array | ||||
|     { | ||||
|         $start->startOfDay(); | ||||
|         $end->endOfDay(); | ||||
|  | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER]); | ||||
|  | ||||
|         if (null !== $accounts) { | ||||
|             $collector->setAccounts($accounts); | ||||
|         } | ||||
|         if (null !== $currency) { | ||||
|             $collector->setCurrency($currency); | ||||
|         } | ||||
|         $journals = $collector->getExtractedJournals(); | ||||
|  | ||||
|         // same but for foreign currencies: | ||||
|         if (null !== $currency) { | ||||
|             /** @var GroupCollectorInterface $collector */ | ||||
|             $collector = app(GroupCollectorInterface::class); | ||||
|             $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL]) | ||||
|                       ->setForeignCurrency($currency); | ||||
|  | ||||
|             if (null !== $accounts) { | ||||
|                 $collector->setAccounts($accounts); | ||||
|             } | ||||
|             $result = $collector->getExtractedJournals(); | ||||
|  | ||||
|             // do not use array_merge because you want keys to overwrite (otherwise you get double results): | ||||
|             $journals = $result + $journals; | ||||
|         } | ||||
|         $array = []; | ||||
|  | ||||
|         foreach ($journals as $journal) { | ||||
|             $currencyId                = (int)$journal['currency_id']; | ||||
|             $array[$currencyId]        = $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'], | ||||
|                 ]; | ||||
|             $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->positive($journal['amount'])); | ||||
|  | ||||
|             // also do foreign amount: | ||||
|             $foreignId = (int)$journal['foreign_currency_id']; | ||||
|             if (0 !== $foreignId) { | ||||
|                 $array[$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')->positive($journal['foreign_amount'])); | ||||
|             } | ||||
|         } | ||||
|         return $array; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -89,4 +89,16 @@ interface OperationsRepositoryInterface | ||||
|      * @return array | ||||
|      */ | ||||
|     public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null): array; | ||||
|  | ||||
|     /** | ||||
|      * Sum of transfers in period for a set of accounts, grouped per currency. Amounts are always positive. | ||||
|      * | ||||
|      * @param Carbon                   $start | ||||
|      * @param Carbon                   $end | ||||
|      * @param Collection|null          $accounts | ||||
|      * @param TransactionCurrency|null $currency | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array; | ||||
| } | ||||
|   | ||||
| @@ -29,7 +29,6 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * | ||||
| @@ -37,8 +36,7 @@ use Log; | ||||
|  */ | ||||
| class NoCategoryRepository implements NoCategoryRepositoryInterface | ||||
| { | ||||
|     /** @var User */ | ||||
|     private $user; | ||||
|     private User $user; | ||||
|  | ||||
|     /** | ||||
|      * This method returns a list of all the withdrawal transaction journals (as arrays) set in that period | ||||
| @@ -229,4 +227,35 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface | ||||
|  | ||||
|         return $array; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null): array | ||||
|     { | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])->withoutCategory(); | ||||
|  | ||||
|         if (null !== $accounts && $accounts->count() > 0) { | ||||
|             $collector->setAccounts($accounts); | ||||
|         } | ||||
|         $journals = $collector->getExtractedJournals(); | ||||
|         $array    = []; | ||||
|  | ||||
|         foreach ($journals as $journal) { | ||||
|             $currencyId                = (int)$journal['currency_id']; | ||||
|             $array[$currencyId]        = $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'], | ||||
|                 ]; | ||||
|             $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->positive($journal['amount'])); | ||||
|         } | ||||
|  | ||||
|         return $array; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -87,5 +87,16 @@ interface NoCategoryRepositoryInterface | ||||
|      */ | ||||
|     public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array; | ||||
|  | ||||
|     /** | ||||
|      * Sum of transfers in period without a category, grouped per currency. Amounts are always positive. | ||||
|      * | ||||
|      * @param Carbon          $start | ||||
|      * @param Carbon          $end | ||||
|      * @param Collection|null $accounts | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null): array; | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -294,6 +294,49 @@ class OperationsRepository implements OperationsRepositoryInterface | ||||
|         return $array; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sum of income journals in period for a set of categories, grouped per currency. Amounts are always positive. | ||||
|      * | ||||
|      * @param Carbon          $start | ||||
|      * @param Carbon          $end | ||||
|      * @param Collection|null $accounts | ||||
|      * @param Collection|null $categories | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array | ||||
|     { | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setUser($this->user)->setRange($start, $end) | ||||
|                   ->setTypes([TransactionType::TRANSFER]); | ||||
|  | ||||
|         if (null !== $accounts && $accounts->count() > 0) { | ||||
|             $collector->setAccounts($accounts); | ||||
|         } | ||||
|         if (null === $categories || (null !== $categories && 0 === $categories->count())) { | ||||
|             $categories = $this->getCategories(); | ||||
|         } | ||||
|         $collector->setCategories($categories); | ||||
|         $journals = $collector->getExtractedJournals(); | ||||
|         $array    = []; | ||||
|  | ||||
|         foreach ($journals as $journal) { | ||||
|             $currencyId                = (int)$journal['currency_id']; | ||||
|             $array[$currencyId]        = $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'], | ||||
|                 ]; | ||||
|             $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->positive($journal['amount'])); | ||||
|         } | ||||
|  | ||||
|         return $array; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of all the categories belonging to a user. | ||||
|      * | ||||
|   | ||||
| @@ -89,4 +89,16 @@ interface OperationsRepositoryInterface | ||||
|      * @return array | ||||
|      */ | ||||
|     public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array; | ||||
|  | ||||
|     /** | ||||
|      * Sum of transfers in period for a set of categories, grouped per currency. Amounts are always positive. | ||||
|      * | ||||
|      * @param Carbon          $start | ||||
|      * @param Carbon          $end | ||||
|      * @param Collection|null $accounts | ||||
|      * @param Collection|null $categories | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array; | ||||
| } | ||||
|   | ||||
| @@ -153,12 +153,14 @@ class WebhookRepository implements WebhookRepositoryInterface | ||||
|                            } | ||||
|                        )->splice(0, 3); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @inheritDoc | ||||
|      */ | ||||
|     public function getMessages(Webhook $webhook): Collection | ||||
|     { | ||||
|         return $webhook->webhookMessages() | ||||
|                        ->orderBy('created_at', 'DESC') | ||||
|                        ->get(['webhook_messages.*']); | ||||
|     } | ||||
|  | ||||
| @@ -167,6 +169,6 @@ class WebhookRepository implements WebhookRepositoryInterface | ||||
|      */ | ||||
|     public function getAttempts(WebhookMessage $webhookMessage): Collection | ||||
|     { | ||||
|         return $webhookMessage->webhookAttempts; | ||||
|         return $webhookMessage->webhookAttempts()->orderBy('created_at', 'DESC')->get(['webhook_attempts.*']); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -118,7 +118,7 @@ class StandardWebhookSender implements WebhookSenderInterface | ||||
|         ]; | ||||
|         $client  = new Client; | ||||
|         try { | ||||
|             $res                 = $client->request('POST', $this->message->webhook->url, $options); | ||||
|             $res                 = $client->request('POST', $this->message->webhook->url . 'x', $options); | ||||
|             $this->message->sent = true; | ||||
|         } catch (ClientException | Exception $e) { | ||||
|             Log::error($e->getMessage()); | ||||
|   | ||||
							
								
								
									
										165
									
								
								routes/api.php
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								routes/api.php
									
									
									
									
									
								
							| @@ -114,15 +114,10 @@ Route::group( | ||||
|         Route::get('tag', ['uses' => 'TagController@tag', 'as' => 'tag']); | ||||
|         Route::get('no-tag', ['uses' => 'TagController@noTag', 'as' => 'no-tag']); | ||||
|  | ||||
|  | ||||
|         // TODO per budget limit? | ||||
|         // TODO per object group? | ||||
|         // TODO per recurrence? | ||||
|         // TODO per object group | ||||
|         // TODO transfers voor piggies | ||||
|         // TODO transfers per piggy? | ||||
|         // TODO currency? | ||||
|         // TODO net worth? | ||||
|         // TODO Per object group, maybe in the future. | ||||
|         // TODO Per recurrence, all transactions created under it. | ||||
|         // TODO Per currency, or as a filter? | ||||
|         // TODO Show user net worth? | ||||
|     } | ||||
| ); | ||||
| // insight in income | ||||
| @@ -140,21 +135,29 @@ Route::group( | ||||
|         Route::get('tag', ['uses' => 'TagController@tag', 'as' => 'tag']); | ||||
|         Route::get('no-tag', ['uses' => 'TagController@noTag', 'as' => 'no-tag']); | ||||
|  | ||||
|         // TODO per budget limit? | ||||
|         // TODO per object group? | ||||
|         // TODO per recurrence? | ||||
|         // TODO per object group | ||||
|         // TODO transfers voor piggies | ||||
|         // TODO transfers per piggy? | ||||
|         // TODO currency? | ||||
|         // TODO net worth? | ||||
|         // TODO Per object group, maybe in the future. | ||||
|         // TODO Per recurrence, all transactions created under it. | ||||
|         // TODO Per currency, or as a filter? | ||||
|         // TODO Show user net worth? | ||||
|     } | ||||
| ); | ||||
|  | ||||
|  | ||||
| // Insight in transfers | ||||
| // TODO | ||||
| Route::group( | ||||
|     ['namespace' => 'FireflyIII\Api\V1\Controllers\Insight\Transfer', 'prefix' => 'insight/transfer', | ||||
|      'as'        => 'api.v1.insight.income.',], | ||||
|     static function () { | ||||
|         // Insight in expenses per account: | ||||
|         Route::get('asset', ['uses' => 'AccountController@asset', 'as' => 'asset']); | ||||
|         Route::get('category', ['uses' => 'CategoryController@category', 'as' => 'category']); | ||||
|         Route::get('no-category', ['uses' => 'CategoryController@noCategory', 'as' => 'no-category']); | ||||
|         Route::get('tag', ['uses' => 'TagController@tag', 'as' => 'tag']); | ||||
|         Route::get('no-tag', ['uses' => 'TagController@noTag', 'as' => 'no-tag']); | ||||
|         Route::get('total', ['uses' => 'PeriodController@total', 'as' => 'total']); | ||||
|  | ||||
|         // TODO Transfers for piggies | ||||
|     } | ||||
| ); | ||||
|  | ||||
|  | ||||
| /** | ||||
| @@ -508,7 +511,6 @@ Route::group( | ||||
| ); | ||||
|  | ||||
|  | ||||
|  | ||||
| // Users API routes: | ||||
| Route::group( | ||||
|     ['middleware' => ['auth:api', 'bindings', IsAdmin::class], 'namespace' => 'FireflyIII\Api\V1\Controllers\System', 'prefix' => 'users', | ||||
| @@ -559,126 +561,9 @@ Route::group( | ||||
|         // webhook message attempts | ||||
|         Route::get('{webhook}/messages/{webhookMessage}/attempts', ['uses' => 'AttemptController@index', 'as' => 'attempts.index']); | ||||
|         Route::get('{webhook}/messages/{webhookMessage}/attempts/{webhookAttempt}', ['uses' => 'AttemptController@show', 'as' => 'attempts.show']); | ||||
|         Route::delete('{webhook}/messages/{webhookMessage}/attempts/{webhookAttempt}', ['uses' => 'DestroyController@destroyAttempt', 'as' => 'attempts.destroy']); | ||||
|         Route::delete( | ||||
|             '{webhook}/messages/{webhookMessage}/attempts/{webhookAttempt}', ['uses' => 'DestroyController@destroyAttempt', 'as' => 'attempts.destroy'] | ||||
|         ); | ||||
|     } | ||||
| ); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * DATA CONTROLLERS | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| //// EXPORT | ||||
| //Route::group( | ||||
| //    ['namespace' => 'FireflyIII\Api\V1\Controllers\Data\Export', 'prefix' => 'data/export', | ||||
| //     'as'        => 'api.v1.data.export.',], | ||||
| //    static function () { | ||||
| //        Route::get('transactions', ['uses' => 'TransactionController@export', 'as' => 'transactions']); | ||||
| //    } | ||||
| //); | ||||
|  | ||||
| /** | ||||
|  * INSIGHT CONTROLLERS | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * System and configuration controllers | ||||
|  */ | ||||
|  | ||||
| // TODO get rid of underscores. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //// TODO VERIFY API DOCS | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // | ||||
| // | ||||
| //// TODO VERIFY API DOCS | ||||
| //Route::group( | ||||
| //    ['namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'cer', | ||||
| //     'as'        => 'api.v1.cer.',], | ||||
| //    static function () { | ||||
| // | ||||
| //        // Currency Exchange Rate API routes: | ||||
| //        Route::get('', ['uses' => 'CurrencyExchangeRateController@index', 'as' => 'index']); | ||||
| //    } | ||||
| //); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //); | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // | ||||
| //// TODO VERIFY API DOCS | ||||
| //Route::group( | ||||
| //    ['namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'tag-cloud', | ||||
| //     'as'        => 'api.v1.tag-cloud.',], | ||||
| //    static function () { | ||||
| //        // Tag cloud API routes (to prevent collisions) | ||||
| //        Route::get('', ['uses' => 'TagController@cloud', 'as' => 'cloud']); | ||||
| //    } | ||||
| //); | ||||
| // | ||||
|  | ||||
| // | ||||
| //// special group for transaction journals | ||||
| //// TODO VERIFY API DOCS | ||||
| //Route::group( | ||||
| //    ['namespace' => 'FireflyIII\Api\V1\Controllers\Models\Transaction', 'prefix' => 'transaction-journals', | ||||
| //     'as'        => 'api.v1.journals.',], | ||||
| //    static function () { | ||||
| // | ||||
| //        // Transaction API routes: | ||||
| //        Route::get('{tj}', ['uses' => 'ShowController@showByJournal', 'as' => 'showByJournal']); | ||||
| //    } | ||||
| //); | ||||
| // | ||||
|   | ||||
		Reference in New Issue
	
	Block a user