Compare commits

...

69 Commits

Author SHA1 Message Date
James Cole
ad44f99dbf Merge branch 'release/4.8.0.2' 2019-08-17 12:38:04 +02:00
James Cole
12a64fefc8 Fix test. 2019-08-17 12:31:55 +02:00
James Cole
2ee8cbbae4 Update change logs and files for new version. 2019-08-17 12:27:15 +02:00
James Cole
34c19b145c Updated strings. 2019-08-17 12:24:16 +02:00
James Cole
c5e047ea02 Update copyright 2019-08-17 12:13:02 +02:00
James Cole
fc78c32fca Add newline to files 2019-08-17 12:09:03 +02:00
James Cole
b53cbbe469 Fix test coverage. 2019-08-17 12:08:09 +02:00
James Cole
1d4434698e Fix some tests. 2019-08-17 11:32:05 +02:00
James Cole
6d1bfd3956 Code cleanup 2019-08-17 10:54:16 +02:00
James Cole
1974d5f1e3 Code cleanup 2019-08-17 10:48:28 +02:00
James Cole
c235e42d6c Bill report URL must be set. 2019-08-17 10:48:09 +02:00
James Cole
342985d52a Code cleanup 2019-08-17 10:47:51 +02:00
James Cole
c2296c3ad5 Code cleanup 2019-08-17 10:47:29 +02:00
James Cole
23479790fe Code cleanup 2019-08-17 10:47:10 +02:00
James Cole
44823c6fec Code cleanup 2019-08-17 10:46:55 +02:00
James Cole
acfdf7dc90 Code cleanup 2019-08-17 10:46:40 +02:00
James Cole
6038a68ba9 Code cleanup 2019-08-17 10:46:32 +02:00
James Cole
79cf61b653 Fix #2434 2019-08-17 08:29:35 +02:00
James Cole
b97d3d3627 And fix sorting. 2019-08-17 08:04:41 +02:00
James Cole
7f887e294a Fix some charts. 2019-08-17 08:00:27 +02:00
James Cole
6f78735bc5 Fix some report issues. 2019-08-17 07:47:39 +02:00
James Cole
3e242aaca6 Clean up login controller. 2019-08-17 06:35:45 +02:00
James Cole
0796e422d4 Cleanup showLoginForm() 2019-08-17 06:24:49 +02:00
James Cole
fbd7c9ae07 Remove logout method (is the same) 2019-08-17 06:23:12 +02:00
James Cole
5cfb1b63dc Remove inspection warnings. 2019-08-17 06:22:42 +02:00
James Cole
f09d0e87e4 Remove inspection, add TODO's, make code a bit simpler. 2019-08-16 21:38:35 +02:00
James Cole
820358af73 Remove unused code. 2019-08-16 21:23:20 +02:00
James Cole
5a2998c80e Simplify bill overview. 2019-08-16 21:21:38 +02:00
James Cole
a32df0066e Fix form inconsistencies. 2019-08-16 19:08:20 +02:00
James Cole
02db333d46 Update for balance box in report. 2019-08-16 17:54:38 +02:00
James Cole
070f46c755 Budget box is multi-currency. 2019-08-16 08:27:08 +02:00
James Cole
b4a732bf77 Namespace errors, spotted by @davids3 #2392 2019-08-16 07:24:04 +02:00
James Cole
d8eb59736e Improve report boxes one by one #2428 2019-08-16 06:21:10 +02:00
James Cole
41c15b0cf8 Forgot auth in API 2019-08-16 06:20:16 +02:00
James Cole
fdf99400bc Some TODO's for the future. 2019-08-16 06:20:07 +02:00
James Cole
1ba45afeab Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2019-08-16 05:22:24 +02:00
James Cole
1819ece55d Merge pull request #2429 from GeoffreyFrogeye/emd_date
Fix typo in BudgetRepository (emd_date)
2019-08-16 05:15:50 +02:00
James Cole
78335210db Cleanup API middleware. 2019-08-16 05:08:56 +02:00
Geoffrey “Frogeye” Preud'homme
ca23bb6272 Fix typo in BudgetRepository (emd_date) 2019-08-15 23:23:06 +02:00
James Cole
eed84e18bb Fix #2423 2019-08-14 20:25:38 +02:00
James Cole
12641f96b1 Fix #2422 2019-08-14 20:23:11 +02:00
James Cole
1b97c4d58f Fix date for recurring transactions #2407 2019-08-14 20:06:16 +02:00
James Cole
ee3a2ef41c Fix report issues. 2019-08-14 19:51:46 +02:00
James Cole
084ceb0c4e Report fixes for #2418 2019-08-14 19:06:05 +02:00
James Cole
2497c4ee5c Fix #2426 2019-08-14 17:54:15 +02:00
James Cole
757a118f87 Change comment [skip ci] 2019-08-14 06:16:44 +02:00
James Cole
97908932e6 Fix #2393 2019-08-13 19:01:30 +02:00
James Cole
4c73ad8306 Fix #2402 2019-08-13 18:50:18 +02:00
James Cole
10a2078661 Fix #2404 2019-08-13 18:45:44 +02:00
James Cole
3fb09136cf Fix #2410 2019-08-13 18:38:15 +02:00
James Cole
843cced454 Fix #2405 2019-08-13 16:45:04 +02:00
James Cole
71a501868f Fix docker build back to original script. 2019-08-13 16:26:27 +02:00
James Cole
0a0ad8200a Fix #2414 2019-08-13 16:24:36 +02:00
James Cole
a9baf54b12 Fix #2416 2019-08-13 16:02:28 +02:00
James Cole
ed565136fc Fix #2415 2019-08-13 16:00:35 +02:00
James Cole
4719b87314 Try the ARM thing with my own version of the script. 2019-08-12 19:53:54 +02:00
James Cole
24b30af018 Install extension. 2019-08-12 19:31:42 +02:00
James Cole
e9f4695355 Fix ARM script. 2019-08-12 18:44:57 +02:00
James Cole
5b969fa014 Fix LDAP in ARM 2019-08-12 18:34:32 +02:00
James Cole
499e713683 Remove unused methods. 2019-08-12 18:24:33 +02:00
James Cole
5eadb51b78 Some refactoring. 2019-08-12 18:19:13 +02:00
James Cole
713a962005 Log errors instead of giving exceptions 2019-08-12 18:19:06 +02:00
James Cole
d96e77a3ec Use new methods from category repository 2019-08-12 18:18:51 +02:00
James Cole
bc68c367c8 Refactor earnedInperiod and spentInPeriod 2019-08-12 18:18:26 +02:00
James Cole
33e241d39a Remove initial balance accounts from auto-complete. 2019-08-12 18:17:43 +02:00
James Cole
e67812bf64 Method is no longer used. 2019-08-12 18:17:15 +02:00
James Cole
1090ce6597 Remove sum, make multi-currency 2019-08-12 18:16:28 +02:00
James Cole
e358f19548 Make method static 2019-08-12 18:16:12 +02:00
James Cole
eac406d62d Merge tag '4.8.0.1' into develop
4.8.0.1
2019-08-12 18:12:03 +02:00
674 changed files with 4289 additions and 4290 deletions

View File

@@ -40,6 +40,7 @@ APP_LOG_LEVEL=notice
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html # For other database types, please see the FAQ: http://firefly-iii.readthedocs.io/en/latest/support/faq.html
DB_CONNECTION=mysql DB_CONNECTION=mysql
# If you use DOCKER COMPOSE, change this variable to "firefly_iii_db"
DB_HOST=127.0.0.1 DB_HOST=127.0.0.1
DB_PORT=3306 DB_PORT=3306
DB_DATABASE=homestead DB_DATABASE=homestead

View File

@@ -1,3 +1,27 @@
# 4.8.0.2 (API 0.10.0)
- [Issue 2203](https://github.com/firefly-iii/firefly-iii/issues/2203) Reconciliation inconsistencies.
- [Issue 2392](https://github.com/firefly-iii/firefly-iii/issues/2392) Bad namespace leads to installation errors.
- [Issue 2393](https://github.com/firefly-iii/firefly-iii/issues/2393) Missing budget selector.
- [Issue 2402](https://github.com/firefly-iii/firefly-iii/issues/2402) bad amounts in default report
- [Issue 2405](https://github.com/firefly-iii/firefly-iii/issues/2405) Due date can't be edited.
- [Issue 2404](https://github.com/firefly-iii/firefly-iii/issues/2404) bad page indicator in the "no category" transaction overview.
- [Issue 2407](https://github.com/firefly-iii/firefly-iii/issues/2407) Fix recurring transaction dates
- [Issue 2410](https://github.com/firefly-iii/firefly-iii/issues/2410) Transaction links inconsistent
- [Issue 2414](https://github.com/firefly-iii/firefly-iii/issues/2414) Can't edit recurring transactions
- [Issue 2415](https://github.com/firefly-iii/firefly-iii/issues/2415) Return here + reset form results in empty transaction form
- [Issue 2416](https://github.com/firefly-iii/firefly-iii/issues/2416) Some form inconsistencies.
- [Issue 2418](https://github.com/firefly-iii/firefly-iii/issues/2418) Reports are inaccurate or broken.
- [Issue 2422](https://github.com/firefly-iii/firefly-iii/issues/2422) PHP error when matching transactions.
- [Issue 2423](https://github.com/firefly-iii/firefly-iii/issues/2423) Reports are inaccurate or broken.
- [Issue 2426](https://github.com/firefly-iii/firefly-iii/issues/2426) Inconsistent documentation and instructions.
- [Issue 2427](https://github.com/firefly-iii/firefly-iii/issues/2427) Deleted account and "initial balance" accounts may appear in dropdowns.
- [Issue 2428](https://github.com/firefly-iii/firefly-iii/issues/2428) Reports are inaccurate or broken.
- [Issue 2429](https://github.com/firefly-iii/firefly-iii/issues/2429) Typo leads to SQL errors in available budgets API
- [Issue 2431](https://github.com/firefly-iii/firefly-iii/issues/2431) Issues creating new recurring transactions.
- [Issue 2434](https://github.com/firefly-iii/firefly-iii/issues/2434) You can edit the initial balance transaction but it fails to save.
- ARM build should work now.
# 4.8.0.1 (API 0.10.0) # 4.8.0.1 (API 0.10.0)
- The balance box on the dashboard shows only negative numbers, skewing the results. - The balance box on the dashboard shows only negative numbers, skewing the results.

View File

@@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = (
manifest = ( manifest = (
appTitle = (defaultText = "Firefly III"), appTitle = (defaultText = "Firefly III"),
appVersion = 33, appVersion = 34,
appMarketingVersion = (defaultText = "4.8.0.1"), appMarketingVersion = (defaultText = "4.8.0.2"),
actions = [ actions = [
# Define your "new document" handlers here. # Define your "new document" handlers here.

View File

@@ -1,7 +1,7 @@
sudo: required sudo: required
language: bash language: bash
env: env:
- VERSION=4.8.0.1 - VERSION=4.8.0.2
dist: xenial dist: xenial

View File

@@ -47,7 +47,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class AccountController. * Class AccountController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class AccountController extends Controller class AccountController extends Controller
{ {
@@ -234,8 +234,6 @@ class AccountController extends Controller
* *
* @return JsonResponse * @return JsonResponse
* *
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/ */
public function transactions(Request $request, Account $account): JsonResponse public function transactions(Request $request, Account $account): JsonResponse
{ {

View File

@@ -45,7 +45,7 @@ use function strlen;
/** /**
* Class AttachmentController. * Class AttachmentController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class AttachmentController extends Controller class AttachmentController extends Controller
{ {

View File

@@ -42,7 +42,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class AvailableBudgetController. * Class AvailableBudgetController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class AvailableBudgetController extends Controller class AvailableBudgetController extends Controller
{ {

View File

@@ -48,7 +48,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class BillController. * Class BillController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class BillController extends Controller class BillController extends Controller
{ {

View File

@@ -47,7 +47,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class BudgetController. * Class BudgetController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class BudgetController extends Controller class BudgetController extends Controller
{ {
@@ -79,8 +79,6 @@ class BudgetController extends Controller
/** /**
* Display a listing of the resource. * Display a listing of the resource.
*
*
* @param Request $request * @param Request $request
* @param Budget $budget * @param Budget $budget
* *

View File

@@ -46,7 +46,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class BudgetLimitController. * Class BudgetLimitController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class BudgetLimitController extends Controller class BudgetLimitController extends Controller
{ {

View File

@@ -44,7 +44,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class CategoryController. * Class CategoryController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class CategoryController extends Controller class CategoryController extends Controller
{ {

View File

@@ -37,7 +37,7 @@ use Symfony\Component\HttpFoundation\ParameterBag;
* Class Controller. * Class Controller.
* *
* @codeCoverageIgnore * @codeCoverageIgnore
* @SuppressWarnings(PHPMD.NumberOfChildren) *
*/ */
class Controller extends BaseController class Controller extends BaseController
{ {

View File

@@ -66,7 +66,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class CurrencyController. * Class CurrencyController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class CurrencyController extends Controller class CurrencyController extends Controller
{ {

View File

@@ -45,7 +45,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class LinkTypeController. * Class LinkTypeController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class LinkTypeController extends Controller class LinkTypeController extends Controller
{ {

View File

@@ -42,7 +42,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class PiggyBankController. * Class PiggyBankController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class PiggyBankController extends Controller class PiggyBankController extends Controller
{ {

View File

@@ -48,7 +48,7 @@ use Log;
/** /**
* Class RuleController * Class RuleController
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class RuleController extends Controller class RuleController extends Controller
{ {

View File

@@ -231,7 +231,7 @@ class RuleGroupController extends Controller
* *
* @return JsonResponse * @return JsonResponse
* @throws FireflyException * @throws FireflyException
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) *
*/ */
public function testGroup(RuleGroupTestRequest $request, RuleGroup $group): JsonResponse public function testGroup(RuleGroupTestRequest $request, RuleGroup $group): JsonResponse
{ {

View File

@@ -42,7 +42,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
/** /**
* Class UserController. * Class UserController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class UserController extends Controller class UserController extends Controller
{ {

View File

@@ -1,4 +1,5 @@
<?php <?php
/** /**
* DateRequest.php * DateRequest.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com
@@ -19,6 +20,8 @@
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>. * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/ */
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests; namespace FireflyIII\Api\V1\Requests;

View File

@@ -1,4 +1,5 @@
<?php <?php
/** /**
* RuleGroupTestRequest.php * RuleGroupTestRequest.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com
@@ -19,6 +20,9 @@
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>. * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/ */
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests; namespace FireflyIII\Api\V1\Requests;

View File

@@ -1,4 +1,5 @@
<?php <?php
/** /**
* RuleGroupTriggerRequest.php * RuleGroupTriggerRequest.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com
@@ -19,6 +20,9 @@
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>. * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/ */
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests; namespace FireflyIII\Api\V1\Requests;

View File

@@ -1,4 +1,5 @@
<?php <?php
/** /**
* RuleTestRequest.php * RuleTestRequest.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com
@@ -19,6 +20,9 @@
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>. * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/ */
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests; namespace FireflyIII\Api\V1\Requests;

View File

@@ -1,4 +1,5 @@
<?php <?php
/** /**
* RuleTriggerRequest.php * RuleTriggerRequest.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com
@@ -19,6 +20,8 @@
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>. * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/ */
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests; namespace FireflyIII\Api\V1\Requests;

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* CreateAccessTokens.php * CreateAccessTokens.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* CreateLinkTypes.php * CreateLinkTypes.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* DeleteEmptyGroups.php * DeleteEmptyGroups.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* DeleteEmptyJournals.php * DeleteEmptyJournals.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* DeleteOrphanedTransactions.php * DeleteOrphanedTransactions.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* DeleteZeroAmount.php * DeleteZeroAmount.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* EnableCurrencies.php * EnableCurrencies.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* FixAccountTypes.php * FixAccountTypes.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* FixPiggies.php * FixPiggies.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* FixUnevenAmount.php * FixUnevenAmount.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* RemoveBills.php * RemoveBills.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* RenameMetaFields.php * RenameMetaFields.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* TransferBudgets.php * TransferBudgets.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* ReportEmptyObjects.php * ReportEmptyObjects.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* ReportSum.php * ReportSum.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* AccountCurrencies.php * AccountCurrencies.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* BackToJournals.php * BackToJournals.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* MigrateToGroups.php * MigrateToGroups.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com
@@ -236,7 +237,7 @@ class MigrateToGroups extends Command
* @param TransactionJournal $journal * @param TransactionJournal $journal
* *
* @throws Exception * @throws Exception
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) *
*/ */
private function makeMultiGroup(TransactionJournal $journal): void private function makeMultiGroup(TransactionJournal $journal): void
{ {

View File

@@ -125,6 +125,7 @@ class OtherCurrenciesCorrections extends Command
if (isset($this->accountCurrencies[$accountId]) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) { if (isset($this->accountCurrencies[$accountId]) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) {
return $this->accountCurrencies[$accountId]; // @codeCoverageIgnore return $this->accountCurrencies[$accountId]; // @codeCoverageIgnore
} }
// TODO we can use getAccountCurrency() instead
$currencyId = (int)$this->accountRepos->getMetaValue($account, 'currency_id'); $currencyId = (int)$this->accountRepos->getMetaValue($account, 'currency_id');
$result = $this->currencyRepos->findNull($currencyId); $result = $this->currencyRepos->findNull($currencyId);
if (null === $result) { if (null === $result) {
@@ -247,8 +248,8 @@ class OtherCurrenciesCorrections extends Command
* Gets the transaction that determines the transaction that "leads" and will determine * Gets the transaction that determines the transaction that "leads" and will determine
* the currency to be used by all transactions, and the journal itself. * the currency to be used by all transactions, and the journal itself.
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @param TransactionJournal $journal * @param TransactionJournal $journal
*
* @return Transaction|null * @return Transaction|null
*/ */
private function getLeadTransaction(TransactionJournal $journal): ?Transaction private function getLeadTransaction(TransactionJournal $journal): ?Transaction

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* RenameAccountMeta.php * RenameAccountMeta.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* TransactionIdentifier.php * TransactionIdentifier.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* TransferCurrenciesCorrections.php * TransferCurrenciesCorrections.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com
@@ -147,6 +148,7 @@ class TransferCurrenciesCorrections extends Command
if (isset($this->accountCurrencies[$accountId]) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) { if (isset($this->accountCurrencies[$accountId]) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) {
return $this->accountCurrencies[$accountId]; // @codeCoverageIgnore return $this->accountCurrencies[$accountId]; // @codeCoverageIgnore
} }
// TODO we can use getAccountCurrency() instead
$currencyId = (int)$this->accountRepos->getMetaValue($account, 'currency_id'); $currencyId = (int)$this->accountRepos->getMetaValue($account, 'currency_id');
$result = $this->currencyRepos->findNull($currencyId); $result = $this->currencyRepos->findNull($currencyId);
if (null === $result) { if (null === $result) {
@@ -290,8 +292,6 @@ class TransferCurrenciesCorrections extends Command
} }
/** /**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*
* @param TransactionJournal $transfer * @param TransactionJournal $transfer
*/ */
private function updateTransferCurrency(TransactionJournal $transfer): void private function updateTransferCurrency(TransactionJournal $transfer): void

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* UpgradeDatabase.php * UpgradeDatabase.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -36,16 +36,15 @@ class StoredTransactionGroup extends Event
{ {
use SerializesModels; use SerializesModels;
public $applyRules;
/** @var TransactionGroup The group that was stored. */ /** @var TransactionGroup The group that was stored. */
public $transactionGroup; public $transactionGroup;
public $applyRules;
/** /**
* Create a new event instance. * Create a new event instance.
* *
* @param TransactionGroup $transactionGroup * @param TransactionGroup $transactionGroup
* @param bool $applyRules * @param bool $applyRules
*/ */
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true) public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true)
{ {

View File

@@ -29,6 +29,7 @@ use Illuminate\Queue\SerializesModels;
/** /**
* Class UpdatedTransactionGroup. * Class UpdatedTransactionGroup.
*
* @codeCoverageIgnore * @codeCoverageIgnore
* *
*/ */

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* GracefulNotFoundHandler.php * GracefulNotFoundHandler.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com
@@ -43,9 +44,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
* *
* @param Request $request * @param Request $request
* @param Exception $exception * @param Exception $exception
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* *
* @return mixed * @return mixed
*/ */

View File

@@ -48,9 +48,7 @@ class Handler extends ExceptionHandler
* *
* @param Request $request * @param Request $request
* @param Exception $exception * @param Exception $exception
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* *
* @return mixed * @return mixed
*/ */
@@ -112,7 +110,7 @@ class Handler extends ExceptionHandler
* *
* This is a great spot to send exceptions to Sentry etc. * This is a great spot to send exceptions to Sentry etc.
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine. * // it's five its fine.
* *
* @param Exception $exception * @param Exception $exception
* *

View File

@@ -189,7 +189,7 @@ class AccountFactory
* @param null|string $accountType * @param null|string $accountType
* *
* @return AccountType|null * @return AccountType|null
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
*/ */
protected function getAccountType(?int $accountTypeId, ?string $accountType): ?AccountType protected function getAccountType(?int $accountTypeId, ?string $accountType): ?AccountType
{ {

View File

@@ -26,7 +26,6 @@ namespace FireflyIII\Factory;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Support\Collection;
use Log; use Log;
/** /**
@@ -53,7 +52,7 @@ class BudgetFactory
* @param null|string $budgetName * @param null|string $budgetName
* *
* @return Budget|null * @return Budget|null
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
*/ */
public function find(?int $budgetId, ?string $budgetName): ?Budget public function find(?int $budgetId, ?string $budgetName): ?Budget
{ {

View File

@@ -26,7 +26,6 @@ namespace FireflyIII\Factory;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Support\Collection;
use Log; use Log;
/** /**
@@ -63,7 +62,7 @@ class CategoryFactory
* @param null|string $categoryName * @param null|string $categoryName
* *
* @return Category|null * @return Category|null
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
*/ */
public function findOrCreate(?int $categoryId, ?string $categoryName): ?Category public function findOrCreate(?int $categoryId, ?string $categoryName): ?Category
{ {

View File

@@ -53,7 +53,7 @@ class PiggyBankEventFactory
* @param PiggyBank|null $piggyBank * @param PiggyBank|null $piggyBank
* *
* @return PiggyBankEvent|null * @return PiggyBankEvent|null
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
*/ */
public function create(TransactionJournal $journal, ?PiggyBank $piggyBank): ?PiggyBankEvent public function create(TransactionJournal $journal, ?PiggyBank $piggyBank): ?PiggyBankEvent
{ {

View File

@@ -52,7 +52,7 @@ class PiggyBankFactory
* @param null|string $piggyBankName * @param null|string $piggyBankName
* *
* @return PiggyBank|null * @return PiggyBank|null
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
*/ */
public function find(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank public function find(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank
{ {

View File

@@ -79,7 +79,7 @@ class TransactionCurrencyFactory
* @param null|string $currencyCode * @param null|string $currencyCode
* *
* @return TransactionCurrency|null * @return TransactionCurrency|null
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
*/ */
public function find(?int $currencyId, ?string $currencyCode): ?TransactionCurrency public function find(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
{ {

View File

@@ -23,9 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Factory; namespace FireflyIII\Factory;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\User; use FireflyIII\User;
/** /**
@@ -60,10 +58,8 @@ class TransactionGroupFactory
$collection = $this->journalFactory->create($data); $collection = $this->journalFactory->create($data);
$title = $data['group_title'] ?? null; $title = $data['group_title'] ?? null;
$title = '' === $title ? null : $title; $title = '' === $title ? null : $title;
/** @var TransactionJournal $first */ $group = new TransactionGroup;
$first = $collection->first(); $group->user()->associate($this->user);
$group = new TransactionGroup;
$group->user()->associate($first->user);
$group->title = $title; $group->title = $title;
$group->save(); $group->save();

View File

@@ -143,6 +143,9 @@ class TransactionJournalFactory
if (null !== $journal) { if (null !== $journal) {
$collection->push($journal); $collection->push($journal);
} }
if(null === $journal) {
Log::error('The createJournal() method returned NULL. This may indicate an error.');
}
} }
return $collection; return $collection;
@@ -247,6 +250,7 @@ class TransactionJournalFactory
$destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']); $destinationAccount = $this->getAccount($type->type, 'destination', (int)$row['destination_id'], $row['destination_name']);
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
} catch (FireflyException $e) { } catch (FireflyException $e) {
Log::error('Could not validate source or destination.');
Log::error($e->getMessage()); Log::error($e->getMessage());
return null; return null;

View File

@@ -49,8 +49,6 @@ class TransactionJournalMetaFactory
* @param array $data * @param array $data
* *
* @return TransactionJournalMeta|null * @return TransactionJournalMeta|null
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function updateOrCreate(array $data): ?TransactionJournalMeta public function updateOrCreate(array $data): ?TransactionJournalMeta
{ {

View File

@@ -109,7 +109,7 @@ class ChartJsGenerator implements GeneratorInterface
* ] * ]
* ] * ]
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five. * // it's five.
* *
* @param array $data * @param array $data
* *

View File

@@ -60,7 +60,7 @@ interface GeneratorInterface
* ] * ]
* ] * ]
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five. * // it's five.
* *
* @param array $data * @param array $data
* *

View File

@@ -24,7 +24,6 @@ namespace FireflyIII\Generator\Report\Standard;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Generator\Report\ReportGeneratorInterface; use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Helpers\Report\ReportHelperInterface;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log; use Log;
use Throwable; use Throwable;
@@ -50,17 +49,11 @@ class MonthReportGenerator implements ReportGeneratorInterface
*/ */
public function generate(): string public function generate(): string
{ {
/** @var ReportHelperInterface $helper */
$helper = app(ReportHelperInterface::class);
$bills = $helper->getBillReport($this->start, $this->end, $this->accounts);
$accountIds = implode(',', $this->accounts->pluck('id')->toArray()); $accountIds = implode(',', $this->accounts->pluck('id')->toArray());
$reportType = 'default'; $reportType = 'default';
try { try {
return view( return view('reports.default.month', compact('accountIds', 'reportType'))->with('start', $this->start)->with('end', $this->end)->render();
'reports.default.month',
compact('bills', 'accountIds', 'reportType')
)->with('start', $this->start)->with('end', $this->end)->render();
} catch (Throwable $e) { } catch (Throwable $e) {
Log::error(sprintf('Cannot render reports.default.month: %s', $e->getMessage())); Log::error(sprintf('Cannot render reports.default.month: %s', $e->getMessage()));
$result = 'Could not render report view.'; $result = 'Could not render report view.';

View File

@@ -112,7 +112,7 @@ class Support
/** /**
* Summarize collection by earned and spent data. * Summarize collection by earned and spent data.
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's exactly five. * // it's exactly five.
* *
* @param array $spent * @param array $spent
* @param array $earned * @param array $earned

View File

@@ -43,9 +43,7 @@ class VersionCheckEventHandler
/** /**
* Checks with GitHub to see if there is a new version. * Checks with GitHub to see if there is a new version.
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @param RequestedVersionCheckStatus $event * @param RequestedVersionCheckStatus $event
*/ */
public function checkForUpdates(RequestedVersionCheckStatus $event): void public function checkForUpdates(RequestedVersionCheckStatus $event): void

View File

@@ -98,7 +98,7 @@ class MetaPieChart implements MetaPieChartInterface
* @param string $group * @param string $group
* *
* @return array * @return array
* @SuppressWarnings(PHPMD.CyclomaticComplexity) *
*/ */
public function generate(string $direction, string $group): array public function generate(string $direction, string $group): array
{ {
@@ -181,8 +181,6 @@ class MetaPieChart implements MetaPieChartInterface
* *
* @return array * @return array
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*
*/ */
protected function groupByFields(array $array, array $fields): array protected function groupByFields(array $array, array $fields): array
{ {

View File

@@ -1,97 +0,0 @@
<?php
/**
* Balance.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection;
/**
* Class Balance.
*
* @codeCoverageIgnore
*/
class Balance
{
/** @var BalanceHeader Header row. */
protected $balanceHeader;
/** @var Collection Collection of lines. */
protected $balanceLines;
/**
* Balance constructor.
*/
public function __construct()
{
$this->balanceLines = new Collection;
}
/**
* Add a line.
*
* @param BalanceLine $line
*/
public function addBalanceLine(BalanceLine $line): void
{
$this->balanceLines->push($line);
}
/**
* Get the header.
*
* @return BalanceHeader
*/
public function getBalanceHeader(): BalanceHeader
{
return $this->balanceHeader ?? new BalanceHeader;
}
/**
* Set the header.
*
* @param BalanceHeader $balanceHeader
*/
public function setBalanceHeader(BalanceHeader $balanceHeader): void
{
$this->balanceHeader = $balanceHeader;
}
/**
* Get all lines.
*
* @return Collection
*/
public function getBalanceLines(): Collection
{
return $this->balanceLines;
}
/**
* Set all lines.
*
* @param Collection $balanceLines
*/
public function setBalanceLines(Collection $balanceLines): void
{
$this->balanceLines = $balanceLines;
}
}

View File

@@ -1,100 +0,0 @@
<?php
/**
* BalanceEntry.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Account as AccountModel;
/**
* Class BalanceEntry.
*
* @codeCoverageIgnore
*/
class BalanceEntry
{
/** @var AccountModel The account. */
protected $account;
/** @var string The amount left. */
protected $left = '0';
/** @var string The amount spent. */
protected $spent = '0';
/**
* Account getter.
*
* @return AccountModel
*/
public function getAccount(): AccountModel
{
return $this->account;
}
/**
* Account setter.
*
* @param AccountModel $account
*/
public function setAccount(AccountModel $account): void
{
$this->account = $account;
}
/**
* Get amount left.
*
* @return string
*/
public function getLeft(): string
{
return $this->left;
}
/**
* Set amount left.
*
* @param string $left
*/
public function setLeft(string $left): void
{
$this->left = $left;
}
/**
* Get amount spent.
*
* @return string
*/
public function getSpent(): string
{
return $this->spent;
}
/**
* Set amount spent.
*
* @param string $spent
*/
public function setSpent(string $spent): void
{
$this->spent = $spent;
}
}

View File

@@ -1,65 +0,0 @@
<?php
/**
* BalanceHeader.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Account as AccountModel;
use Illuminate\Support\Collection;
/**
* Class BalanceHeader.
*
* @codeCoverageIgnore
*/
class BalanceHeader
{
/** @var Collection The accounts. */
protected $accounts;
/**
* BalanceHeader constructor.
*/
public function __construct()
{
$this->accounts = new Collection;
}
/**
* Add an account.
*
* @param AccountModel $account
*/
public function addAccount(AccountModel $account): void
{
$this->accounts->push($account);
}
/**
* Get them all.
*
* @return Collection
*/
public function getAccounts(): Collection
{
return $this->accounts;
}
}

View File

@@ -1,189 +0,0 @@
<?php
/**
* BalanceLine.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use Carbon\Carbon;
use FireflyIII\Models\Budget as BudgetModel;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Support\Collection;
/**
* Class BalanceLine.
*
* @codeCoverageIgnore
*/
class BalanceLine
{
/**
*
*/
public const ROLE_DEFAULTROLE = 1;
/**
*
*/
public const ROLE_TAGROLE = 2;
/** @var Collection */
protected $balanceEntries;
/** @var BudgetModel */
protected $budget;
/** @var BudgetLimit */
protected $budgetLimit;
/** @var int */
protected $role = self::ROLE_DEFAULTROLE;
/**
*
*/
public function __construct()
{
$this->balanceEntries = new Collection;
}
/**
* @param BalanceEntry $balanceEntry
*/
public function addBalanceEntry(BalanceEntry $balanceEntry): void
{
$this->balanceEntries->push($balanceEntry);
}
/**
* @return Collection
*/
public function getBalanceEntries(): Collection
{
return $this->balanceEntries;
}
/**
* @param Collection $balanceEntries
*/
public function setBalanceEntries(Collection $balanceEntries): void
{
$this->balanceEntries = $balanceEntries;
}
/**
* @return BudgetModel
*/
public function getBudget(): BudgetModel
{
return $this->budget ?? new BudgetModel;
}
/**
* @param BudgetModel $budget
*/
public function setBudget(BudgetModel $budget): void
{
$this->budget = $budget;
}
/**
* @return BudgetLimit
*/
public function getBudgetLimit(): BudgetLimit
{
return $this->budgetLimit;
}
/**
* @param BudgetLimit $budgetLimit
*/
public function setBudgetLimit(BudgetLimit $budgetLimit): void
{
$this->budgetLimit = $budgetLimit;
}
/**
* @return Carbon
*/
public function getEndDate(): Carbon
{
return $this->budgetLimit->end_date ?? new Carbon;
}
/**
* @return int
*/
public function getRole(): int
{
return $this->role;
}
/**
* @param int $role
*/
public function setRole(int $role): void
{
$this->role = $role;
}
/**
* @return Carbon
*/
public function getStartDate(): Carbon
{
return $this->budgetLimit->start_date ?? new Carbon;
}
/**
* @return string
*/
public function getTitle(): string
{
$title = '';
if ($this->getBudget() instanceof BudgetModel && null !== $this->getBudget()->id) {
$title = $this->getBudget()->name;
}
if ('' === $title && self::ROLE_DEFAULTROLE === $this->getRole()) {
$title = (string)trans('firefly.no_budget');
}
if ('' === $title && self::ROLE_TAGROLE === $this->getRole()) {
$title = (string)trans('firefly.coveredWithTags');
}
return $title;
}
/**
* If a BalanceLine has a budget/repetition, each BalanceEntry in this BalanceLine
* should have a "spent" value, which is the amount of money that has been spent
* on the given budget/repetition. If you subtract all those amounts from the budget/repetition's
* total amount, this is returned:.
*
* @return string
*/
public function leftOfRepetition(): string
{
$start = $this->budgetLimit->amount ?? '0';
/** @var BalanceEntry $balanceEntry */
foreach ($this->getBalanceEntries() as $balanceEntry) {
$start = bcadd($balanceEntry->getSpent(), $start);
}
return $start;
}
}

View File

@@ -1,128 +0,0 @@
<?php
/**
* Bill.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use Carbon\Carbon;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use Illuminate\Support\Collection;
use Log;
/**
* Class Bill.
*
* @codeCoverageIgnore
*/
class Bill
{
/** @var Collection The bills. */
private $bills;
/** @var Carbon End date of the collection. */
private $endDate;
/** @var Carbon Start date of the collection. */
private $startDate;
/**
* Bill constructor.
*/
public function __construct()
{
$this->bills = new Collection;
}
/**
* Add a bill line.
*
* @param BillLine $bill
*/
public function addBill(BillLine $bill): void
{
$this->bills->push($bill);
}
/**
* Filter the bills (yes how very descriptive).
*/
public function filterBills(): void
{
Log::debug('Now in filterBills()');
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$start = $this->startDate;
$end = $this->endDate;
$lines = $this->bills->filter(
function (BillLine $line) use ($repository, $start, $end) {
// next expected match?
$date = $start;
Log::debug(sprintf('Now at bill line for bill "%s"', $line->getBill()->name));
Log::debug(sprintf('Default date to use is start date: %s', $date->format('Y-m-d')));
if ($line->isHit()) {
$date = $line->getLastHitDate();
Log::debug(sprintf('Line was hit, see date: %s. Always include it.', $date->format('Y-m-d')));
return $line;
}
$expected = $repository->nextExpectedMatch($line->getBill(), $date);
Log::debug(sprintf('Next expected match is %s', $expected->format('Y-m-d')));
if ($expected <= $end && $expected >= $start) {
Log::debug('This date is inside report limits');
return $line;
}
Log::debug('This date is OUTSIDE report limits');
return false;
}
);
$this->bills = $lines;
}
/**
* Bills getter.
*
* @return Collection
*/
public function getBills(): Collection
{
return $this->bills;
}
/**
* End date setter.
*
* @param Carbon $endDate
*/
public function setEndDate(Carbon $endDate): void
{
$this->endDate = $endDate;
}
/**
* Start date setter.
*
* @param Carbon $startDate
*/
public function setStartDate(Carbon $startDate): void
{
$this->startDate = $startDate;
}
}

View File

@@ -1,270 +0,0 @@
<?php
/**
* BillLine.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use Carbon\Carbon;
use FireflyIII\Models\Bill as BillModel;
use FireflyIII\Models\TransactionCurrency;
/**
* Class BillLine.
*
* @codeCoverageIgnore
*/
class BillLine
{
/** @var string The amount */
protected $amount;
/** @var BillModel The bill. */
protected $bill;
/** @var bool Is it hit this period */
protected $hit;
/** @var string What was the max amount. */
protected $max;
/** @var string What was the min amount. */
protected $min;
/** @var TransactionCurrency The transaction currency */
private $currency;
/** @var Carbon Latest date that payment is expected. */
private $endOfPayDate;
/** @var Carbon Date of last hit */
private $lastHitDate;
/** @var Carbon Date of last payment */
private $payDate;
/** @var int Journal */
private $transactionJournalId;
/**
* BillLine constructor.
*/
public function __construct()
{
$this->lastHitDate = new Carbon;
}
/**
* Amount getter.
*
* @return string
*/
public function getAmount(): string
{
return $this->amount ?? '0';
}
/**
* Amount setter.
*
* @param string $amount
*/
public function setAmount(string $amount): void
{
$this->amount = $amount;
}
/**
* Bill getter.
*
* @return BillModel
*/
public function getBill(): BillModel
{
return $this->bill;
}
/**
* Bill setter.
*
* @param BillModel $bill
*/
public function setBill(BillModel $bill): void
{
$this->bill = $bill;
}
/**
* @return TransactionCurrency
*/
public function getCurrency(): TransactionCurrency
{
return $this->currency;
}
/**
* @param TransactionCurrency $currency
*/
public function setCurrency(TransactionCurrency $currency): void
{
$this->currency = $currency;
}
/**
* End of pay date getter.
*
* @return Carbon
*/
public function getEndOfPayDate(): Carbon
{
return $this->endOfPayDate;
}
/**
* End of pay date setter.
*
* @param Carbon $endOfPayDate
*/
public function setEndOfPayDate(Carbon $endOfPayDate): void
{
$this->endOfPayDate = $endOfPayDate;
}
/**
* Last hit date getter.
*
* @return Carbon
*/
public function getLastHitDate(): Carbon
{
return $this->lastHitDate;
}
/**
* Last hit date setter.
*
* @param Carbon $lastHitDate
*/
public function setLastHitDate(Carbon $lastHitDate): void
{
$this->lastHitDate = $lastHitDate;
}
/**
* Max getter.
*
* @return string
*/
public function getMax(): string
{
return $this->max;
}
/**
* Max setter.
*
* @param string $max
*/
public function setMax(string $max): void
{
$this->max = $max;
}
/**
* Min getter.
*
* @return string
*/
public function getMin(): string
{
return $this->min;
}
/**
* Min setter.
*
* @param string $min
*/
public function setMin(string $min): void
{
$this->min = $min;
}
/**
* Pay date getter.
*
* @return Carbon
*/
public function getPayDate(): Carbon
{
return $this->payDate;
}
/**
* Pay date setter.
*
* @param Carbon $payDate
*/
public function setPayDate(Carbon $payDate): void
{
$this->payDate = $payDate;
}
/**
* Journal ID getter.
*
* @return int
*/
public function getTransactionJournalId(): int
{
return $this->transactionJournalId ?? 0;
}
/**
* Journal ID setter.
*
* @param int $transactionJournalId
*/
public function setTransactionJournalId(int $transactionJournalId): void
{
$this->transactionJournalId = $transactionJournalId;
}
/**
* Is active.
*
* @return bool
*/
public function isActive(): bool
{
return 1 === (int)$this->bill->active;
}
/**
* Is hit.
*
* @return bool
*/
public function isHit(): bool
{
return $this->hit;
}
/**
* Set is hit.
*
* @param bool $hit
*/
public function setHit(bool $hit): void
{
$this->hit = $hit;
}
}

View File

@@ -1,97 +0,0 @@
<?php
/**
* Category.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Category as CategoryModel;
use Illuminate\Support\Collection;
/**
* Class Category.
*
* @codeCoverageIgnore
*/
class Category
{
/** @var Collection The categories */
protected $categories;
/** @var string Total amount */
protected $total = '0';
/**
* Category constructor.
*/
public function __construct()
{
$this->categories = new Collection;
}
/**
* Add a category.
*
* @param CategoryModel $category
*/
public function addCategory(CategoryModel $category): void
{
// spent is minus zero for an expense report:
if ($category->spent < 0) {
$this->categories->push($category);
$this->addTotal((string)$category->spent);
}
}
/**
* Add to the total amount.
*
* @param string $add
*/
public function addTotal(string $add): void
{
$this->total = bcadd($this->total, $add);
}
/**
* Get all categories.
*
* @return Collection
*/
public function getCategories(): Collection
{
$set = $this->categories->sortBy(
static function (CategoryModel $category) {
return $category->spent;
}
);
return $set;
}
/**
* Get the total.
*
* @return string
*/
public function getTotal(): string
{
return $this->total;
}
}

View File

@@ -46,8 +46,6 @@ use Log;
*/ */
class GroupCollector implements GroupCollectorInterface class GroupCollector implements GroupCollectorInterface
{ {
/** @var array The accounts to filter on. Asset accounts or liabilities. */
private $accountIds;
/** @var array The standard fields to select. */ /** @var array The standard fields to select. */
private $fields; private $fields;
/** @var bool Will be set to true if query result contains account information. (see function withAccountInformation). */ /** @var bool Will be set to true if query result contains account information. (see function withAccountInformation). */
@@ -86,8 +84,6 @@ class GroupCollector implements GroupCollectorInterface
$this->hasJoinedTagTables = false; $this->hasJoinedTagTables = false;
$this->total = 0; $this->total = 0;
$this->limit = 50;
$this->page = 0;
$this->fields = [ $this->fields = [
# group # group
'transaction_groups.id as transaction_group_id', 'transaction_groups.id as transaction_group_id',
@@ -157,10 +153,14 @@ class GroupCollector implements GroupCollectorInterface
$collection = $this->parseArray($result); $collection = $this->parseArray($result);
$this->total = $collection->count(); $this->total = $collection->count();
// now filter the array according to the page and the // now filter the array according to the page and the limit (if necessary)
$offset = $this->page * $this->limit; if (null !== $this->limit && null !== $this->page) {
$offset = ($this->page-1) * $this->limit;
return $collection->slice($offset, $this->limit); return $collection->slice($offset, $this->limit);
}
return $collection;
} }
@@ -182,7 +182,44 @@ class GroupCollector implements GroupCollectorInterface
} }
); );
app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds))); app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds)));
$this->accountIds = $accountIds; }
return $this;
}
/**
* Define which accounts can be part of the source and destination transactions.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setSourceAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereIn('source.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: setSourceAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* Define which accounts can be part of the source and destination transactions.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setDestinationAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereIn('destination.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: setSourceAccounts: %s', implode(', ', $accountIds)));
} }
return $this; return $this;
@@ -370,9 +407,9 @@ class GroupCollector implements GroupCollectorInterface
*/ */
public function setPage(int $page): GroupCollectorInterface public function setPage(int $page): GroupCollectorInterface
{ {
$page = 0 === $page ? 0 : $page - 1; $page = 0 === $page ? 1 : $page;
$this->page = $page; $this->page = $page;
app('log')->debug(sprintf('GroupCollector: page is now %d (is minus 1)', $page)); app('log')->debug(sprintf('GroupCollector: page is now %d', $page));
return $this; return $this;
} }
@@ -807,6 +844,7 @@ class GroupCollector implements GroupCollectorInterface
/** @var TransactionGroup $augmentedGroup */ /** @var TransactionGroup $augmentedGroup */
foreach ($collection as $augmentedGroup) { foreach ($collection as $augmentedGroup) {
$groupId = $augmentedGroup->transaction_group_id; $groupId = $augmentedGroup->transaction_group_id;
if (!isset($groups[$groupId])) { if (!isset($groups[$groupId])) {
// make new array // make new array
$parsedGroup = $this->parseAugmentedGroup($augmentedGroup); $parsedGroup = $this->parseAugmentedGroup($augmentedGroup);
@@ -837,7 +875,9 @@ class GroupCollector implements GroupCollectorInterface
$groups[$groupId]['transactions'][$journalId] = $this->parseAugmentedGroup($augmentedGroup); $groups[$groupId]['transactions'][$journalId] = $this->parseAugmentedGroup($augmentedGroup);
} }
} }
$groups = $this->parseSums($groups); $groups = $this->parseSums($groups);
return new Collection($groups); return new Collection($groups);
@@ -1010,4 +1050,42 @@ class GroupCollector implements GroupCollectorInterface
->orderBy('transaction_journals.description', 'DESC') ->orderBy('transaction_journals.description', 'DESC')
->orderBy('source.amount', 'DESC'); ->orderBy('source.amount', 'DESC');
} }
/**
* These accounts must not be source accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function excludeSourceAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereNotIn('source.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: excludeSourceAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
/**
* These accounts must not be destination accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function excludeDestinationAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->whereNotIn('destination.account_id', $accountIds);
app('log')->debug(sprintf('GroupCollector: excludeDestinationAccounts: %s', implode(', ', $accountIds)));
}
return $this;
}
} }

View File

@@ -46,6 +46,41 @@ interface GroupCollectorInterface
*/ */
public function getExtractedJournals(): array; public function getExtractedJournals(): array;
/**
* Set source accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setSourceAccounts(Collection $accounts): GroupCollectorInterface;
/**
* These accounts must not be source accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function excludeSourceAccounts(Collection $accounts): GroupCollectorInterface;
/**
* Exclude destination accounts.
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function excludeDestinationAccounts(Collection $accounts): GroupCollectorInterface;
/**
* Set destination accounts.
*
* @param Collection $accounts
*
* @return GroupCollectorInterface
*/
public function setDestinationAccounts(Collection $accounts): GroupCollectorInterface;
/** /**
* Return the sum of all journals. * Return the sum of all journals.
* *

View File

@@ -23,11 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Report; namespace FireflyIII\Helpers\Report;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Balance; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Collection\BalanceEntry; use FireflyIII\Models\Account;
use FireflyIII\Helpers\Collection\BalanceHeader; use FireflyIII\Models\Budget;
use FireflyIII\Helpers\Collection\BalanceLine; use FireflyIII\Models\TransactionType;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log; use Log;
@@ -44,8 +43,6 @@ class BalanceReportHelper implements BalanceReportHelperInterface
/** /**
* ReportHelper constructor. * ReportHelper constructor.
*
*
* @param BudgetRepositoryInterface $budgetRepository * @param BudgetRepositoryInterface $budgetRepository
*/ */
public function __construct(BudgetRepositoryInterface $budgetRepository) public function __construct(BudgetRepositoryInterface $budgetRepository)
@@ -65,126 +62,78 @@ class BalanceReportHelper implements BalanceReportHelperInterface
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
* @return Balance * @return array
*/ */
public function getBalanceReport(Collection $accounts, Carbon $start, Carbon $end): Balance public function getBalanceReport(Collection $accounts, Carbon $start, Carbon $end): array
{ {
Log::debug('Start of balance report'); Log::debug('Start of balance report');
$balance = new Balance; $report = [
$header = new BalanceHeader; 'budgets' => [],
$budgetLimits = $this->budgetRepository->getAllBudgetLimits($start, $end); 'accounts' => [],
];
/** @var Account $account */
foreach ($accounts as $account) { foreach ($accounts as $account) {
Log::debug(sprintf('Add account %s to headers.', $account->name)); $report['accounts'][$account->id] = [
$header->addAccount($account); 'id' => $account->id,
'name' => $account->name,
'iban' => $account->iban,
'sum' => '0',
];
} }
/** @var BudgetLimit $budgetLimit */ $budgets = $this->budgetRepository->getBudgets();
foreach ($budgetLimits as $budgetLimit) {
if (null !== $budgetLimit->budget) { /** @var Budget $budget */
$line = $this->createBalanceLine($budgetLimit, $accounts); foreach ($budgets as $budget) {
$balance->addBalanceLine($line); $budgetId = $budget->id;
$report['budgets'][$budgetId] = [
'budget_id' => $budgetId,
'budget_name' => $budget->name,
'spent' => [], // per account
'sums' => [], // per currency
];
$spent = [];
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$journals = $collector->setRange($start, $end)->setSourceAccounts($accounts)->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget)
->getExtractedJournals();
/** @var array $journal */
foreach ($journals as $journal) {
$sourceAccount = $journal['source_account_id'];
$currencyId = $journal['currency_id'];
$spent[$sourceAccount] = $spent[$sourceAccount] ?? [
'source_account_id' => $sourceAccount,
'currency_id' => $journal['currency_id'],
'currency_code' => $journal['currency_code'],
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_decimal_places' => $journal['currency_decimal_places'],
'spent' => '0',
];
$spent[$sourceAccount]['spent'] = bcadd($spent[$sourceAccount]['spent'], $journal['amount']);
// also fix sum:
$report['sums'][$budgetId][$currencyId] = $report['sums'][$budgetId][$currencyId] ?? [
'sum' => '0',
'currency_id' => $journal['currency_id'],
'currency_code' => $journal['currency_code'],
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
$report['sums'][$budgetId][$currencyId]['sum'] = bcadd($report['sums'][$budgetId][$currencyId]['sum'], $journal['amount']);
$report['accounts'][$sourceAccount]['sum'] = bcadd($report['accounts'][$sourceAccount]['sum'], $journal['amount']);
// add currency info for account sum
$report['accounts'][$sourceAccount]['currency_id'] = $journal['currency_id'];
$report['accounts'][$sourceAccount]['currency_code'] = $journal['currency_code'];
$report['accounts'][$sourceAccount]['currency_name'] = $journal['currency_name'];
$report['accounts'][$sourceAccount]['currency_symbol'] = $journal['currency_symbol'];
$report['accounts'][$sourceAccount]['currency_decimal_places'] = $journal['currency_decimal_places'];
} }
$report['budgets'][$budgetId]['spent'] = $spent;
// get transactions in budget
} }
$noBudgetLine = $this->createNoBudgetLine($accounts, $start, $end); return $report;
$balance->addBalanceLine($noBudgetLine);
$balance->setBalanceHeader($header);
Log::debug('Clear unused budgets.');
// remove budgets without expenses from balance lines:
$balance = $this->removeUnusedBudgets($balance);
Log::debug('Return report.');
return $balance;
}
/**
* Create one balance line.
*
* @param BudgetLimit $budgetLimit
* @param Collection $accounts
*
* @return BalanceLine
*/
private function createBalanceLine(BudgetLimit $budgetLimit, Collection $accounts): BalanceLine
{
$line = new BalanceLine;
$line->setBudget($budgetLimit->budget);
$line->setBudgetLimit($budgetLimit);
// loop accounts:
foreach ($accounts as $account) {
$balanceEntry = new BalanceEntry;
$balanceEntry->setAccount($account);
$spent = $this->budgetRepository->spentInPeriod(
new Collection([$budgetLimit->budget]),
new Collection([$account]),
$budgetLimit->start_date,
$budgetLimit->end_date
);
$balanceEntry->setSpent($spent);
$line->addBalanceEntry($balanceEntry);
}
return $line;
}
/**
* Create a line for transactions without a budget.
*
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return BalanceLine
*/
private function createNoBudgetLine(Collection $accounts, Carbon $start, Carbon $end): BalanceLine
{
$empty = new BalanceLine;
foreach ($accounts as $account) {
$spent = $this->budgetRepository->spentInPeriodWoBudget(new Collection([$account]), $start, $end);
// budget
$budgetEntry = new BalanceEntry;
$budgetEntry->setAccount($account);
$budgetEntry->setSpent($spent);
$empty->addBalanceEntry($budgetEntry);
}
return $empty;
}
/**
* Remove unused budgets from the report.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @param Balance $balance
*
* @return Balance
*/
private function removeUnusedBudgets(Balance $balance): Balance
{
$set = $balance->getBalanceLines();
$newSet = new Collection;
/** @var BalanceLine $entry */
foreach ($set as $entry) {
if (null !== $entry->getBudget()->id) {
$sum = '0';
/** @var BalanceEntry $balanceEntry */
foreach ($entry->getBalanceEntries() as $balanceEntry) {
$sum = bcadd($sum, $balanceEntry->getSpent());
}
if (bccomp($sum, '0') === -1) {
$newSet->push($entry);
}
continue;
}
$newSet->push($entry);
}
$balance->setBalanceLines($newSet);
return $balance;
} }
} }

View File

@@ -38,7 +38,7 @@ interface BalanceReportHelperInterface
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* *
* @return Balance * @return array
*/ */
public function getBalanceReport(Collection $accounts, Carbon $start, Carbon $end): Balance; public function getBalanceReport(Collection $accounts, Carbon $start, Carbon $end): array;
} }

View File

@@ -57,8 +57,8 @@ class BudgetReportHelper implements BudgetReportHelperInterface
/** /**
* Get the full budget report. * Get the full budget report.
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity) * TODO one big method is very complex.
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) *
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* @param Collection $accounts * @param Collection $accounts
@@ -68,104 +68,142 @@ class BudgetReportHelper implements BudgetReportHelperInterface
public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): array public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): array
{ {
$set = $this->repository->getBudgets(); $set = $this->repository->getBudgets();
$array = []; $array = [
'budgets' => [],
'sums' => [],
];
/** @var Budget $budget */ /** @var Budget $budget */
foreach ($set as $budget) { foreach ($set as $budget) {
$entry = [
'budget_id' => $budget->id,
'budget_name' => $budget->name,
'no_budget' => false,
'rows' => [],
];
// get multi currency expenses first:
$budgetLimits = $this->repository->getBudgetLimits($budget, $start, $end); $budgetLimits = $this->repository->getBudgetLimits($budget, $start, $end);
if (0 === $budgetLimits->count()) { // no budget limit(s) for this budget $expenses = $this->repository->spentInPeriodMc(new Collection([$budget]), $accounts, $start, $end);
$spent = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end); // spent for budget in time range if (0 === count($expenses)) {
if (bccomp($spent, '0') === -1) { // list the budget limits, basic amounts.
$line = [ /** @var BudgetLimit $limit */
'type' => 'budget', foreach ($budgetLimits as $limit) {
'id' => $budget->id, $row = [
'name' => $budget->name, 'limit_id' => $limit->id,
'budgeted' => '0', 'start_date' => $limit->start_date,
'spent' => $spent, 'end_date' => $limit->end_date,
'left' => '0', 'budgeted' => $limit->amount,
'overspent' => '0', 'spent' => '0',
'left' => $limit->amount,
'overspent' => null,
'currency_id' => $limit->transactionCurrency->id,
'currency_code' => $limit->transactionCurrency->code,
'currency_name' => $limit->transactionCurrency->name,
'currency_symbol' => $limit->transactionCurrency->symbol,
'currency_decimal_places' => $limit->transactionCurrency->decimal_places,
]; ];
$array[] = $line;
$entry['rows'][] = $row;
} }
continue;
} }
/** @var BudgetLimit $budgetLimit */ foreach ($expenses as $expense) {
foreach ($budgetLimits as $budgetLimit) { // one or more repetitions for budget $limit = $this->budgetLimitInCurrency($expense['currency_id'], $budgetLimits);
$data = $this->calculateExpenses($budget, $budgetLimit, $accounts); $row = [
$line = [ 'limit_id' => null,
'type' => 'budget-line', 'start_date' => null,
'start' => $budgetLimit->start_date, 'end_date' => null,
'end' => $budgetLimit->end_date, 'budgeted' => null,
'limit' => $budgetLimit->id, 'spent' => $expense['amount'],
'id' => $budget->id, 'left' => null,
'name' => $budget->name, 'overspent' => null,
'currency_id' => $expense['currency_id'],
'budgeted' => (string)$budgetLimit->amount, 'currency_code' => $expense['currency_name'],
'spent' => $data['expenses'], 'currency_name' => $expense['currency_name'],
'left' => $data['left'], 'currency_symbol' => $expense['currency_symbol'],
'overspent' => $data['overspent'], 'currency_decimal_places' => $expense['currency_decimal_places'],
]; ];
$array[] = $line; if (null !== $limit) {
// yes
$row['start_date'] = $limit->start_date;
$row['end_date'] = $limit->end_date;
$row['budgeted'] = $limit->amount;
$row['limit_id'] = $limit->id;
// less than zero? Set to 0.0
$row['left'] = -1 === bccomp(bcadd($limit->amount, $row['spent']), '0') ? '0' : bcadd($limit->amount, $row['spent']);
// spent > budgeted? then sum, otherwise other sum
$row['overspent'] = 1 === bccomp($row['spent'], $row['budgeted']) ? bcadd($row['spent'], $row['budgeted']) : '0';
}
$entry['rows'][] = $row;
} }
$array['budgets'][] = $entry;
} }
$noBudget = $this->repository->spentInPeriodWoBudget($accounts, $start, $end); // stuff outside of budgets $noBudget = $this->repository->spentInPeriodWoBudgetMc($accounts, $start, $end);
$line = [ $noBudgetEntry = [
'type' => 'no-budget', 'budget_id' => null,
'budgeted' => '0', 'budget_name' => null,
'spent' => $noBudget, 'no_budget' => true,
'left' => '0', 'rows' => [],
'overspent' => '0',
]; ];
$array[] = $line; foreach ($noBudget as $row) {
$noBudgetEntry['rows'][] = [
'limit_id' => null,
'start_date' => null,
'end_date' => null,
'budgeted' => null,
'spent' => $row['amount'],
'left' => null,
'overspent' => null,
'currency_id' => $row['currency_id'],
'currency_code' => $row['currency_code'],
'currency_name' => $row['currency_name'],
'currency_symbol' => $row['currency_symbol'],
'currency_decimal_places' => $row['currency_decimal_places'],
];
}
$array['budgets'][] = $noBudgetEntry;
return $array; // fill sums:
} /** @var array $budget */
foreach ($array['budgets'] as $budget) {
/** /** @var array $row */
* Get all budgets and the expenses in these budgets. foreach ($budget['rows'] as $row) {
* $currencyId = $row['currency_id'];
* @param Carbon $start $array['sums'][$currencyId] = $array['sums'][$currencyId] ?? [
* @param Carbon $end 'currency_id' => $row['currency_id'],
* @param Collection $accounts 'currency_code' => $row['currency_code'],
* 'currency_name' => $row['currency_name'],
* @return Collection 'currency_symbol' => $row['currency_symbol'],
*/ 'currency_decimal_places' => $row['currency_decimal_places'],
public function getBudgetsWithExpenses(Carbon $start, Carbon $end, Collection $accounts): Collection 'budgeted' => '0',
{ 'spent' => '0',
/** @var BudgetRepositoryInterface $repository */ 'left' => '0',
$repository = app(BudgetRepositoryInterface::class); 'overspent' => '0',
$budgets = $repository->getActiveBudgets(); ];
$array['sums'][$currencyId]['budgeted'] = bcadd($array['sums'][$currencyId]['budgeted'], $row['budgeted'] ?? '0');
$set = new Collection; $array['sums'][$currencyId]['spent'] = bcadd($array['sums'][$currencyId]['spent'], $row['spent'] ?? '0');
/** @var Budget $budget */ $array['sums'][$currencyId]['left'] = bcadd($array['sums'][$currencyId]['left'], $row['left'] ?? '0');
foreach ($budgets as $budget) { $array['sums'][$currencyId]['overspent'] = bcadd($array['sums'][$currencyId]['overspent'], $row['overspent'] ?? '0');
$total = $repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end);
if (bccomp($total, '0') === -1) {
$set->push($budget);
} }
} }
return $array;
return $set;
} }
/** /**
* Calculate the expenses for a budget. * Returns from the collection the budget limit with the indicated currency ID
* *
* @param Budget $budget * @param int $currencyId
* @param BudgetLimit $budgetLimit * @param Collection $budgetLimits
* @param Collection $accounts
* *
* @return array * @return BudgetLimit|null
*/ */
private function calculateExpenses(Budget $budget, BudgetLimit $budgetLimit, Collection $accounts): array private function budgetLimitInCurrency(int $currencyId, Collection $budgetLimits): ?BudgetLimit
{ {
$array = []; return $budgetLimits->first(
$expenses = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $budgetLimit->start_date, $budgetLimit->end_date); static function (BudgetLimit $limit) use ($currencyId) {
$array['left'] = 1 === bccomp(bcadd($budgetLimit->amount, $expenses), '0') ? bcadd($budgetLimit->amount, $expenses) : '0'; return $limit->transaction_currency_id === $currencyId;
$array['spent'] = 1 === bccomp(bcadd($budgetLimit->amount, $expenses), '0') ? $expenses : '0'; }
$array['overspent'] = 1 === bccomp(bcadd($budgetLimit->amount, $expenses), '0') ? '0' : bcadd($expenses, $budgetLimit->amount); );
$array['expenses'] = $expenses;
return $array;
} }
} }

View File

@@ -40,15 +40,4 @@ interface BudgetReportHelperInterface
* @return array * @return array
*/ */
public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): array; public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): array;
/**
* Get budgets and the expenses in each budget.
*
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return Collection
*/
public function getBudgetsWithExpenses(Carbon $start, Carbon $end, Collection $accounts): Collection;
} }

View File

@@ -26,8 +26,8 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log; use Log;
@@ -98,11 +98,24 @@ class PopupReport implements PopupReportInterface
*/ */
public function byBudget(Budget $budget, array $attributes): array public function byBudget(Budget $budget, array $attributes): array
{ {
// filter by currency, if set.
$currencyId = $attributes['currencyId'] ?? null;
$currency = null;
if (null !== $currencyId) {
/** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int)$currencyId);
}
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($attributes['accounts'])->setRange($attributes['startDate'], $attributes['endDate']); $collector->setAccounts($attributes['accounts'])->setRange($attributes['startDate'], $attributes['endDate']);
if (null !== $currency) {
$collector->setCurrency($currency);
}
if (null === $budget->id) { if (null === $budget->id) {
$collector->setTypes([TransactionType::WITHDRAWAL])->withoutBudget(); $collector->setTypes([TransactionType::WITHDRAWAL])->withoutBudget();
} }
@@ -123,12 +136,25 @@ class PopupReport implements PopupReportInterface
*/ */
public function byCategory(Category $category, array $attributes): array public function byCategory(Category $category, array $attributes): array
{ {
// filter by currency, if set.
$currencyId = $attributes['currencyId'] ?? null;
$currency = null;
if (null !== $currencyId) {
/** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int)$currencyId);
}
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($attributes['accounts'])->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) $collector->setAccounts($attributes['accounts'])
->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::DEPOSIT])
->setRange($attributes['startDate'], $attributes['endDate'])->withAccountInformation() ->setRange($attributes['startDate'], $attributes['endDate'])->withAccountInformation()
->setCategory($category); ->setCategory($category);
if (null !== $currency) {
$collector->setCurrency($currency);
}
return $collector->getExtractedJournals(); return $collector->getExtractedJournals();
} }
@@ -143,6 +169,15 @@ class PopupReport implements PopupReportInterface
*/ */
public function byExpenses(Account $account, array $attributes): array public function byExpenses(Account $account, array $attributes): array
{ {
// filter by currency, if set.
$currencyId = $attributes['currencyId'] ?? null;
$currency = null;
if (null !== $currencyId) {
/** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int)$currencyId);
}
/** @var JournalRepositoryInterface $repository */ /** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class); $repository = app(JournalRepositoryInterface::class);
$repository->setUser($account->user); $repository->setUser($account->user);
@@ -150,20 +185,15 @@ class PopupReport implements PopupReportInterface
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setRange($attributes['startDate'], $attributes['endDate']) $collector->setAccounts(new Collection([$account]))
->setRange($attributes['startDate'], $attributes['endDate'])
->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]); ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]);
$journals = $collector->getExtractedJournals();
$report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report
$filtered = []; if (null !== $currency) {
// TODO not sure if filter is necessary. $collector->setCurrency($currency);
/** @var array $journal */
foreach ($journals as $journal) {
if (in_array($journal['source_account_id'], $report, true)) {
$filtered[] = $journal;
}
} }
return $filtered;
return $collector->getExtractedJournals();
} }
/** /**
@@ -179,24 +209,14 @@ class PopupReport implements PopupReportInterface
/** @var JournalRepositoryInterface $repository */ /** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class); $repository = app(JournalRepositoryInterface::class);
$repository->setUser($account->user); $repository->setUser($account->user);
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setRange($attributes['startDate'], $attributes['endDate']) $collector
->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) ->setSourceAccounts(new Collection([$account]))
->setDestinationAccounts($attributes['accounts'])
->setRange($attributes['startDate'], $attributes['endDate'])
->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
->withAccountInformation(); ->withAccountInformation();
$journals = $collector->getExtractedJournals(); return $collector->getExtractedJournals();
$report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report
// filter the set so the destinations outside of $attributes['accounts'] are not included.
// TODO not sure if filter is necessary.
$filtered = [];
/** @var array $journal */
foreach ($journals as $journal) {
if (in_array($journal['destination_account_id'], $report, true)) {
$filtered[] = $journal;
}
}
return $filtered;
} }
} }

View File

@@ -23,8 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Report; namespace FireflyIII\Helpers\Report;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Helpers\Collection\Bill as BillCollection;
use FireflyIII\Helpers\Collection\BillLine;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Fiscal\FiscalHelperInterface; use FireflyIII\Helpers\Fiscal\FiscalHelperInterface;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
@@ -45,8 +43,6 @@ class ReportHelper implements ReportHelperInterface
/** /**
* ReportHelper constructor. * ReportHelper constructor.
*
*
* @param BudgetRepositoryInterface $budgetRepository * @param BudgetRepositoryInterface $budgetRepository
*/ */
public function __construct(BudgetRepositoryInterface $budgetRepository) public function __construct(BudgetRepositoryInterface $budgetRepository)
@@ -66,64 +62,57 @@ class ReportHelper implements ReportHelperInterface
* *
* Excludes bills which have not had a payment on the mentioned accounts. * Excludes bills which have not had a payment on the mentioned accounts.
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
* @param Collection $accounts * @param Collection $accounts
* *
* @return BillCollection * @return array
*/ */
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts): BillCollection public function getBillReport(Collection $accounts, Carbon $start, Carbon $end): array
{ {
/** @var BillRepositoryInterface $repository */ /** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class); $repository = app(BillRepositoryInterface::class);
$bills = $repository->getBillsForAccounts($accounts); $bills = $repository->getBillsForAccounts($accounts);
$report = [
$collection = new BillCollection; 'bills' => [],
$collection->setStartDate($start); ];
$collection->setEndDate($end);
/** @var Bill $bill */ /** @var Bill $bill */
foreach ($bills as $bill) { foreach ($bills as $bill) {
$expectedDates = $repository->getPayDatesInRange($bill, $start, $end); $expectedDates = $repository->getPayDatesInRange($bill, $start, $end);
foreach ($expectedDates as $payDate) { $billId = $bill->id;
$endOfPayPeriod = app('navigation')->endOfX($payDate, $bill->repeat_freq, null); $currency = $bill->transactionCurrency;
$current = [
'id' => $bill->id,
'name' => $bill->name,
'active' => $bill->active,
'amount_min' => $bill->amount_min,
'amount_max' => $bill->amount_max,
'currency_id' => $bill->transaction_currency_id,
'currency_code' => $currency->code,
'currency_name' => $currency->name,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
'expected_dates' => $expectedDates->toArray(),
'paid_moments' => [],
];
/** @var Carbon $start */
foreach ($expectedDates as $expectedStart) {
$expectedEnd = app('navigation')->endOfX($expectedStart, $bill->repeat_freq, null);
// is paid in this period maybe?
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class); $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($payDate, $endOfPayPeriod)->setBill($bill); $collector->setAccounts($accounts)->setRange($expectedStart, $expectedEnd)->setBill($bill);
$journals = $collector->getExtractedJournals(); $current['paid_moments'][] = $collector->getExtractedJournals();
$billLine = new BillLine;
$billLine->setBill($bill);
$billLine->setCurrency($bill->transactionCurrency);
$billLine->setPayDate($payDate);
$billLine->setEndOfPayDate($endOfPayPeriod);
$billLine->setMin((string)$bill->amount_min);
$billLine->setMax((string)$bill->amount_max);
$billLine->setHit(false);
/** @var array $first */
$first = null;
if (count($journals) > 0) {
$first = reset($journals);
}
if (null !== $first) {
$billLine->setTransactionJournalId($first['transaction_journal_id']);
$billLine->setAmount($first['amount']);
$billLine->setLastHitDate($first['date']);
$billLine->setHit(true);
}
if ($billLine->isActive() || $billLine->isHit()) {
$collection->addBill($billLine);
}
} }
}
$collection->filterBills();
return $collection; // append to report:
$report['bills'][$billId] = $current;
}
return $report;
} }
/** /**

View File

@@ -41,9 +41,9 @@ interface ReportHelperInterface
* @param Carbon $end * @param Carbon $end
* @param Collection $accounts * @param Collection $accounts
* *
* @return BillCollection * @return array
*/ */
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts): BillCollection; public function getBillReport(Collection $accounts, Carbon $start, Carbon $end): array;
/** /**
* Generate a list of months. * Generate a list of months.

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Http\Controllers\Account;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Controllers\UserNavigation;
use Illuminate\Http\Request; use Illuminate\Http\Request;
/** /**
@@ -34,6 +35,8 @@ use Illuminate\Http\Request;
*/ */
class DeleteController extends Controller class DeleteController extends Controller
{ {
use UserNavigation;
/** @var AccountRepositoryInterface The account repository */ /** @var AccountRepositoryInterface The account repository */
private $repository; private $repository;
@@ -67,6 +70,10 @@ class DeleteController extends Controller
*/ */
public function delete(Account $account) public function delete(Account $account)
{ {
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
}
$typeName = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type)); $typeName = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
$subTitle = (string)trans(sprintf('firefly.delete_%s_account', $typeName), ['name' => $account->name]); $subTitle = (string)trans(sprintf('firefly.delete_%s_account', $typeName), ['name' => $account->name]);
$accountList = app('expandedform')->makeSelectListWithEmpty($this->repository->getAccountsByType([$account->accountType->type])); $accountList = app('expandedform')->makeSelectListWithEmpty($this->repository->getAccountsByType([$account->accountType->type]));
@@ -89,6 +96,10 @@ class DeleteController extends Controller
*/ */
public function destroy(Request $request, Account $account) public function destroy(Request $request, Account $account)
{ {
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
}
$type = $account->accountType->type; $type = $account->accountType->type;
$typeName = config(sprintf('firefly.shortNamesByFullName.%s', $type)); $typeName = config(sprintf('firefly.shortNamesByFullName.%s', $type));
$name = $account->name; $name = $account->name;

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Controllers\ModelInformation; use FireflyIII\Support\Http\Controllers\ModelInformation;
use FireflyIII\Support\Http\Controllers\UserNavigation;
use Illuminate\Http\Request; use Illuminate\Http\Request;
/** /**
@@ -38,7 +39,7 @@ use Illuminate\Http\Request;
*/ */
class EditController extends Controller class EditController extends Controller
{ {
use ModelInformation; use ModelInformation, UserNavigation;
/** @var CurrencyRepositoryInterface The currency repository */ /** @var CurrencyRepositoryInterface The currency repository */
private $currencyRepos; private $currencyRepos;
/** @var AccountRepositoryInterface The account repository */ /** @var AccountRepositoryInterface The account repository */
@@ -74,11 +75,13 @@ class EditController extends Controller
* *
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function edit(Request $request, Account $account, AccountRepositoryInterface $repository) public function edit(Request $request, Account $account, AccountRepositoryInterface $repository)
{ {
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
}
$objectType = config('firefly.shortNamesByFullName')[$account->accountType->type]; $objectType = config('firefly.shortNamesByFullName')[$account->accountType->type];
$subTitle = (string)trans(sprintf('firefly.edit_%s_account', $objectType), ['name' => $account->name]); $subTitle = (string)trans(sprintf('firefly.edit_%s_account', $objectType), ['name' => $account->name]);
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType)); $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
@@ -144,6 +147,10 @@ class EditController extends Controller
*/ */
public function update(AccountFormRequest $request, Account $account) public function update(AccountFormRequest $request, Account $account)
{ {
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
}
$data = $request->getAccountData(); $data = $request->getAccountData();
$this->repository->update($account, $data); $this->repository->update($account, $data);

View File

@@ -86,6 +86,10 @@ class ReconcileController extends Controller
*/ */
public function reconcile(Account $account, Carbon $start = null, Carbon $end = null) public function reconcile(Account $account, Carbon $start = null, Carbon $end = null)
{ {
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
}
if (AccountType::ASSET !== $account->accountType->type) { if (AccountType::ASSET !== $account->accountType->type) {
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
session()->flash('error', (string)trans('firefly.must_be_asset_account')); session()->flash('error', (string)trans('firefly.must_be_asset_account'));
@@ -146,6 +150,10 @@ class ReconcileController extends Controller
*/ */
public function submit(ReconciliationStoreRequest $request, Account $account, Carbon $start, Carbon $end) public function submit(ReconciliationStoreRequest $request, Account $account, Carbon $start, Carbon $end)
{ {
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
}
Log::debug('In ReconcileController::submit()'); Log::debug('In ReconcileController::submit()');
$data = $request->getAll(); $data = $request->getAll();
@@ -178,6 +186,10 @@ class ReconcileController extends Controller
*/ */
private function createReconciliation(Account $account, Carbon $start, Carbon $end, string $difference): string private function createReconciliation(Account $account, Carbon $start, Carbon $end, string $difference): string
{ {
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
}
$reconciliation = $this->accountRepos->getReconciliation($account); $reconciliation = $this->accountRepos->getReconciliation($account);
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency(); $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
$source = $reconciliation; $source = $reconciliation;

View File

@@ -28,7 +28,6 @@ use Exception;
use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Controllers\PeriodOverview; use FireflyIII\Support\Http\Controllers\PeriodOverview;
@@ -40,7 +39,7 @@ use View;
/** /**
* Class ShowController * Class ShowController
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class ShowController extends Controller class ShowController extends Controller
{ {
@@ -73,7 +72,7 @@ class ShowController extends Controller
); );
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Show an account. * Show an account.
* *
@@ -87,8 +86,8 @@ class ShowController extends Controller
*/ */
public function show(Request $request, Account $account, Carbon $start = null, Carbon $end = null) public function show(Request $request, Account $account, Carbon $start = null, Carbon $end = null)
{ {
if (in_array($account->accountType->type, [AccountType::INITIAL_BALANCE, AccountType::RECONCILIATION], true)) { if (!$this->isEditableAccount($account)) {
return $this->redirectToOriginalAccount($account); // @codeCoverageIgnore return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
} }
/** @var Carbon $start */ /** @var Carbon $start */
@@ -139,15 +138,14 @@ class ShowController extends Controller
* @param Request $request * @param Request $request
* @param Account $account * @param Account $account
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
*
*
* @throws Exception * @throws Exception
*/ */
public function showAll(Request $request, Account $account) public function showAll(Request $request, Account $account)
{ {
if (AccountType::INITIAL_BALANCE === $account->accountType->type) { if (!$this->isEditableAccount($account)) {
return $this->redirectToOriginalAccount($account); // @codeCoverageIgnore return $this->redirectAccountToAccount($account); // @codeCoverageIgnore
} }
$isLiability = $this->repository->isLiability($account); $isLiability = $this->repository->isLiability($account);
$objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type)); $objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
$end = new Carbon; $end = new Carbon;

View File

@@ -18,7 +18,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>. * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
declare(strict_types=1); declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth; namespace FireflyIII\Http\Controllers\Auth;
@@ -26,8 +25,6 @@ namespace FireflyIII\Http\Controllers\Auth;
use Adldap; use Adldap;
use DB; use DB;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\User;
use Illuminate\Cookie\CookieJar;
use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Log; use Log;
@@ -85,61 +82,35 @@ class LoginController extends Controller
} }
$this->validateLogin($request); $this->validateLogin($request);
/** Copied directly from AuthenticatesUsers, but with logging added: */
// If the class is using the ThrottlesLogins trait, we can automatically throttle // If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and // the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application. // the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) { if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) {
Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get('email'))); Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get('email')));
$this->fireLockoutEvent($request); $this->fireLockoutEvent($request);
/** @noinspection PhpInconsistentReturnPointsInspection */
/** @noinspection PhpVoidFunctionResultUsedInspection */
return $this->sendLockoutResponse($request); return $this->sendLockoutResponse($request);
} }
/** Copied directly from AuthenticatesUsers, but with logging added: */
if ($this->attemptLogin($request)) { if ($this->attemptLogin($request)) {
Log::channel('audit')->info(sprintf('User "%s" has been logged in.', $request->get('email'))); Log::channel('audit')->info(sprintf('User "%s" has been logged in.', $request->get('email')));
// user is logged in. Save in session if the user requested session to be remembered:
$request->session()->put('remember_login', $request->filled('remember'));
Log::debug(sprintf('Redirect after login is %s.', $this->redirectPath())); Log::debug(sprintf('Redirect after login is %s.', $this->redirectPath()));
/** @noinspection PhpInconsistentReturnPointsInspection */ return $this->sendLoginResponse($request);
/** @noinspection PhpVoidFunctionResultUsedInspection */
$response = $this->sendLoginResponse($request);
Log::debug(sprintf('Response Location header: %s', $response->headers->get('location')));
return $response;
} }
/** Copied directly from AuthenticatesUsers, but with logging added: */
// If the login attempt was unsuccessful we will increment the number of attempts // If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this // to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out. // user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request); $this->incrementLoginAttempts($request);
Log::channel('audit')->info(sprintf('Login attempt for user "%s" failed.', $request->get('email'))); Log::channel('audit')->info(sprintf('Login attempt for user "%s" failed.', $request->get('email')));
/** @noinspection PhpInconsistentReturnPointsInspection */
/** @noinspection PhpVoidFunctionResultUsedInspection */
return $this->sendFailedLoginResponse($request); return $this->sendFailedLoginResponse($request);
} }
/**
* Log the user out of the application.
*
* @param Request $request
* @param CookieJar $cookieJar
*
* @return $this|\Illuminate\Http\RedirectResponse
*/
public function logout(Request $request, CookieJar $cookieJar)
{
$this->guard()->logout();
$request->session()->invalidate();
$cookie = $cookieJar->forget('twoFactorAuthenticated');
return redirect('/')->withCookie($cookie);
}
/** /**
* Show the application's login form. * Show the application's login form.
* *
@@ -151,20 +122,16 @@ class LoginController extends Controller
{ {
$count = DB::table('users')->count(); $count = DB::table('users')->count();
$loginProvider = config('firefly.login_provider'); $loginProvider = config('firefly.login_provider');
$pageTitle = (string)trans('firefly.login_page_title'); $title = (string)trans('firefly.login_page_title');
if (0 === $count && 'eloquent' === $loginProvider) { if (0 === $count && 'eloquent' === $loginProvider) {
return redirect(route('register')); // @codeCoverageIgnore return redirect(route('register')); // @codeCoverageIgnore
} }
// forget 2fa session thing.
$request->session()->forget('twoFactorAuthenticated');
// is allowed to? // is allowed to?
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data; $singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$userCount = User::count();
$allowRegistration = true; $allowRegistration = true;
$allowReset = true; $allowReset = true;
if (true === $singleUserMode && $userCount > 0) { if (true === $singleUserMode && $count > 0) {
$allowRegistration = false; $allowRegistration = false;
} }
@@ -177,6 +144,6 @@ class LoginController extends Controller
$email = $request->old('email'); $email = $request->old('email');
$remember = $request->old('remember'); $remember = $request->old('remember');
return view('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'pageTitle')); return view('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title'));
} }
} }

View File

@@ -43,7 +43,7 @@ use Symfony\Component\HttpFoundation\ParameterBag;
/** /**
* Class BillController. * Class BillController.
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class BillController extends Controller class BillController extends Controller
{ {
@@ -339,8 +339,6 @@ class BillController extends Controller
* *
* @return RedirectResponse * @return RedirectResponse
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function store(BillFormRequest $request): RedirectResponse public function store(BillFormRequest $request): RedirectResponse
{ {

View File

@@ -25,18 +25,15 @@ namespace FireflyIII\Http\Controllers\Budget;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\BudgetIncomeRequest; use FireflyIII\Http\Requests\BudgetIncomeRequest;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Support\Http\Controllers\DateCalculation; use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse; use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log;
/** /**
* Class AmountController * Class AmountController
@@ -75,8 +72,6 @@ class AmountController extends Controller
* @param Budget $budget * @param Budget $budget
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function amount(Request $request, Budget $budget): JsonResponse public function amount(Request $request, Budget $budget): JsonResponse
{ {

View File

@@ -74,8 +74,6 @@ class IndexController extends Controller
* @param Carbon|null $end * @param Carbon|null $end
* *
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function index(Request $request, Carbon $start = null, Carbon $end = null) public function index(Request $request, Carbon $start = null, Carbon $end = null)
{ {

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* CreateController.php * CreateController.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* DeleteController.php * DeleteController.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* EditController.php * EditController.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1);
/** /**
* IndexController.php * IndexController.php
* Copyright (c) 2019 thegrumpydictator@gmail.com * Copyright (c) 2019 thegrumpydictator@gmail.com

View File

@@ -31,13 +31,12 @@ use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Support\Http\Controllers\PeriodOverview; use FireflyIII\Support\Http\Controllers\PeriodOverview;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log;
/** /**
* *
* Class ShowController * Class ShowController
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class ShowController extends Controller class ShowController extends Controller
{ {
@@ -65,7 +64,7 @@ class ShowController extends Controller
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Show a single category. * Show a single category.
* *

View File

@@ -43,9 +43,9 @@ use Log;
/** /**
* Class AccountController. * Class AccountController.
* *
* @SuppressWarnings(PHPMD.TooManyPublicMethods) *
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity) *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class AccountController extends Controller class AccountController extends Controller
{ {
@@ -436,8 +436,6 @@ class AccountController extends Controller
* @param Carbon $end * @param Carbon $end
* *
* @return JsonResponse * @return JsonResponse
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function period(Account $account, Carbon $start, Carbon $end): JsonResponse public function period(Account $account, Carbon $start, Carbon $end): JsonResponse
{ {

View File

@@ -40,8 +40,8 @@ use Illuminate\Support\Collection;
/** /**
* Class BudgetController. * Class BudgetController.
* *
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity) *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
* *
*/ */
class BudgetController extends Controller class BudgetController extends Controller
@@ -181,8 +181,6 @@ class BudgetController extends Controller
* @param BudgetLimit|null $budgetLimit * @param BudgetLimit|null $budgetLimit
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/ */
public function expenseAsset(Budget $budget, ?BudgetLimit $budgetLimit): JsonResponse public function expenseAsset(Budget $budget, ?BudgetLimit $budgetLimit): JsonResponse
{ {
@@ -232,8 +230,6 @@ class BudgetController extends Controller
* @param BudgetLimit|null $budgetLimit * @param BudgetLimit|null $budgetLimit
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/ */
public function expenseCategory(Budget $budget, ?BudgetLimit $budgetLimit): JsonResponse public function expenseCategory(Budget $budget, ?BudgetLimit $budgetLimit): JsonResponse
{ {
@@ -282,8 +278,6 @@ class BudgetController extends Controller
* @param BudgetLimit|null $budgetLimit * @param BudgetLimit|null $budgetLimit
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/ */
public function expenseExpense(Budget $budget, ?BudgetLimit $budgetLimit): JsonResponse public function expenseExpense(Budget $budget, ?BudgetLimit $budgetLimit): JsonResponse
{ {
@@ -333,8 +327,6 @@ class BudgetController extends Controller
* *
* @return JsonResponse * @return JsonResponse
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function frontpage(): JsonResponse public function frontpage(): JsonResponse
{ {
@@ -382,7 +374,7 @@ class BudgetController extends Controller
return response()->json($data); return response()->json($data);
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Shows a budget overview chart (spent and budgeted). * Shows a budget overview chart (spent and budgeted).
* *

View File

@@ -39,7 +39,7 @@ use Illuminate\Support\Collection;
* *
* Class BudgetReportController * Class BudgetReportController
* *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) *
*/ */
class BudgetReportController extends Controller class BudgetReportController extends Controller
{ {
@@ -66,7 +66,7 @@ class BudgetReportController extends Controller
); );
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Chart that groups expenses by the account. * Chart that groups expenses by the account.
* *
@@ -79,8 +79,6 @@ class BudgetReportController extends Controller
* @param string $others * @param string $others
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/ */
public function accountExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end, string $others): JsonResponse public function accountExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end, string $others): JsonResponse
{ {
@@ -97,7 +95,7 @@ class BudgetReportController extends Controller
return response()->json($data); return response()->json($data);
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Chart that groups the expenses by budget. * Chart that groups the expenses by budget.
* *
@@ -110,8 +108,6 @@ class BudgetReportController extends Controller
* @param string $others * @param string $others
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/ */
public function budgetExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end, string $others): JsonResponse public function budgetExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end, string $others): JsonResponse
{ {
@@ -128,7 +124,7 @@ class BudgetReportController extends Controller
return response()->json($data); return response()->json($data);
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Main overview of a budget in the budget report. * Main overview of a budget in the budget report.
* *
@@ -141,8 +137,6 @@ class BudgetReportController extends Controller
* *
* @return JsonResponse * @return JsonResponse
* *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function mainChart(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse public function mainChart(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse
{ {

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart; namespace FireflyIII\Http\Controllers\Chart;
use Carbon\Carbon; use Carbon\Carbon;
use Exception;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface; use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
@@ -32,6 +33,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Chart\Category\WholePeriodChartGenerator;
use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\ChartGeneration; use FireflyIII\Support\Http\Controllers\ChartGeneration;
use FireflyIII\Support\Http\Controllers\DateCalculation; use FireflyIII\Support\Http\Controllers\DateCalculation;
@@ -66,89 +68,30 @@ class CategoryController extends Controller
* TODO this chart is not multi-currency aware. * TODO this chart is not multi-currency aware.
* *
* @param CategoryRepositoryInterface $repository * @param CategoryRepositoryInterface $repository
* @param AccountRepositoryInterface $accountRepository
* @param Category $category * @param Category $category
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function all(CategoryRepositoryInterface $repository, AccountRepositoryInterface $accountRepository, Category $category): JsonResponse public function all(CategoryRepositoryInterface $repository, Category $category): JsonResponse
{ {
// cache results:
$cache = new CacheProperties; $cache = new CacheProperties;
$cache->addProperty('chart.category.all'); $cache->addProperty('chart.category.all');
$cache->addProperty($category->id); $cache->addProperty($category->id);
if ($cache->has()) { if ($cache->has()) {
return response()->json($cache->get()); // @codeCoverageIgnore return response()->json($cache->get()); // @codeCoverageIgnore
} }
$start = $repository->firstUseDate($category); $start = $repository->firstUseDate($category) ?? $this->getDate();
$start = $start ?? new Carbon;
$range = app('preferences')->get('viewRange', '1M')->data; $range = app('preferences')->get('viewRange', '1M')->data;
$start = app('navigation')->startOfPeriod($start, $range); $start = app('navigation')->startOfPeriod($start, $range);
$end = new Carbon; $end = $this->getDate();
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
Log::debug(sprintf('Full range is %s to %s', $start->format('Y-m-d'), $end->format('Y-m-d'))); Log::debug(sprintf('Full range is %s to %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
$chartData = [ /** @var WholePeriodChartGenerator $generator */
[ $generator = app(WholePeriodChartGenerator::class);
'label' => (string)trans('firefly.spent'), $chartData = $generator->generate($category, $start, $end);
'entries' => [], 'type' => 'bar', $data = $this->generator->multiSet($chartData);
'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
],
[
'label' => (string)trans('firefly.earned'),
'entries' => [], 'type' => 'bar',
'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
],
[
'label' => (string)trans('firefly.sum'),
'entries' => [], 'type' => 'line', 'fill' => false,
],
];
$step = $this->calculateStep($start, $end);
/** @var Carbon $current */
$current = clone $start;
Log::debug(sprintf('abc Step is %s', $step));
switch ($step) {
case '1D':
while ($current <= $end) {
//Log::debug(sprintf('Current day is %s', $current->format('Y-m-d')));
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $current, $current);
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $current, $current);
$sum = bcadd($spent, $earned);
$label = app('navigation')->periodShow($current, $step);
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 12);
$chartData[1]['entries'][$label] = round($earned, 12);
$chartData[2]['entries'][$label] = round($sum, 12);
$current->addDay();
}
break;
// @codeCoverageIgnoreStart
// for some reason it doesn't pick up on these case entries.
case '1W':
case '1M':
case '1Y':
// @codeCoverageIgnoreEnd
while ($current <= $end) {
$currentEnd = app('navigation')->endOfPeriod($current, $step);
//Log::debug(sprintf('abc Range is %s to %s', $current->format('Y-m-d'), $currentEnd->format('Y-m-d')));
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $current, $currentEnd);
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $current, $currentEnd);
$sum = bcadd($spent, $earned);
$label = app('navigation')->periodShow($current, $step);
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 12);
$chartData[1]['entries'][$label] = round($earned, 12);
$chartData[2]['entries'][$label] = round($sum, 12);
$current = app('navigation')->addPeriod($current, $step, 0);
}
break;
}
$data = $this->generator->multiSet($chartData);
$cache->store($data); $cache->store($data);
return response()->json($data); return response()->json($data);
@@ -259,8 +202,6 @@ class CategoryController extends Controller
* @param Carbon $end * @param Carbon $end
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function reportPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): JsonResponse public function reportPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{ {
@@ -271,7 +212,7 @@ class CategoryController extends Controller
$cache->addProperty($accounts->pluck('id')->toArray()); $cache->addProperty($accounts->pluck('id')->toArray());
$cache->addProperty($category); $cache->addProperty($category);
if ($cache->has()) { if ($cache->has()) {
return response()->json($cache->get());// @codeCoverageIgnore return response()->json($cache->get());// @codeCoverageIgnore
} }
$repository = app(CategoryRepositoryInterface::class); $repository = app(CategoryRepositoryInterface::class);
$expenses = $repository->periodExpenses(new Collection([$category]), $accounts, $start, $end); $expenses = $repository->periodExpenses(new Collection([$category]), $accounts, $start, $end);
@@ -303,7 +244,7 @@ class CategoryController extends Controller
$spent = $expenses[$category->id]['entries'][$period] ?? '0'; $spent = $expenses[$category->id]['entries'][$period] ?? '0';
$earned = $income[$category->id]['entries'][$period] ?? '0'; $earned = $income[$category->id]['entries'][$period] ?? '0';
$sum = bcadd($spent, $earned); $sum = bcadd($spent, $earned);
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 12); $chartData[0]['entries'][$label] = round($spent, 12);
$chartData[1]['entries'][$label] = round($earned, 12); $chartData[1]['entries'][$label] = round($earned, 12);
$chartData[2]['entries'][$label] = round($sum, 12); $chartData[2]['entries'][$label] = round($sum, 12);
} }
@@ -315,7 +256,7 @@ class CategoryController extends Controller
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Chart for period for transactions without a category. * Chart for period for transactions without a category.
@@ -327,8 +268,6 @@ class CategoryController extends Controller
* @param Carbon $end * @param Carbon $end
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function reportPeriodNoCategory(Collection $accounts, Carbon $start, Carbon $end): JsonResponse public function reportPeriodNoCategory(Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{ {
@@ -383,8 +322,6 @@ class CategoryController extends Controller
/** /**
* Chart for a specific period. * Chart for a specific period.
* *
* TODO this chart is not multi-currency aware.
*
* @param Category $category * @param Category $category
* @param $date * @param $date
* *
@@ -399,8 +336,42 @@ class CategoryController extends Controller
[$end, $start] = [$start, $end]; // @codeCoverageIgnore [$end, $start] = [$start, $end]; // @codeCoverageIgnore
} }
$data = $this->makePeriodChart($category, $start, $end); $cache = new CacheProperties;
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($category->id);
$cache->addProperty('chart.category.period-chart');
if ($cache->has()) {
return response()->json($cache->get()); // @codeCoverageIgnore
}
/** @var GeneratorInterface $generator */
$generator = app(GeneratorInterface::class);
/** @var WholePeriodChartGenerator $chartGenerator */
$chartGenerator = app(WholePeriodChartGenerator::class);
$chartData = $chartGenerator->generate($category, $start, $end);
$data = $generator->multiSet($chartData);
$cache->store($data);
return response()->json($data); return response()->json($data);
} }
/**
* @return Carbon
*/
private function getDate(): Carbon
{
$carbon = null;
try {
$carbon = new Carbon;
} catch (Exception $e) {
$e->getMessage();
}
return $carbon;
}
} }

View File

@@ -61,7 +61,7 @@ class CategoryReportController extends Controller
); );
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Chart for expenses grouped by expense account. * Chart for expenses grouped by expense account.
* *
@@ -74,8 +74,6 @@ class CategoryReportController extends Controller
* @param string $others * @param string $others
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/ */
public function accountExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end, string $others): JsonResponse public function accountExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end, string $others): JsonResponse
{ {
@@ -89,7 +87,7 @@ class CategoryReportController extends Controller
return response()->json($data); return response()->json($data);
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Chart for income grouped by revenue account. * Chart for income grouped by revenue account.
* *
@@ -102,8 +100,6 @@ class CategoryReportController extends Controller
* @param string $others * @param string $others
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/ */
public function accountIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end, string $others): JsonResponse public function accountIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end, string $others): JsonResponse
{ {
@@ -120,7 +116,7 @@ class CategoryReportController extends Controller
return response()->json($data); return response()->json($data);
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Chart for expenses grouped by expense account. * Chart for expenses grouped by expense account.
* *
@@ -133,8 +129,6 @@ class CategoryReportController extends Controller
* @param string $others * @param string $others
* *
* @return JsonResponse * @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/ */
public function categoryExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end, string $others): JsonResponse public function categoryExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end, string $others): JsonResponse
{ {
@@ -151,7 +145,7 @@ class CategoryReportController extends Controller
return response()->json($data); return response()->json($data);
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Piechart for income grouped by account. * Piechart for income grouped by account.
* *
@@ -164,7 +158,7 @@ class CategoryReportController extends Controller
* @param string $others * @param string $others
* *
* @return JsonResponse * @return JsonResponse
* @SuppressWarnings(PHPMD.ExcessiveParameterList) *
*/ */
public function categoryIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end, string $others): JsonResponse public function categoryIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end, string $others): JsonResponse
{ {
@@ -182,7 +176,7 @@ class CategoryReportController extends Controller
} }
/** @noinspection MoreThanThreeArgumentsInspection */
/** /**
* Main report category chart. * Main report category chart.
* *
@@ -195,9 +189,7 @@ class CategoryReportController extends Controller
* *
* @return JsonResponse * @return JsonResponse
* *
* @SuppressWarnings(PHPMD.ExcessiveParameterList) *
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
public function mainChart(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse public function mainChart(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse
{ {
@@ -208,7 +200,7 @@ class CategoryReportController extends Controller
$cache->addProperty($start); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);
if ($cache->has()) { if ($cache->has()) {
//return response()->json($cache->get()); // @codeCoverageIgnore return response()->json($cache->get()); // @codeCoverageIgnore
} }
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end); $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
@@ -262,7 +254,7 @@ class CategoryReportController extends Controller
$labelOut = $category->id . '-out'; $labelOut = $category->id . '-out';
$labelSumIn = $category->id . '-total-in'; $labelSumIn = $category->id . '-total-in';
$labelSumOut = $category->id . '-total-out'; $labelSumOut = $category->id . '-total-out';
$currentIncome = bcmul($income[$category->id] ?? '0','-1'); $currentIncome = $income[$category->id] ?? '0';
$currentExpense = $expenses[$category->id] ?? '0'; $currentExpense = $expenses[$category->id] ?? '0';
// add to sum: // add to sum:

Some files were not shown because too many files have changed in this diff Show More