diff --git a/app/Api/V1/Controllers/Chart/AccountController.php b/app/Api/V1/Controllers/Chart/AccountController.php
index 7547cbb248..062748cfe5 100644
--- a/app/Api/V1/Controllers/Chart/AccountController.php
+++ b/app/Api/V1/Controllers/Chart/AccountController.php
@@ -26,10 +26,9 @@ namespace FireflyIII\Api\V1\Controllers\Chart;
use Carbon\Carbon;
use FireflyIII\Api\V1\Controllers\Controller;
-use FireflyIII\Api\V1\Requests\DateRequest;
+use FireflyIII\Api\V1\Requests\Data\DateRequest;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\ApiSupport;
@@ -44,8 +43,7 @@ class AccountController extends Controller
use ApiSupport;
private CurrencyRepositoryInterface $currencyRepository;
-
- private AccountRepositoryInterface $repository;
+ private AccountRepositoryInterface $repository;
/**
@@ -71,92 +69,6 @@ class AccountController extends Controller
);
}
- /**
- * @param DateRequest $request
- * @deprecated
- * @return JsonResponse
- */
- public function expenseOverview(DateRequest $request): JsonResponse
- {
- // parameters for chart:
- $dates = $request->getAll();
- /** @var Carbon $start */
- $start = $dates['start'];
- /** @var Carbon $end */
- $end = $dates['end'];
-
- $start->subDay();
-
- // prep some vars:
- $currencies = [];
- $chartData = [];
- $tempData = [];
-
- // grab all accounts and names
- $accounts = $this->repository->getAccountsByType([AccountType::EXPENSE]);
- $accountNames = $this->extractNames($accounts);
- $startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
- $endBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $end);
-
- // loop the end balances. This is an array for each account ($expenses)
- foreach ($endBalances as $accountId => $expenses) {
- $accountId = (int) $accountId;
- // loop each expense entry (each entry can be a different currency).
- foreach ($expenses as $currencyId => $endAmount) {
- $currencyId = (int) $currencyId;
-
- // see if there is an accompanying start amount.
- // grab the difference and find the currency.
- $startAmount = $startBalances[$accountId][$currencyId] ?? '0';
- $diff = bcsub($endAmount, $startAmount);
- $currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->findNull($currencyId);
- if (0 !== bccomp($diff, '0')) {
- // store the values in a temporary array.
- $tempData[] = [
- 'name' => $accountNames[$accountId],
- 'difference' => $diff,
- 'diff_float' => (float) $diff,
- 'currency_id' => $currencyId,
- ];
- }
- }
- }
-
- // sort temp array by amount.
- $amounts = array_column($tempData, 'diff_float');
- array_multisort($amounts, SORT_DESC, $tempData);
-
- // loop all found currencies and build the data array for the chart.
- /**
- * @var int $currencyId
- * @var TransactionCurrency $currency
- */
- foreach ($currencies as $currencyId => $currency) {
- $currentSet = [
- 'label' => trans('firefly.box_spent_in_currency', ['currency' => $currency->symbol]),
- 'currency_id' => $currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
- 'type' => 'bar', // line, area or bar
- 'yAxisID' => 0, // 0, 1, 2
- 'entries' => $this->expandNames($tempData),
- ];
- $chartData[$currencyId] = $currentSet;
- }
-
- // loop temp data and place data in correct array:
- foreach ($tempData as $entry) {
- $currencyId = $entry['currency_id'];
- $name = $entry['name'];
- $chartData[$currencyId]['entries'][$name] = round((float) $entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
- }
- $chartData = array_values($chartData);
-
- return response()->json($chartData);
- }
-
-
/**
* @param DateRequest $request
*
@@ -193,7 +105,7 @@ class AccountController extends Controller
}
$currentSet = [
'label' => $account->name,
- 'currency_id' => (string) $currency->id,
+ 'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
'currency_decimal_places' => $currency->decimal_places,
@@ -206,11 +118,11 @@ class AccountController extends Controller
/** @var Carbon $currentStart */
$currentStart = clone $start;
$range = app('steam')->balanceInRange($account, $start, clone $end);
- $previous = round((float) array_values($range)[0], 12);
+ $previous = round((float)array_values($range)[0], 12);
while ($currentStart <= $end) {
$format = $currentStart->format('Y-m-d');
$label = $currentStart->format('Y-m-d');
- $balance = array_key_exists($format, $range) ? round((float) $range[$format], 12) : $previous;
+ $balance = array_key_exists($format, $range) ? round((float)$range[$format], 12) : $previous;
$previous = $balance;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;
@@ -220,91 +132,4 @@ class AccountController extends Controller
return response()->json($chartData);
}
-
- /**
- * @param DateRequest $request
- * @deprecated
- * @return JsonResponse
- */
- public function revenueOverview(DateRequest $request): JsonResponse
- {
- // parameters for chart:
- $dates = $request->getAll();
- /** @var Carbon $start */
- $start = $dates['start'];
- /** @var Carbon $end */
- $end = $dates['end'];
-
- $start->subDay();
-
- // prep some vars:
- $currencies = [];
- $chartData = [];
- $tempData = [];
-
- // grab all accounts and names
- $accounts = $this->repository->getAccountsByType([AccountType::REVENUE]);
- $accountNames = $this->extractNames($accounts);
- $startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
- $endBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $end);
-
- // loop the end balances. This is an array for each account ($expenses)
- foreach ($endBalances as $accountId => $expenses) {
- $accountId = (int) $accountId;
- // loop each expense entry (each entry can be a different currency).
- foreach ($expenses as $currencyId => $endAmount) {
- $currencyId = (int) $currencyId;
-
- // see if there is an accompanying start amount.
- // grab the difference and find the currency.
- $startAmount = $startBalances[$accountId][$currencyId] ?? '0';
- $diff = bcsub($endAmount, $startAmount);
- $currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->findNull($currencyId);
- if (0 !== bccomp($diff, '0')) {
- // store the values in a temporary array.
- $tempData[] = [
- 'name' => $accountNames[$accountId],
- 'difference' => bcmul($diff, '-1'),
- // For some reason this line is never covered in code coverage:
- 'diff_float' => ((float) $diff) * -1, // @codeCoverageIgnore
- 'currency_id' => $currencyId,
- ];
- }
- }
- }
-
- // sort temp array by amount.
- $amounts = array_column($tempData, 'diff_float');
- array_multisort($amounts, SORT_DESC, $tempData);
-
- // loop all found currencies and build the data array for the chart.
- /**
- * @var int $currencyId
- * @var TransactionCurrency $currency
- */
- foreach ($currencies as $currencyId => $currency) {
- $currentSet = [
- 'label' => trans('firefly.box_earned_in_currency', ['currency' => $currency->symbol]),
- 'currency_id' => $currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
- 'type' => 'bar', // line, area or bar
- 'yAxisID' => 0, // 0, 1, 2
- 'entries' => $this->expandNames($tempData),
- ];
- $chartData[$currencyId] = $currentSet;
- }
-
- // loop temp data and place data in correct array:
- foreach ($tempData as $entry) {
- $currencyId = $entry['currency_id'];
- $name = $entry['name'];
- $chartData[$currencyId]['entries'][$name] = round((float) $entry['difference'], $chartData[$currencyId]['currency_decimal_places']);
- }
- $chartData = array_values($chartData);
-
- return response()->json($chartData);
- }
-
}
diff --git a/app/Api/V1/Controllers/Chart/AvailableBudgetController.php b/app/Api/V1/Controllers/Chart/AvailableBudgetController.php
deleted file mode 100644
index 039ebffe49..0000000000
--- a/app/Api/V1/Controllers/Chart/AvailableBudgetController.php
+++ /dev/null
@@ -1,115 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace FireflyIII\Api\V1\Controllers\Chart;
-
-
-use FireflyIII\Api\V1\Controllers\Controller;
-use FireflyIII\Models\AvailableBudget;
-use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
-use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
-use FireflyIII\User;
-use Illuminate\Http\JsonResponse;
-
-/**
- * Class AvailableBudgetController
- */
-class AvailableBudgetController extends Controller
-{
- private OperationsRepositoryInterface $opsRepository;
- private BudgetRepositoryInterface $repository;
-
- /**
- * AvailableBudgetController constructor.
- * @deprecated
- * @codeCoverageIgnore
- */
- public function __construct()
- {
- parent::__construct();
- $this->middleware(
- function ($request, $next) {
- /** @var User $user */
- $user = auth()->user();
- $this->repository = app(BudgetRepositoryInterface::class);
- $this->opsRepository = app(OperationsRepositoryInterface::class);
- $this->repository->setUser($user);
- $this->opsRepository->setUser($user);
-
- return $next($request);
- }
- );
- }
-
- /**
- * @param AvailableBudget $availableBudget
- * @deprecated
- * @return JsonResponse
- */
- public function overview(AvailableBudget $availableBudget): JsonResponse
- {
- $currency = $availableBudget->transactionCurrency;
- $budgets = $this->repository->getActiveBudgets();
- $newBudgetInformation = $this->opsRepository->sumExpenses($availableBudget->start_date, $availableBudget->end_date, null, $budgets);
- $spent = '0';
-
- foreach ($newBudgetInformation as $currencyId => $info) {
- if ($currencyId === (int) $availableBudget->transaction_currency_id) {
- $spent = $info['sum'];
- }
- }
-
- $left = bcadd($availableBudget->amount, $spent);
- // left less than zero? Set to zero.
- if (-1 === bccomp($left, '0')) {
- $left = '0';
- }
-
- $chartData = [
- [
- 'label' => trans('firefly.spent'),
- 'currency_id' => $currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
- 'type' => 'pie',
- 'yAxisID' => 0, // 0, 1, 2
- 'entries' => [$spent * -1],
- ],
- [
- 'label' => trans('firefly.left'),
- 'currency_id' => $currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
- 'type' => 'line', // line, area or bar
- 'yAxisID' => 0, // 0, 1, 2
- 'entries' => [round((float) $left, $currency->decimal_places)],
- ],
- ];
-
- return response()->json($chartData);
- }
-
-}
diff --git a/app/Api/V1/Controllers/Chart/BudgetController.php b/app/Api/V1/Controllers/Chart/BudgetController.php
deleted file mode 100644
index 3a1ad355aa..0000000000
--- a/app/Api/V1/Controllers/Chart/BudgetController.php
+++ /dev/null
@@ -1,297 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace FireflyIII\Api\V1\Controllers\Chart;
-
-
-use Carbon\Carbon;
-use FireflyIII\Api\V1\Controllers\Controller;
-use FireflyIII\Api\V1\Requests\DateRequest;
-use FireflyIII\Models\Budget;
-use FireflyIII\Models\BudgetLimit;
-use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
-use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
-use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
-use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Collection;
-
-/**
- * Class BudgetController
- */
-class BudgetController extends Controller
-{
- private BudgetLimitRepositoryInterface $blRepository;
-
- private OperationsRepositoryInterface $opsRepository;
-
- private BudgetRepositoryInterface $repository;
-
-
- /**
- * BudgetController constructor.
- * @deprecated
- * @codeCoverageIgnore
- */
- public function __construct()
- {
- parent::__construct();
-
- $this->middleware(
- function ($request, $next) {
- $this->repository = app(BudgetRepositoryInterface::class);
- $this->opsRepository = app(OperationsRepositoryInterface::class);
- $this->blRepository = app(BudgetLimitRepositoryInterface::class);
-
- return $next($request);
- }
- );
- }
-
- /**
- * [
- * 'label' => 'label for entire set'
- * 'currency_id' => 0,
- * 'currency_code' => 'EUR',
- * 'currency_symbol' => '$',
- * 'currency_decimal_places' => 2,
- * 'type' => 'bar', // line, area or bar
- * 'yAxisID' => 0, // 0, 1, 2
- * 'entries' => ['a' => 1, 'b' => 4],
- * ],
- *
- * @param DateRequest $request
- * @deprecated
- * @return JsonResponse
- */
- public function overview(DateRequest $request): JsonResponse
- {
- $dates = $request->getAll();
- $budgets = $this->repository->getActiveBudgets();
- $budgetNames = [];
- $currencyNames = [];
- $sets = [];
- /** @var Budget $budget */
- foreach ($budgets as $budget) {
- $expenses = $this->getExpenses($budget, $dates['start'], $dates['end']);
- $expenses = $this->filterNulls($expenses);
- foreach ($expenses as $set) {
- $budgetNames[] = $set['budget_name'];
- $currencyNames[] = $set['currency_name'];
- $sets[] = $set;
- }
- }
- $budgetNames = array_unique($budgetNames);
- $currencyNames = array_unique($currencyNames);
- $basic = $this->createSets($budgetNames, $currencyNames);
- $filled = $this->fillSets($basic, $sets);
- $keys = array_values($filled);
-
- return response()->json($keys);
- }
-
- /**
- * @param Collection $limits
- * @param Carbon $start
- * @param Carbon $end
- * @deprecated
- * @return array
- */
- protected function getExpenses(Budget $budget, Carbon $start, Carbon $end): array
- {
- $limits = $this->blRepository->getBudgetLimits($budget, $start, $end);
- if (0 === $limits->count()) {
- return $this->getExpenseInRange($budget, $start, $end);
- }
- $arr = [];
- /** @var BudgetLimit $limit */
- foreach ($limits as $limit) {
- $arr[] = $this->getExpensesForLimit($limit);
- }
-
- return $arr;
- }
-
- /**
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- * @deprecated
- * @return array
- */
- private function getExpenseInRange(Budget $budget, Carbon $start, Carbon $end): array
- {
- $spent = $this->opsRepository->sumExpenses($start, $end, null, new Collection([$budget]), null);
- $return = [];
- /** @var array $set */
- foreach ($spent as $set) {
- $current = [
- 'label' => sprintf('%s (%s)', $budget->name, $set['currency_name']),
- 'budget_name' => $budget->name,
- 'start_date' => $start->format('Y-m-d'),
- 'end_date' => $end->format('Y-m-d'),
- 'currency_id' => (int) $set['currency_id'],
- 'currency_code' => $set['currency_code'],
- 'currency_name' => $set['currency_name'],
- 'currency_symbol' => $set['currency_symbol'],
- 'currency_decimal_places' => (int) $set['currency_decimal_places'],
- 'type' => 'bar', // line, area or bar,
- 'entries' => [],
- ];
- $sumSpent = bcmul($set['sum'], '-1'); // spent
- $current['entries']['spent'] = $sumSpent;
- $current['entries']['amount'] = '0';
- $current['entries']['spent_capped'] = $sumSpent;
- $current['entries']['left'] = '0';
- $current['entries']['overspent'] = '0';
- $return[] = $current;
- }
-
- return $return;
- }
-
- /**
- * @param BudgetLimit $limit
- * @deprecated
- * @return array
- */
- private function getExpensesForLimit(BudgetLimit $limit): array
- {
- $budget = $limit->budget;
- $spent = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $limit->transactionCurrency);
- $currency = $limit->transactionCurrency;
- // when limited to a currency, the count is always one. Or it's empty.
- $set = array_shift($spent);
- if (null === $set) {
- return [];
- }
- $return = [
- 'label' => sprintf('%s (%s)', $budget->name, $set['currency_name']),
- 'budget_name' => $budget->name,
- 'start_date' => $limit->start_date->format('Y-m-d'),
- 'end_date' => $limit->end_date->format('Y-m-d'),
- 'currency_id' => (int) $currency->id,
- 'currency_code' => $currency->code,
- 'currency_name' => $currency->name,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int) $currency->decimal_places,
- 'type' => 'bar', // line, area or bar,
- 'entries' => [],
- ];
- $sumSpent = bcmul($set['sum'], '-1'); // spent
- $return['entries']['spent'] = $sumSpent;
- $return['entries']['amount'] = $limit->amount;
- $return['entries']['spent_capped'] = 1 === bccomp($sumSpent, $limit->amount) ? $limit->amount : $sumSpent;
- $return['entries']['left'] = 1 === bccomp($limit->amount, $sumSpent) ? bcadd($set['sum'], $limit->amount) : '0'; // left
- $return['entries']['overspent'] = 1 === bccomp($limit->amount, $sumSpent) ? '0' : bcmul(bcadd($set['sum'], $limit->amount), '-1'); // overspent
-
- return $return;
- }
-
- /**
- * @param array $expenses
- * @deprecated
- * @return array
- */
- private function filterNulls(array $expenses): array
- {
- $return = [];
- /** @var array|null $arr */
- foreach ($expenses as $arr) {
- if ([] !== $arr) {
- $return[] = $arr;
- }
- }
-
- return $return;
- }
-
- /**
- * @param array $budgetNames
- * @param array $currencyNames
- * @deprecated
- * @return array
- */
- private function createSets(array $budgetNames, array $currencyNames): array
- {
- $return = [];
- foreach ($currencyNames as $currencyName) {
- $entries = [];
- foreach ($budgetNames as $budgetName) {
- $label = sprintf('%s (%s)', $budgetName, $currencyName);
- $entries[$label] = '0';
- }
-
- // left
- $return['left'] = [
- 'label' => sprintf('%s (%s)', trans('firefly.left'), $currencyName),
- 'data_type' => 'left',
- 'currency_name' => $currencyName,
- 'type' => 'bar',
- 'yAxisID' => 0, // 0, 1, 2
- 'entries' => $entries,
- ];
-
- // spent_capped
- $return['spent_capped'] = [
- 'label' => sprintf('%s (%s)', trans('firefly.spent'), $currencyName),
- 'data_type' => 'spent_capped',
- 'currency_name' => $currencyName,
- 'type' => 'bar',
- 'yAxisID' => 0, // 0, 1, 2
- 'entries' => $entries,
- ];
-
- // overspent
- $return['overspent'] = [
- 'label' => sprintf('%s (%s)', trans('firefly.overspent'), $currencyName),
- 'data_type' => 'overspent',
- 'currency_name' => $currencyName,
- 'type' => 'bar',
- 'yAxisID' => 0, // 0, 1, 2
- 'entries' => $entries,
- ];
-
- }
-
- return $return;
- }
-
- /**
- * @param array $basic
- * @param array $sets
- * @deprecated
- * @return array
- */
- private function fillSets(array $basic, array $sets): array
- {
- foreach ($sets as $set) {
- $label = $set['label'];
- $basic['spent_capped']['entries'][$label] = $set['entries']['spent_capped'];
- $basic['left']['entries'][$label] = $set['entries']['left'];
- $basic['overspent']['entries'][$label] = $set['entries']['overspent'];
- }
-
- return $basic;
- }
-
-}
diff --git a/app/Api/V1/Controllers/Chart/CategoryController.php b/app/Api/V1/Controllers/Chart/CategoryController.php
deleted file mode 100644
index 04d525cd87..0000000000
--- a/app/Api/V1/Controllers/Chart/CategoryController.php
+++ /dev/null
@@ -1,157 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace FireflyIII\Api\V1\Controllers\Chart;
-
-use Carbon\Carbon;
-use FireflyIII\Api\V1\Controllers\Controller;
-use FireflyIII\Api\V1\Requests\DateRequest;
-use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
-use FireflyIII\Repositories\Category\NoCategoryRepositoryInterface;
-use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
-use FireflyIII\User;
-use Illuminate\Http\JsonResponse;
-
-/**
- * Class CategoryController
- */
-class CategoryController extends Controller
-{
- private CategoryRepositoryInterface $categoryRepository;
- private NoCategoryRepositoryInterface $noCatRepository;
- private OperationsRepositoryInterface $opsRepository;
- private array $categories;
-
- /**
- * AccountController constructor.
- * @deprecated
- * @codeCoverageIgnore
- */
- public function __construct()
- {
- parent::__construct();
- $this->middleware(
- function ($request, $next) {
- /** @var User $user */
- $user = auth()->user();
- $this->categoryRepository = app(CategoryRepositoryInterface::class);
- $this->opsRepository = app(OperationsRepositoryInterface::class);
- $this->noCatRepository = app(NoCategoryRepositoryInterface::class);
- $this->categories = [];
- $this->categoryRepository->setUser($user);
- $this->opsRepository->setUser($user);
- $this->noCatRepository->setUser($user);
-
- return $next($request);
- }
- );
- }
-
-
- /**
- * @param DateRequest $request
- * @deprecated
- * @return JsonResponse
- */
- public function overview(DateRequest $request): JsonResponse
- {
- // parameters for chart:
- $dates = $request->getAll();
- /** @var Carbon $start */
- $start = $dates['start'];
- /** @var Carbon $end */
- $end = $dates['end'];
-
- $tempData = [];
- $spentWith = $this->opsRepository->listExpenses($start, $end);
- $spentWithout = $this->noCatRepository->listExpenses($start, $end);
-
- /** @var array $set */
- foreach ([$spentWith, $spentWithout,] as $set) {
- $tempData = $this->processArray($tempData, $set);
- }
-
- $chartData = $this->sortArray($tempData);
-
- return response()->json($chartData);
- }
-
- /**
- * @param array $tempData
- * @param array $set
- * @deprecated
- * @return array
- */
- private function processArray(array $tempData, array $set): array
- {
- foreach ($set as $currency) {
- foreach ($currency['categories'] as $category) {
- $this->categories[] = $category['name'];
- $outKey = sprintf('%d-e', $currency['currency_id']);
- $tempData[$outKey] = $tempData[$outKey] ?? [
- 'currency_id' => $currency['currency_id'],
- 'label' => (string)trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
- 'currency_code' => $currency['currency_code'],
- 'currency_symbol' => $currency['currency_symbol'],
- 'currency_decimal_places' => $currency['currency_decimal_places'],
- 'type' => 'bar', // line, area or bar
- 'yAxisID' => 0, // 0, 1, 2
- 'entries' => [],
- ];
-
- foreach ($category['transaction_journals'] as $journal) {
- // is it expense or income?
- $currentKey = sprintf('%d-%s', $currency['currency_id'], 'e');
- $name = $category['name'];
- $tempData[$currentKey]['entries'][$name] = $tempData[$currentKey]['entries'][$name] ?? '0';
- $tempData[$currentKey]['entries'][$name] = bcadd($tempData[$currentKey]['entries'][$name], $journal['amount']);
- }
- }
- }
-
- return $tempData;
- }
-
- /**
- * @param array $tempData
- * @deprecated
- * @return array
- */
- private function sortArray(array $tempData): array
- {
- // re-sort every spent array and add 0 for missing entries.
- foreach ($tempData as $index => $set) {
- $oldSet = $set['entries'];
- $newSet = [];
- foreach ($this->categories as $category) {
- $value = $oldSet[$category] ?? '0';
- $value = -1 === bccomp($value, '0') ? bcmul($value, '-1') : $value;
- $newSet[$category] = $value;
- }
- $tempData[$index]['entries'] = $newSet;
- }
-
- return array_values($tempData);
- }
-}
diff --git a/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php b/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php
index c3f980007f..5c988790f4 100644
--- a/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php
@@ -73,14 +73,14 @@ class UpdateController extends Controller
public function update(UpdateRequest $request, Recurrence $recurrence): JsonResponse
{
$data = $request->getAll();
- $category = $this->repository->update($recurrence, $data);
+ $recurrence = $this->repository->update($recurrence, $data);
$manager = $this->getManager();
/** @var RecurrenceTransformer $transformer */
$transformer = app(RecurrenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($category, $transformer, 'recurrences');
+ $resource = new Item($recurrence, $transformer, 'recurrences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php b/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php
index 0a44df523a..6c3aea75c3 100644
--- a/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php
@@ -43,7 +43,6 @@ class UpdateRequest extends FormRequest
use ConvertsDataTypes, RecurrenceValidation, TransactionValidation, CurrencyValidation, GetRecurrenceData, ChecksLogin;
-
/**
* Get all data from the request.
*
@@ -51,46 +50,46 @@ class UpdateRequest extends FormRequest
*/
public function getAll(): array
{
- $active = null;
- $applyRules = null;
- if (null !== $this->get('active')) {
- $active = $this->boolean('active');
+ // this is the way:
+ $fields = [
+ 'title' => ['title', 'string'],
+ 'description' => ['description', 'string'],
+ 'first_date' => ['first_date', 'date'],
+ 'repeat_until' => ['repeat_until', 'date'],
+ 'nr_of_repetitions' => ['nr_of_repetitions', 'integer'],
+ 'apply_rules' => ['apply_rules', 'boolean'],
+ 'active' => ['active', 'boolean'],
+ 'notes' => ['notes', 'string'],
+ ];
+ $reps = $this->getRepetitionData();
+ $transactions = $this->getTransactionData();
+ $return = [
+ 'recurrence' => $this->getAllData($fields),
+ ];
+ if (null !== $reps) {
+ $return['repetitions'] = $reps;
}
- if (null !== $this->get('apply_rules')) {
- $applyRules = $this->boolean('apply_rules');
+ if (null !== $transactions) {
+ $return['transactions'] = $transactions;
}
- return [
- 'recurrence' => [
- 'type' => $this->nullableString('type'),
- 'title' => $this->nullableString('title'),
- 'description' => $this->nullableString('description'),
- 'first_date' => $this->date('first_date'),
- 'notes' => $this->nullableNlString('notes'),
- 'repeat_until' => $this->date('repeat_until'),
- 'nr_of_repetitions' => $this->nullableInteger('nr_of_repetitions'),
- 'apply_rules' => $applyRules,
- 'active' => $active,
- ],
- 'transactions' => $this->getTransactionData(),
- 'repetitions' => $this->getRepetitionData(),
- ];
+ return $return;
}
/**
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
*
- * @return array
+ * @return array|null
*/
- private function getTransactionData(): array
+ private function getTransactionData(): ?array
{
$return = [];
// transaction data:
/** @var array $transactions */
$transactions = $this->get('transactions');
if (null === $transactions) {
- return [];
+ return null;
}
/** @var array $transaction */
foreach ($transactions as $transaction) {
@@ -103,25 +102,36 @@ class UpdateRequest extends FormRequest
/**
* Returns the repetition data as it is found in the submitted data.
*
- * @return array
+ * @return array|null
*/
- private function getRepetitionData(): array
+ private function getRepetitionData(): ?array
{
$return = [];
// repetition data:
/** @var array $repetitions */
$repetitions = $this->get('repetitions');
if (null === $repetitions) {
- return [];
+ return null;
}
/** @var array $repetition */
foreach ($repetitions as $repetition) {
- $return[] = [
- 'type' => $repetition['type'],
- 'moment' => $repetition['moment'],
- 'skip' => (int) $repetition['skip'],
- 'weekend' => (int) $repetition['weekend'],
- ];
+ $current = [];
+ if(array_key_exists('type', $repetition)) {
+ $current['type'] = $repetition['type'];
+ }
+
+ if(array_key_exists('moment', $repetition)) {
+ $current['moment'] = $repetition['moment'];
+ }
+
+ if(array_key_exists('skip', $repetition)) {
+ $current['skip'] = (int)$repetition['skip'];
+ }
+
+ if(array_key_exists('weekend', $repetition)) {
+ $current['weekend'] = (int) $repetition['weekend'];
+ }
+ $return[] = $current;
}
return $return;
@@ -138,7 +148,6 @@ class UpdateRequest extends FormRequest
$recurrence = $this->route()->parameter('recurrence');
return [
- 'type' => 'in:withdrawal,transfer,deposit',
'title' => sprintf('between:1,255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
'description' => 'between:1,65000',
'first_date' => 'date',
@@ -148,11 +157,11 @@ class UpdateRequest extends FormRequest
'nr_of_repetitions' => 'numeric|between:1,31',
'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly',
'repetitions.*.moment' => 'between:0,10',
- 'repetitions.*.skip' => 'required|numeric|between:0,31',
- 'repetitions.*.weekend' => 'required|numeric|min:1|max:4',
+ 'repetitions.*.skip' => 'numeric|between:0,31',
+ 'repetitions.*.weekend' => 'numeric|min:1|max:4',
- 'transactions.*.description' => 'required|between:1,255',
- 'transactions.*.amount' => 'required|numeric|gt:0',
+ 'transactions.*.description' => 'between:1,255',
+ 'transactions.*.amount' => 'numeric|gt:0',
'transactions.*.foreign_amount' => 'numeric|gt:0',
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
@@ -186,9 +195,9 @@ class UpdateRequest extends FormRequest
{
$validator->after(
function (Validator $validator) {
- $this->validateOneRecurrenceTransaction($validator);
- $this->validateOneRepetitionUpdate($validator);
- $this->validateRecurrenceRepetition($validator);
+ //$this->validateOneRecurrenceTransaction($validator);
+ //$this->validateOneRepetitionUpdate($validator);
+ //$this->validateRecurrenceRepetition($validator);
$this->validateRepetitionMoment($validator);
$this->validateForeignCurrencyInformation($validator);
$this->valUpdateAccountInfo($validator);
diff --git a/app/Console/Commands/Upgrade/MigrateRecurrenceType.php b/app/Console/Commands/Upgrade/MigrateRecurrenceType.php
index 0a2ee674e8..bb86826544 100644
--- a/app/Console/Commands/Upgrade/MigrateRecurrenceType.php
+++ b/app/Console/Commands/Upgrade/MigrateRecurrenceType.php
@@ -42,7 +42,7 @@ class MigrateRecurrenceType extends Command
$this->migrateTypes();
- //$this->markAsExecuted();
+ $this->markAsExecuted();
$end = round(microtime(true) - $start, 2);
$this->info(sprintf('Update recurring transaction types in %s seconds.', $end));
diff --git a/app/Repositories/Recurring/RecurringRepository.php b/app/Repositories/Recurring/RecurringRepository.php
index 05780c8bbe..80ba813e26 100644
--- a/app/Repositories/Recurring/RecurringRepository.php
+++ b/app/Repositories/Recurring/RecurringRepository.php
@@ -570,7 +570,6 @@ class RecurringRepository implements RecurringRepositoryInterface
{
/** @var RecurrenceUpdateService $service */
$service = app(RecurrenceUpdateService::class);
-
return $service->update($recurrence, $data);
}
diff --git a/app/Services/Internal/Update/AccountUpdateService.php b/app/Services/Internal/Update/AccountUpdateService.php
index 9380edd624..2393772dd6 100644
--- a/app/Services/Internal/Update/AccountUpdateService.php
+++ b/app/Services/Internal/Update/AccountUpdateService.php
@@ -108,31 +108,31 @@ class AccountUpdateService
/**
* @param Account $account
* @param array $data
+ *
+ * @return Account
*/
- private function updateLocation(Account $account, array $data): void
+ private function updateAccount(Account $account, array $data): Account
{
- $updateLocation = $data['update_location'] ?? false;
- // location must be updated?
- if (true === $updateLocation) {
- // if all set to NULL, delete
- if (null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level']) {
- $account->locations()->delete();
- }
+ // update the account itself:
+ $account->name = $data['name'] ?? $account->name;
+ $account->active = $data['active'] ?? $account->active;
+ $account->iban = $data['iban'] ?? $account->iban;
- // otherwise, update or create.
- if (!(null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level'])) {
- $location = $this->accountRepository->getLocation($account);
- if (null === $location) {
- $location = new Location;
- $location->locatable()->associate($account);
- }
-
- $location->latitude = $data['latitude'] ?? config('firefly.default_location.latitude');
- $location->longitude = $data['longitude'] ?? config('firefly.default_location.longitude');
- $location->zoom_level = $data['zoom_level'] ?? config('firefly.default_location.zoom_level');
- $location->save();
- }
+ // liability stuff:
+ $liabilityType = $data['liability_type'] ?? '';
+ if ($this->isLiability($account) && $this->isLiabilityType($liabilityType)) {
+ $type = $this->getAccountType($liabilityType);
+ $account->account_type_id = $type->id;
}
+
+ // update virtual balance (could be set to zero if empty string).
+ if (null !== $data['virtual_balance']) {
+ $account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance'];
+ }
+
+ $account->save();
+
+ return $account;
}
/**
@@ -169,93 +169,6 @@ class AccountUpdateService
return AccountType::whereType($type)->first();
}
- /**
- * @param Account $account
- * @param array $data
- *
- * @return Account
- */
- private function updateAccount(Account $account, array $data): Account
- {
- // update the account itself:
- $account->name = $data['name'] ?? $account->name;
- $account->active = $data['active'] ?? $account->active;
- $account->iban = $data['iban'] ?? $account->iban;
-
- // liability stuff:
- $liabilityType = $data['liability_type'] ?? '';
- if ($this->isLiability($account) && $this->isLiabilityType($liabilityType)) {
- $type = $this->getAccountType($liabilityType);
- $account->account_type_id = $type->id;
- }
-
- // update virtual balance (could be set to zero if empty string).
- if (null !== $data['virtual_balance']) {
- $account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance'];
- }
-
- $account->save();
-
- return $account;
- }
-
- /**
- * @param Account $account
- * @param array $data
- */
- private function updatePreferences(Account $account, array $data): void
- {
- Log::debug(sprintf('Now in updatePreferences(#%d)', $account->id));
- if (array_key_exists('active', $data) && (false === $data['active'] || 0 === $data['active'])) {
- Log::debug('Account was marked as inactive.');
- $preference = app('preferences')->getForUser($account->user, 'frontpageAccounts');
- if (null !== $preference) {
- $removeAccountId = (int)$account->id;
- $array = $preference->data;
- Log::debug('Current list of accounts: ', $array);
- Log::debug(sprintf('Going to remove account #%d', $removeAccountId));
- $filtered = array_filter(
- $array, function ($accountId) use ($removeAccountId) {
- return (int)$accountId !== $removeAccountId;
- }
- );
- Log::debug('Left with accounts', array_values($filtered));
- app('preferences')->setForUser($account->user, 'frontpageAccounts', array_values($filtered));
- app('preferences')->forget($account->user, 'frontpageAccounts');
-
- return;
- }
- Log::debug("Found no frontpageAccounts preference, do nothing.");
-
- return;
- }
- Log::debug('Account was not marked as inactive, do nothing.');
- }
-
- /**
- * @param Account $account
- * @param array $data
- */
- private function updateOpeningBalance(Account $account, array $data): void
- {
-
- // has valid initial balance (IB) data?
- $type = $account->accountType;
- // if it can have a virtual balance, it can also have an opening balance.
-
- if (in_array($type->type, $this->canHaveVirtual, true)) {
-
- // check if is submitted as empty, that makes it valid:
- if ($this->validOBData($data) && !$this->isEmptyOBData($data)) {
- $this->updateOBGroup($account, $data);
- }
-
- if (!$this->validOBData($data) && $this->isEmptyOBData($data)) {
- $this->deleteOBGroup($account);
- }
- }
- }
-
/**
* @param Account $account
* @param array $data
@@ -314,4 +227,91 @@ class AccountUpdateService
return $return;
}
+
+ /**
+ * @param Account $account
+ * @param array $data
+ */
+ private function updateLocation(Account $account, array $data): void
+ {
+ $updateLocation = $data['update_location'] ?? false;
+ // location must be updated?
+ if (true === $updateLocation) {
+ // if all set to NULL, delete
+ if (null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level']) {
+ $account->locations()->delete();
+ }
+
+ // otherwise, update or create.
+ if (!(null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level'])) {
+ $location = $this->accountRepository->getLocation($account);
+ if (null === $location) {
+ $location = new Location;
+ $location->locatable()->associate($account);
+ }
+
+ $location->latitude = $data['latitude'] ?? config('firefly.default_location.latitude');
+ $location->longitude = $data['longitude'] ?? config('firefly.default_location.longitude');
+ $location->zoom_level = $data['zoom_level'] ?? config('firefly.default_location.zoom_level');
+ $location->save();
+ }
+ }
+ }
+
+ /**
+ * @param Account $account
+ * @param array $data
+ */
+ private function updateOpeningBalance(Account $account, array $data): void
+ {
+
+ // has valid initial balance (IB) data?
+ $type = $account->accountType;
+ // if it can have a virtual balance, it can also have an opening balance.
+
+ if (in_array($type->type, $this->canHaveVirtual, true)) {
+
+ // check if is submitted as empty, that makes it valid:
+ if ($this->validOBData($data) && !$this->isEmptyOBData($data)) {
+ $this->updateOBGroup($account, $data);
+ }
+
+ if (!$this->validOBData($data) && $this->isEmptyOBData($data)) {
+ $this->deleteOBGroup($account);
+ }
+ }
+ }
+
+ /**
+ * @param Account $account
+ * @param array $data
+ */
+ private function updatePreferences(Account $account, array $data): void
+ {
+ Log::debug(sprintf('Now in updatePreferences(#%d)', $account->id));
+ if (array_key_exists('active', $data) && (false === $data['active'] || 0 === $data['active'])) {
+ Log::debug('Account was marked as inactive.');
+ $preference = app('preferences')->getForUser($account->user, 'frontpageAccounts');
+ if (null !== $preference) {
+ $removeAccountId = (int)$account->id;
+ $array = $preference->data;
+ Log::debug('Current list of accounts: ', $array);
+ Log::debug(sprintf('Going to remove account #%d', $removeAccountId));
+ $filtered = array_filter(
+ $array, function ($accountId) use ($removeAccountId) {
+ return (int)$accountId !== $removeAccountId;
+ }
+ );
+ Log::debug('Left with accounts', array_values($filtered));
+ app('preferences')->setForUser($account->user, 'frontpageAccounts', array_values($filtered));
+ app('preferences')->forget($account->user, 'frontpageAccounts');
+
+ return;
+ }
+ Log::debug("Found no frontpageAccounts preference, do nothing.");
+
+ return;
+ }
+ Log::debug('Account was not marked as inactive, do nothing.');
+ }
}
diff --git a/app/Services/Internal/Update/BillUpdateService.php b/app/Services/Internal/Update/BillUpdateService.php
index ca4168ebf0..2aeffabf75 100644
--- a/app/Services/Internal/Update/BillUpdateService.php
+++ b/app/Services/Internal/Update/BillUpdateService.php
@@ -136,6 +136,69 @@ class BillUpdateService
return $bill;
}
+ /**
+ * @param Bill $bill
+ * @param array $data
+ *
+ * @return Bill
+ */
+ private function updateBillProperties(Bill $bill, array $data): Bill
+ {
+
+ if (isset($data['name']) && '' !== (string)$data['name']) {
+ $bill->name = $data['name'];
+ }
+
+ if (isset($data['amount_min']) && '' !== (string)$data['amount_min']) {
+ $bill->amount_min = $data['amount_min'];
+ }
+ if (isset($data['amount_max']) && '' !== (string)$data['amount_max']) {
+ $bill->amount_max = $data['amount_max'];
+ }
+ if (isset($data['date']) && '' !== (string)$data['date']) {
+ $bill->date = $data['date'];
+ }
+ if (isset($data['repeat_freq']) && '' !== (string)$data['repeat_freq']) {
+ $bill->repeat_freq = $data['repeat_freq'];
+ }
+ if (isset($data['skip']) && '' !== (string)$data['skip']) {
+ $bill->skip = $data['skip'];
+ }
+ if (isset($data['active']) && is_bool($data['active'])) {
+ $bill->active = $data['active'];
+ }
+
+ $bill->match = 'EMPTY';
+ $bill->automatch = true;
+ $bill->save();
+
+ return $bill;
+ }
+
+ /**
+ * @param Bill $bill
+ * @param int $oldOrder
+ * @param int $newOrder
+ */
+ private function updateOrder(Bill $bill, int $oldOrder, int $newOrder): void
+ {
+ if ($newOrder > $oldOrder) {
+ $this->user->bills()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder)
+ ->where('bills.id', '!=', $bill->id)
+ ->update(['order' => DB::raw('bills.order-1')]);
+ $bill->order = $newOrder;
+ $bill->save();
+ }
+ if ($newOrder < $oldOrder) {
+ $this->user->bills()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder)
+ ->where('bills.id', '!=', $bill->id)
+ ->update(['order' => DB::raw('bills.order+1')]);
+ $bill->order = $newOrder;
+ $bill->save();
+ }
+
+ }
+
/**
* @param Bill $bill
* @param array $oldData
@@ -195,7 +258,6 @@ class BillUpdateService
}
}
-
/**
* @param Rule $rule
* @param string $key
@@ -206,67 +268,4 @@ class BillUpdateService
{
return $rule->ruleTriggers()->where('trigger_type', $key)->first();
}
-
- /**
- * @param Bill $bill
- * @param int $oldOrder
- * @param int $newOrder
- */
- private function updateOrder(Bill $bill, int $oldOrder, int $newOrder): void
- {
- if ($newOrder > $oldOrder) {
- $this->user->bills()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder)
- ->where('bills.id', '!=', $bill->id)
- ->update(['order' => DB::raw('bills.order-1')]);
- $bill->order = $newOrder;
- $bill->save();
- }
- if ($newOrder < $oldOrder) {
- $this->user->bills()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder)
- ->where('bills.id', '!=', $bill->id)
- ->update(['order' => DB::raw('bills.order+1')]);
- $bill->order = $newOrder;
- $bill->save();
- }
-
- }
-
- /**
- * @param Bill $bill
- * @param array $data
- *
- * @return Bill
- */
- private function updateBillProperties(Bill $bill, array $data): Bill
- {
-
- if (isset($data['name']) && '' !== (string)$data['name']) {
- $bill->name = $data['name'];
- }
-
- if (isset($data['amount_min']) && '' !== (string)$data['amount_min']) {
- $bill->amount_min = $data['amount_min'];
- }
- if (isset($data['amount_max']) && '' !== (string)$data['amount_max']) {
- $bill->amount_max = $data['amount_max'];
- }
- if (isset($data['date']) && '' !== (string)$data['date']) {
- $bill->date = $data['date'];
- }
- if (isset($data['repeat_freq']) && '' !== (string)$data['repeat_freq']) {
- $bill->repeat_freq = $data['repeat_freq'];
- }
- if (isset($data['skip']) && '' !== (string)$data['skip']) {
- $bill->skip = $data['skip'];
- }
- if (isset($data['active']) && is_bool($data['active'])) {
- $bill->active = $data['active'];
- }
-
- $bill->match = 'EMPTY';
- $bill->automatch = true;
- $bill->save();
-
- return $bill;
- }
}
diff --git a/app/Services/Internal/Update/CategoryUpdateService.php b/app/Services/Internal/Update/CategoryUpdateService.php
index aa78e1161a..5a00fd9da5 100644
--- a/app/Services/Internal/Update/CategoryUpdateService.php
+++ b/app/Services/Internal/Update/CategoryUpdateService.php
@@ -23,13 +23,13 @@ declare(strict_types=1);
namespace FireflyIII\Services\Internal\Update;
+use Exception;
use FireflyIII\Models\Category;
use FireflyIII\Models\Note;
use FireflyIII\Models\RecurrenceTransactionMeta;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleTrigger;
use Log;
-use Exception;
/**
* Class CategoryUpdateService
@@ -54,6 +54,14 @@ class CategoryUpdateService
}
}
+ /**
+ * @param mixed $user
+ */
+ public function setUser($user): void
+ {
+ $this->user = $user;
+ }
+
/**
* @param Category $category
* @param array $data
@@ -75,27 +83,6 @@ class CategoryUpdateService
return $category;
}
- /**
- * @param string $oldName
- * @param string $newName
- */
- private function updateRuleActions(string $oldName, string $newName): void
- {
- $types = ['set_category',];
- $actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id')
- ->where('rules.user_id', $this->user->id)
- ->whereIn('rule_actions.action_type', $types)
- ->where('rule_actions.action_value', $oldName)
- ->get(['rule_actions.*']);
- Log::debug(sprintf('Found %d actions to update.', $actions->count()));
- /** @var RuleAction $action */
- foreach ($actions as $action) {
- $action->action_value = $newName;
- $action->save();
- Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value));
- }
- }
-
/**
* @param string $oldName
* @param string $newName
@@ -118,11 +105,24 @@ class CategoryUpdateService
}
/**
- * @param mixed $user
+ * @param string $oldName
+ * @param string $newName
*/
- public function setUser($user): void
+ private function updateRuleActions(string $oldName, string $newName): void
{
- $this->user = $user;
+ $types = ['set_category',];
+ $actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id')
+ ->where('rules.user_id', $this->user->id)
+ ->whereIn('rule_actions.action_type', $types)
+ ->where('rule_actions.action_value', $oldName)
+ ->get(['rule_actions.*']);
+ Log::debug(sprintf('Found %d actions to update.', $actions->count()));
+ /** @var RuleAction $action */
+ foreach ($actions as $action) {
+ $action->action_value = $newName;
+ $action->save();
+ Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value));
+ }
}
/**
@@ -145,7 +145,7 @@ class CategoryUpdateService
* @param Category $category
* @param array $data
*
- * @throws \Exception
+ * @throws Exception
*/
private function updateNotes(Category $category, array $data): void
{
diff --git a/app/Services/Internal/Update/GroupCloneService.php b/app/Services/Internal/Update/GroupCloneService.php
index e5fb261197..81abc35a3f 100644
--- a/app/Services/Internal/Update/GroupCloneService.php
+++ b/app/Services/Internal/Update/GroupCloneService.php
@@ -108,16 +108,15 @@ class GroupCloneService
}
/**
- * @param TransactionJournalMeta $meta
- * @param TransactionJournal $newJournal
+ * @param Transaction $transaction
+ * @param TransactionJournal $newJournal
*/
- private function cloneMeta(TransactionJournalMeta $meta, TransactionJournal $newJournal): void
+ private function cloneTransaction(Transaction $transaction, TransactionJournal $newJournal): void
{
- $newMeta = $meta->replicate();
- $newMeta->transaction_journal_id = $newJournal->id;
- if ('recurrence_id' !== $newMeta->name) {
- $newMeta->save();
- }
+ $newTransaction = $transaction->replicate();
+ $newTransaction->transaction_journal_id = $newJournal->id;
+ $newTransaction->reconciled = false;
+ $newTransaction->save();
}
/**
@@ -137,15 +136,16 @@ class GroupCloneService
}
/**
- * @param Transaction $transaction
- * @param TransactionJournal $newJournal
+ * @param TransactionJournalMeta $meta
+ * @param TransactionJournal $newJournal
*/
- private function cloneTransaction(Transaction $transaction, TransactionJournal $newJournal): void
+ private function cloneMeta(TransactionJournalMeta $meta, TransactionJournal $newJournal): void
{
- $newTransaction = $transaction->replicate();
- $newTransaction->transaction_journal_id = $newJournal->id;
- $newTransaction->reconciled = false;
- $newTransaction->save();
+ $newMeta = $meta->replicate();
+ $newMeta->transaction_journal_id = $newJournal->id;
+ if ('recurrence_id' !== $newMeta->name) {
+ $newMeta->save();
+ }
}
diff --git a/app/Services/Internal/Update/GroupUpdateService.php b/app/Services/Internal/Update/GroupUpdateService.php
index d6ae83693e..0c7bf27885 100644
--- a/app/Services/Internal/Update/GroupUpdateService.php
+++ b/app/Services/Internal/Update/GroupUpdateService.php
@@ -96,37 +96,6 @@ class GroupUpdateService
return $transactionGroup;
}
- /**
- * @param TransactionGroup $transactionGroup
- * @param array $data
- *
- * @throws FireflyException
- */
- private function createTransactionJournal(TransactionGroup $transactionGroup, array $data): void
- {
-
- $submission = [
- 'transactions' => [
- $data,
- ],
- ];
- /** @var TransactionJournalFactory $factory */
- $factory = app(TransactionJournalFactory::class);
- $factory->setUser($transactionGroup->user);
- try {
- $collection = $factory->create($submission);
- } catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
- throw new FireflyException(sprintf('Could not create new transaction journal: %s', $e->getMessage()));
- }
- $collection->each(
- function (TransactionJournal $journal) use ($transactionGroup) {
- $transactionGroup->transactionJournals()->save($journal);
- }
- );
- }
-
/**
* Update single journal.
*
@@ -191,4 +160,35 @@ class GroupUpdateService
return $updated;
}
+ /**
+ * @param TransactionGroup $transactionGroup
+ * @param array $data
+ *
+ * @throws FireflyException
+ */
+ private function createTransactionJournal(TransactionGroup $transactionGroup, array $data): void
+ {
+
+ $submission = [
+ 'transactions' => [
+ $data,
+ ],
+ ];
+ /** @var TransactionJournalFactory $factory */
+ $factory = app(TransactionJournalFactory::class);
+ $factory->setUser($transactionGroup->user);
+ try {
+ $collection = $factory->create($submission);
+ } catch (FireflyException $e) {
+ Log::error($e->getMessage());
+ Log::error($e->getTraceAsString());
+ throw new FireflyException(sprintf('Could not create new transaction journal: %s', $e->getMessage()));
+ }
+ $collection->each(
+ function (TransactionJournal $journal) use ($transactionGroup) {
+ $transactionGroup->transactionJournals()->save($journal);
+ }
+ );
+ }
+
}
diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php
index ee893e6154..5394209ba8 100644
--- a/app/Services/Internal/Update/JournalUpdateService.php
+++ b/app/Services/Internal/Update/JournalUpdateService.php
@@ -161,47 +161,61 @@ class JournalUpdateService
}
/**
- * Get destination transaction.
- *
- * @return Transaction
+ * @return bool
*/
- private function getDestinationTransaction(): Transaction
+ private function hasValidAccounts(): bool
{
- if (null === $this->destinationTransaction) {
- $this->destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first();
- }
-
- return $this->destinationTransaction;
+ return $this->hasValidSourceAccount() && $this->hasValidDestinationAccount();
}
/**
- * This method returns the current or expected type of the journal (in case of a change) based on the data in the array.
- *
- * If the array contains key 'type' and the value is correct, this is returned. Otherwise, the original type is returned.
- *
- * @return string
+ * @return bool
*/
- private function getExpectedType(): string
+ private function hasValidSourceAccount(): bool
{
- Log::debug('Now in getExpectedType()');
- if ($this->hasFields(['type'])) {
- return ucfirst('opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']);
+ Log::debug('Now in hasValidSourceAccount().');
+ $sourceId = $this->data['source_id'] ?? null;
+ $sourceName = $this->data['source_name'] ?? null;
+
+ if (!$this->hasFields(['source_id', 'source_name'])) {
+ $origSourceAccount = $this->getOriginalSourceAccount();
+ $sourceId = $origSourceAccount->id;
+ $sourceName = $origSourceAccount->name;
}
- return $this->transactionJournal->transactionType->type;
+ // make new account validator.
+ $expectedType = $this->getExpectedType();
+ Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
+
+ // make a new validator.
+ /** @var AccountValidator $validator */
+ $validator = app(AccountValidator::class);
+ $validator->setTransactionType($expectedType);
+ $validator->setUser($this->transactionJournal->user);
+
+ $result = $validator->validateSource($sourceId, $sourceName, null);
+ Log::debug(sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true)));
+
+ // TODO typeOverrule: the account validator may have another opinion on the transaction type.
+
+ // validate submitted info:
+ return $result;
}
/**
- * @return Account
+ * @param array $fields
+ *
+ * @return bool
*/
- private function getOriginalDestinationAccount(): Account
+ private function hasFields(array $fields): bool
{
- if (null === $this->destinationAccount) {
- $destination = $this->getDestinationTransaction();
- $this->destinationAccount = $destination->account;
+ foreach ($fields as $field) {
+ if (array_key_exists($field, $this->data)) {
+ return true;
+ }
}
- return $this->destinationAccount;
+ return false;
}
/**
@@ -231,96 +245,20 @@ class JournalUpdateService
}
/**
- * Does a validation and returns the destination account. This method will break if the dest isn't really valid.
+ * This method returns the current or expected type of the journal (in case of a change) based on the data in the array.
*
- * @return Account
- */
- private function getValidDestinationAccount(): Account
- {
- Log::debug('Now in getValidDestinationAccount().');
-
- if (!$this->hasFields(['destination_id', 'destination_name'])) {
- return $this->getOriginalDestinationAccount();
- }
-
- $destInfo = [
- 'id' => (int)($this->data['destination_id'] ?? null),
- 'name' => $this->data['destination_name'] ?? null,
- 'iban' => $this->data['destination_iban'] ?? null,
- 'number' => $this->data['destination_number'] ?? null,
- 'bic' => $this->data['destination_bic'] ?? null,
- ];
-
- // make new account validator.
- $expectedType = $this->getExpectedType();
- Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
- try {
- $result = $this->getAccount($expectedType, 'destination', $destInfo);
- } catch (FireflyException $e) {
- Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage()));
- $result = $this->getOriginalDestinationAccount();
- }
-
- return $result;
- }
-
- /**
- * Does a validation and returns the source account. This method will break if the source isn't really valid.
+ * If the array contains key 'type' and the value is correct, this is returned. Otherwise, the original type is returned.
*
- * @return Account
+ * @return string
*/
- private function getValidSourceAccount(): Account
+ private function getExpectedType(): string
{
- Log::debug('Now in getValidSourceAccount().');
-
- if (!$this->hasFields(['source_id', 'source_name'])) {
- return $this->getOriginalSourceAccount();
+ Log::debug('Now in getExpectedType()');
+ if ($this->hasFields(['type'])) {
+ return ucfirst('opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']);
}
- $sourceInfo = [
- 'id' => (int)($this->data['source_id'] ?? null),
- 'name' => $this->data['source_name'] ?? null,
- 'iban' => $this->data['source_iban'] ?? null,
- 'number' => $this->data['source_number'] ?? null,
- 'bic' => $this->data['source_bic'] ?? null,
- ];
-
- $expectedType = $this->getExpectedType();
- try {
- $result = $this->getAccount($expectedType, 'source', $sourceInfo);
- } catch (FireflyException $e) {
- Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage()));
-
- $result = $this->getOriginalSourceAccount();
- }
-
- Log::debug(sprintf('getValidSourceAccount() will return #%d ("%s")', $result->id, $result->name));
-
- return $result;
- }
-
- /**
- * @param array $fields
- *
- * @return bool
- */
- private function hasFields(array $fields): bool
- {
- foreach ($fields as $field) {
- if (array_key_exists($field, $this->data)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * @return bool
- */
- private function hasValidAccounts(): bool
- {
- return $this->hasValidSourceAccount() && $this->hasValidDestinationAccount();
+ return $this->transactionJournal->transactionType->type;
}
/**
@@ -361,36 +299,64 @@ class JournalUpdateService
}
/**
- * @return bool
+ * @return Account
*/
- private function hasValidSourceAccount(): bool
+ private function getOriginalDestinationAccount(): Account
{
- Log::debug('Now in hasValidSourceAccount().');
- $sourceId = $this->data['source_id'] ?? null;
- $sourceName = $this->data['source_name'] ?? null;
-
- if (!$this->hasFields(['source_id', 'source_name'])) {
- $origSourceAccount = $this->getOriginalSourceAccount();
- $sourceId = $origSourceAccount->id;
- $sourceName = $origSourceAccount->name;
+ if (null === $this->destinationAccount) {
+ $destination = $this->getDestinationTransaction();
+ $this->destinationAccount = $destination->account;
}
- // make new account validator.
+ return $this->destinationAccount;
+ }
+
+ /**
+ * Get destination transaction.
+ *
+ * @return Transaction
+ */
+ private function getDestinationTransaction(): Transaction
+ {
+ if (null === $this->destinationTransaction) {
+ $this->destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first();
+ }
+
+ return $this->destinationTransaction;
+ }
+
+ /**
+ * Does a validation and returns the source account. This method will break if the source isn't really valid.
+ *
+ * @return Account
+ */
+ private function getValidSourceAccount(): Account
+ {
+ Log::debug('Now in getValidSourceAccount().');
+
+ if (!$this->hasFields(['source_id', 'source_name'])) {
+ return $this->getOriginalSourceAccount();
+ }
+
+ $sourceInfo = [
+ 'id' => (int)($this->data['source_id'] ?? null),
+ 'name' => $this->data['source_name'] ?? null,
+ 'iban' => $this->data['source_iban'] ?? null,
+ 'number' => $this->data['source_number'] ?? null,
+ 'bic' => $this->data['source_bic'] ?? null,
+ ];
+
$expectedType = $this->getExpectedType();
- Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
+ try {
+ $result = $this->getAccount($expectedType, 'source', $sourceInfo);
+ } catch (FireflyException $e) {
+ Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage()));
- // make a new validator.
- /** @var AccountValidator $validator */
- $validator = app(AccountValidator::class);
- $validator->setTransactionType($expectedType);
- $validator->setUser($this->transactionJournal->user);
+ $result = $this->getOriginalSourceAccount();
+ }
- $result = $validator->validateSource($sourceId, $sourceName, null);
- Log::debug(sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true)));
+ Log::debug(sprintf('getValidSourceAccount() will return #%d ("%s")', $result->id, $result->name));
- // TODO typeOverrule: the account validator may have another opinion on the transaction type.
-
- // validate submitted info:
return $result;
}
@@ -427,36 +393,68 @@ class JournalUpdateService
}
/**
+ * Does a validation and returns the destination account. This method will break if the dest isn't really valid.
*
+ * @return Account
*/
- private function updateAmount(): void
+ private function getValidDestinationAccount(): Account
{
- if (!$this->hasFields(['amount'])) {
- return;
+ Log::debug('Now in getValidDestinationAccount().');
+
+ if (!$this->hasFields(['destination_id', 'destination_name'])) {
+ return $this->getOriginalDestinationAccount();
}
- $value = $this->data['amount'] ?? '';
+ $destInfo = [
+ 'id' => (int)($this->data['destination_id'] ?? null),
+ 'name' => $this->data['destination_name'] ?? null,
+ 'iban' => $this->data['destination_iban'] ?? null,
+ 'number' => $this->data['destination_number'] ?? null,
+ 'bic' => $this->data['destination_bic'] ?? null,
+ ];
+
+ // make new account validator.
+ $expectedType = $this->getExpectedType();
+ Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
try {
- $amount = $this->getAmount($value);
+ $result = $this->getAccount($expectedType, 'destination', $destInfo);
} catch (FireflyException $e) {
- Log::debug(sprintf('getAmount("%s") returns error: %s', $value, $e->getMessage()));
+ Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage()));
+ $result = $this->getOriginalDestinationAccount();
+ }
+
+ return $result;
+ }
+
+ /**
+ * Updates journal transaction type.
+ */
+ private function updateType(): void
+ {
+ Log::debug('Now in updateType()');
+ if ($this->hasFields(['type'])) {
+ $type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
+ Log::debug(
+ sprintf(
+ 'Trying to change journal #%d from a %s to a %s.',
+ $this->transactionJournal->id, $this->transactionJournal->transactionType->type, $type
+ )
+ );
+
+ /** @var TransactionTypeFactory $typeFactory */
+ $typeFactory = app(TransactionTypeFactory::class);
+ $result = $typeFactory->find($this->data['type']);
+ if (null !== $result) {
+ Log::debug('Changed transaction type!');
+ $this->transactionJournal->transaction_type_id = $result->id;
+ $this->transactionJournal->save();
+
+ return;
+ }
return;
}
- $origSourceTransaction = $this->getSourceTransaction();
- $origSourceTransaction->amount = app('steam')->negative($amount);
- $origSourceTransaction->save();
-
-
- $destTransaction = $this->getDestinationTransaction();
- $destTransaction->amount = app('steam')->positive($amount);
- $destTransaction->save();
-
-
- // refresh transactions.
- $this->sourceTransaction->refresh();
- $this->destinationTransaction->refresh();
- Log::debug(sprintf('Updated amount to "%s"', $amount));
+ Log::debug('No type field present.');
}
/**
@@ -479,6 +477,47 @@ class JournalUpdateService
}
}
+ /**
+ * Update journal generic field. Cannot be set to NULL.
+ *
+ * @param string $fieldName
+ */
+ private function updateField(string $fieldName): void
+ {
+ if (array_key_exists($fieldName, $this->data) && '' !== (string)$this->data[$fieldName]) {
+ $value = $this->data[$fieldName];
+
+ if ('date' === $fieldName) {
+ if ($value instanceof Carbon) {
+ // update timezone.
+ $value->setTimezone(config('app.timezone'));
+ }
+ if (!($value instanceof Carbon)) {
+ $value = new Carbon($value);
+ }
+ // do some parsing.
+ Log::debug(sprintf('Create date value from string "%s".', $value));
+ }
+
+
+ $this->transactionJournal->$fieldName = $value;
+ Log::debug(sprintf('Updated %s', $fieldName));
+ }
+ }
+
+ /**
+ *
+ */
+ private function updateCategory(): void
+ {
+ // update category
+ if ($this->hasFields(['category_id', 'category_name'])) {
+ Log::debug('Will update category.');
+
+ $this->storeCategory($this->transactionJournal, new NullArrayObject($this->data));
+ }
+ }
+
/**
*
*/
@@ -494,13 +533,103 @@ class JournalUpdateService
/**
*
*/
- private function updateCategory(): void
+ private function updateTags(): void
{
- // update category
- if ($this->hasFields(['category_id', 'category_name'])) {
- Log::debug('Will update category.');
+ if ($this->hasFields(['tags'])) {
+ Log::debug('Will update tags.');
+ $tags = $this->data['tags'] ?? null;
+ $this->storeTags($this->transactionJournal, $tags);
+ }
+ }
- $this->storeCategory($this->transactionJournal, new NullArrayObject($this->data));
+ /**
+ *
+ */
+ private function updateReconciled(): void
+ {
+ if (array_key_exists('reconciled', $this->data) && is_bool($this->data['reconciled'])) {
+ $this->transactionJournal->transactions()->update(['reconciled' => $this->data['reconciled']]);
+ }
+ }
+
+ /**
+ *
+ */
+ private function updateNotes(): void
+ {
+ // update notes.
+ if ($this->hasFields(['notes'])) {
+ $notes = '' === (string)$this->data['notes'] ? null : $this->data['notes'];
+ $this->storeNotes($this->transactionJournal, $notes);
+ }
+ }
+
+ /**
+ *
+ */
+ private function updateMeta(): void
+ {
+ // update meta fields.
+ // first string
+ if ($this->hasFields($this->metaString)) {
+ Log::debug('Meta string fields are present.');
+ $this->updateMetaFields();
+ }
+
+ // then date fields.
+ if ($this->hasFields($this->metaDate)) {
+ Log::debug('Meta date fields are present.');
+ $this->updateMetaDateFields();
+ }
+ }
+
+ /**
+ *
+ */
+ private function updateMetaFields(): void
+ {
+ /** @var TransactionJournalMetaFactory $factory */
+ $factory = app(TransactionJournalMetaFactory::class);
+
+ foreach ($this->metaString as $field) {
+ if ($this->hasFields([$field])) {
+ $value = '' === $this->data[$field] ? null : $this->data[$field];
+ Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
+ $set = [
+ 'journal' => $this->transactionJournal,
+ 'name' => $field,
+ 'data' => $value,
+ ];
+ $factory->updateOrCreate($set);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private function updateMetaDateFields(): void
+ {
+ /** @var TransactionJournalMetaFactory $factory */
+ $factory = app(TransactionJournalMetaFactory::class);
+
+ foreach ($this->metaDate as $field) {
+ if ($this->hasFields([$field])) {
+ try {
+ $value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
+ } catch (Exception $e) {
+ Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
+
+ return;
+ }
+ Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
+ $set = [
+ 'journal' => $this->transactionJournal,
+ 'name' => $field,
+ 'data' => $value,
+ ];
+ $factory->updateOrCreate($set);
+ }
}
}
@@ -537,33 +666,37 @@ class JournalUpdateService
}
/**
- * Update journal generic field. Cannot be set to NULL.
*
- * @param string $fieldName
*/
- private function updateField(string $fieldName): void
+ private function updateAmount(): void
{
- if (array_key_exists($fieldName, $this->data) && '' !== (string)$this->data[$fieldName]) {
- $value = $this->data[$fieldName];
-
- if ('date' === $fieldName) {
- if ($value instanceof Carbon) {
- // update timezone.
- $value->setTimezone(config('app.timezone'));
- }
- if (!($value instanceof Carbon)) {
- $value = new Carbon($value);
- }
- // do some parsing.
- Log::debug(sprintf('Create date value from string "%s".', $value));
- }
-
-
- $this->transactionJournal->$fieldName = $value;
- Log::debug(sprintf('Updated %s', $fieldName));
+ if (!$this->hasFields(['amount'])) {
+ return;
}
- }
+ $value = $this->data['amount'] ?? '';
+ try {
+ $amount = $this->getAmount($value);
+ } catch (FireflyException $e) {
+ Log::debug(sprintf('getAmount("%s") returns error: %s', $value, $e->getMessage()));
+
+ return;
+ }
+ $origSourceTransaction = $this->getSourceTransaction();
+ $origSourceTransaction->amount = app('steam')->negative($amount);
+ $origSourceTransaction->save();
+
+
+ $destTransaction = $this->getDestinationTransaction();
+ $destTransaction->amount = app('steam')->positive($amount);
+ $destTransaction->save();
+
+
+ // refresh transactions.
+ $this->sourceTransaction->refresh();
+ $this->destinationTransaction->refresh();
+ Log::debug(sprintf('Updated amount to "%s"', $amount));
+ }
/**
*
@@ -628,138 +761,4 @@ class JournalUpdateService
$this->sourceTransaction->refresh();
$this->destinationTransaction->refresh();
}
-
- /**
- *
- */
- private function updateMeta(): void
- {
- // update meta fields.
- // first string
- if ($this->hasFields($this->metaString)) {
- Log::debug('Meta string fields are present.');
- $this->updateMetaFields();
- }
-
- // then date fields.
- if ($this->hasFields($this->metaDate)) {
- Log::debug('Meta date fields are present.');
- $this->updateMetaDateFields();
- }
- }
-
- /**
- *
- */
- private function updateMetaDateFields(): void
- {
- /** @var TransactionJournalMetaFactory $factory */
- $factory = app(TransactionJournalMetaFactory::class);
-
- foreach ($this->metaDate as $field) {
- if ($this->hasFields([$field])) {
- try {
- $value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
- } catch (Exception $e) {
- Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
-
- return;
- }
- Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
- $set = [
- 'journal' => $this->transactionJournal,
- 'name' => $field,
- 'data' => $value,
- ];
- $factory->updateOrCreate($set);
- }
- }
- }
-
- /**
- *
- */
- private function updateMetaFields(): void
- {
- /** @var TransactionJournalMetaFactory $factory */
- $factory = app(TransactionJournalMetaFactory::class);
-
- foreach ($this->metaString as $field) {
- if ($this->hasFields([$field])) {
- $value = '' === $this->data[$field] ? null : $this->data[$field];
- Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
- $set = [
- 'journal' => $this->transactionJournal,
- 'name' => $field,
- 'data' => $value,
- ];
- $factory->updateOrCreate($set);
- }
- }
- }
-
- /**
- *
- */
- private function updateNotes(): void
- {
- // update notes.
- if ($this->hasFields(['notes'])) {
- $notes = '' === (string)$this->data['notes'] ? null : $this->data['notes'];
- $this->storeNotes($this->transactionJournal, $notes);
- }
- }
-
- /**
- *
- */
- private function updateTags(): void
- {
- if ($this->hasFields(['tags'])) {
- Log::debug('Will update tags.');
- $tags = $this->data['tags'] ?? null;
- $this->storeTags($this->transactionJournal, $tags);
- }
- }
-
- /**
- * Updates journal transaction type.
- */
- private function updateType(): void
- {
- Log::debug('Now in updateType()');
- if ($this->hasFields(['type'])) {
- $type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
- Log::debug(
- sprintf(
- 'Trying to change journal #%d from a %s to a %s.',
- $this->transactionJournal->id, $this->transactionJournal->transactionType->type, $type
- )
- );
-
- /** @var TransactionTypeFactory $typeFactory */
- $typeFactory = app(TransactionTypeFactory::class);
- $result = $typeFactory->find($this->data['type']);
- if (null !== $result) {
- Log::debug('Changed transaction type!');
- $this->transactionJournal->transaction_type_id = $result->id;
- $this->transactionJournal->save();
-
- return;
- }
-
- return;
- }
- Log::debug('No type field present.');
- }
-
- /**
- *
- */
- private function updateReconciled(): void
- {
- if (array_key_exists('reconciled', $this->data) && is_bool($this->data['reconciled'])) {
- $this->transactionJournal->transactions()->update(['reconciled' => $this->data['reconciled']]);
- }
- }
}
diff --git a/app/Services/Internal/Update/RecurrenceUpdateService.php b/app/Services/Internal/Update/RecurrenceUpdateService.php
index 775bb79c7d..714b6e0e99 100644
--- a/app/Services/Internal/Update/RecurrenceUpdateService.php
+++ b/app/Services/Internal/Update/RecurrenceUpdateService.php
@@ -27,6 +27,7 @@ use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Note;
use FireflyIII\Models\Recurrence;
+use FireflyIII\Models\RecurrenceRepetition;
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
use FireflyIII\User;
@@ -56,53 +57,55 @@ class RecurrenceUpdateService
*/
public function update(Recurrence $recurrence, array $data): Recurrence
{
- $this->user = $recurrence->user;
- $transactionType = $recurrence->transactionType;
- if (isset($data['recurrence']['type'])) {
- $transactionType = $this->findTransactionType(ucfirst($data['recurrence']['type']));
- }
+ $this->user = $recurrence->user;
// update basic fields first:
- $recurrence->transaction_type_id = $transactionType->id;
- $recurrence->title = $data['recurrence']['title'] ?? $recurrence->title;
- $recurrence->description = $data['recurrence']['description'] ?? $recurrence->description;
- $recurrence->first_date = $data['recurrence']['first_date'] ?? $recurrence->first_date;
- $recurrence->repeat_until = $data['recurrence']['repeat_until'] ?? $recurrence->repeat_until;
- $recurrence->repetitions = $data['recurrence']['nr_of_repetitions'] ?? $recurrence->repetitions;
- $recurrence->apply_rules = $data['recurrence']['apply_rules'] ?? $recurrence->apply_rules;
- $recurrence->active = $data['recurrence']['active'] ?? $recurrence->active;
- // if nr_of_repetitions is set, then drop the "repeat_until" field.
- if (0 !== $recurrence->repetitions) {
- $recurrence->repeat_until = null;
- }
-
- if (isset($data['recurrence']['repetition_end'])) {
- if (in_array($data['recurrence']['repetition_end'], ['forever', 'until_date'])) {
- $recurrence->repetitions = 0;
+ if (array_key_exists('recurrence', $data)) {
+ $info = $data['recurrence'];
+ if (array_key_exists('title', $info)) {
+ $recurrence->title = $info['title'];
}
- if (in_array($data['recurrence']['repetition_end'], ['forever', 'times'])) {
- $recurrence->repeat_until = null;
+ if (array_key_exists('description', $info)) {
+ $recurrence->description = $info['description'];
+ }
+ if (array_key_exists('first_date', $info)) {
+ $recurrence->first_date = $info['first_date'];
+ }
+ if (array_key_exists('repeat_until', $info)) {
+ $recurrence->repeat_until = $info['repeat_until'];
+ $recurrence->repetitions = 0;
+ }
+ if (array_key_exists('nr_of_repetitions', $info)) {
+ if (0 !== (int)$info['nr_of_repetitions']) {
+ $recurrence->repeat_until = null;
+ }
+ $recurrence->repetitions = $info['nr_of_repetitions'];
+ }
+ if (array_key_exists('apply_rules', $info)) {
+ $recurrence->apply_rules = $info['apply_rules'];
+ }
+ if (array_key_exists('active', $info)) {
+ $recurrence->active = $info['active'];
+ }
+ // update all meta data:
+ if (array_key_exists('notes', $info)) {
+ $this->setNoteText($recurrence, $info['notes']);
}
}
$recurrence->save();
- // update all meta data:
-
- if (isset($data['recurrence']['notes']) && null !== $data['recurrence']['notes']) {
- $this->setNoteText($recurrence, $data['recurrence']['notes']);
- }
-
// update all repetitions
- if (null !== $data['repetitions']) {
- $this->deleteRepetitions($recurrence);
- $this->createRepetitions($recurrence, $data['repetitions'] ?? []);
+ if (array_key_exists('repetitions', $data)) {
+ Log::debug('Will update repetitions array');
+ // update each repetition or throw error yay
+ $this->updateRepetitions($recurrence, $data['repetitions'] ?? []);
}
- // update all transactions (and associated meta-data)
- if (null !== $data['transactions']) {
- $this->deleteTransactions($recurrence);
- $this->createTransactions($recurrence, $data['transactions'] ?? []);
- }
+// // update all transactions (and associated meta-data)
+// if (array_key_exists('transactions', $data)) {
+// $this->deleteTransactions($recurrence);
+// $this->createTransactions($recurrence, $data['transactions'] ?? []);
+// }
return $recurrence;
}
@@ -133,4 +136,76 @@ class RecurrenceUpdateService
}
}
+
+ /**
+ *
+ * @param Recurrence $recurrence
+ * @param array $repetitions
+ */
+ private function updateRepetitions(Recurrence $recurrence, array $repetitions): void
+ {
+ $originalCount = $recurrence->recurrenceRepetitions()->count();
+ if (0 === count($repetitions)) {
+ // wont drop repetition, rather avoid.
+ return;
+ }
+ // user added or removed repetitions, delete all and recreate:
+ if ($originalCount !== count($repetitions)) {
+ Log::debug('Del + recreate');
+ $this->deleteRepetitions($recurrence);
+ $this->createRepetitions($recurrence, $repetitions);
+
+ return;
+ }
+ // loop all and try to match them:
+ if ($originalCount === count($repetitions)) {
+ Log::debug('Loop and find');
+ foreach ($repetitions as $current) {
+ $match = $this->matchRepetition($recurrence, $current);
+ if (null === $match) {
+ throw new FireflyException('Cannot match recurring repetition to existing repetition. Not sure what to do. Break.');
+ }
+ $fields = [
+ 'type' => 'repetition_type',
+ 'moment' => 'repetition_moment',
+ 'skip' => 'repetition_skip',
+ 'weekend' => 'weekend',];
+ foreach ($fields as $field => $column) {
+ if (array_key_exists($field, $current)) {
+ $match->$column = $current[$field];
+ $match->save();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return RecurrenceRepetition|null
+ */
+ private function matchRepetition(Recurrence $recurrence, array $data): ?RecurrenceRepetition
+ {
+ $originalCount = $recurrence->recurrenceRepetitions()->count();
+ if (1 === $originalCount) {
+ Log::debug('Return the first one');
+ return $recurrence->recurrenceRepetitions()->first();
+ }
+ // find it:
+ $fields = ['id' => 'id',
+ 'type' => 'repetition_type',
+ 'moment' => 'repetition_moment',
+ 'skip' => 'repetition_skip',
+ 'weekend' => 'weekend',
+ ];
+ $query = $recurrence->recurrenceRepetitions();
+ foreach ($fields as $field => $column) {
+ if (array_key_exists($field, $data)) {
+ $query->where($column, $data[$field]);
+ }
+ }
+
+ return $query->first();
+ }
}
diff --git a/app/Validation/RecurrenceValidation.php b/app/Validation/RecurrenceValidation.php
index 6a067d26e4..9c37f84367 100644
--- a/app/Validation/RecurrenceValidation.php
+++ b/app/Validation/RecurrenceValidation.php
@@ -154,7 +154,10 @@ trait RecurrenceValidation
* @var array $repetition
*/
foreach ($repetitions as $index => $repetition) {
- if(null === $repetition['moment']) {
+ if (!array_key_exists('moment', $repetition)) {
+ continue;
+ }
+ if (null === $repetition['moment']) {
$repetition['moment'] = '';
}
$repetition['moment'] = $repetition['moment'] ?? 'invalid';
diff --git a/tests/Api/Autocomplete/AccountControllerTest.php b/tests/Api/Autocomplete/AccountControllerTest.php
new file mode 100644
index 0000000000..857436c5b8
--- /dev/null
+++ b/tests/Api/Autocomplete/AccountControllerTest.php
@@ -0,0 +1,63 @@
+.
+ */
+
+namespace Tests\Api\Autocomplete;
+
+
+use Tests\TestCase;
+use Laravel\Passport\Passport;
+use Log;
+
+/**
+ * Class AccountControllerTest
+ */
+class AccountControllerTest extends TestCase
+{
+ /**
+ *
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+ Passport::actingAs($this->user());
+ Log::info(sprintf('Now in %s.', get_class($this)));
+ }
+
+ /**
+ *
+ */
+ public function testBasic(): void
+ {
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @covers \FireflyIII\Api\V1\Controllers\Autocomplete\AccountController
+ */
+ public function testAccounts(): void
+ {
+ // test API
+ $response = $this->get(route('api.v1.autocomplete.accounts'), ['Accept' => 'application/json']);
+ $response->assertStatus(200);
+ $response->assertHeader('Content-Type', 'application/json');
+ }
+
+}
\ No newline at end of file
diff --git a/tests/Feature/Console/Commands/Correction/CorrectOpeningBalanceCurrenciesTest.php b/tests/Feature/Console/Commands/Correction/CorrectOpeningBalanceCurrenciesTest.php
deleted file mode 100644
index 98dca2cb22..0000000000
--- a/tests/Feature/Console/Commands/Correction/CorrectOpeningBalanceCurrenciesTest.php
+++ /dev/null
@@ -1,110 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-/*
- * CorrectOpeningBalanceCurrenciesTest.php
- * Copyright (c) 2020 james@firefly-iii.org
- *
- * This file is part of Firefly III (https://github.com/firefly-iii).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\TransactionJournal;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class CorrectOpeningBalanceCurrenciesTest
- *
- * @package Tests\Feature\Console\Commands\Correction
- */
-class CorrectOpeningBalanceCurrenciesTest extends TestCase
-{
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\CorrectOpeningBalanceCurrencies
- */
- public function testBasic(): void
- {
- $this->assertTrue(true);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\CorrectOpeningBalanceCurrencies
- */
- public function testHandleOK(): void
- {
- // run command
- $this->artisan('firefly-iii:fix-ob-currencies')
- ->expectsOutput('There was nothing to fix in the opening balance transactions.')
- ->assertExitCode(0);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\CorrectOpeningBalanceCurrencies
- */
- public function testHandleBroken(): void
- {
- // create opening balance journal for test. Is enough to trigger this test.
- TransactionJournal::factory()->openingBalance()->create();
-
- // run command
- $this->artisan('firefly-iii:fix-ob-currencies')
- ->expectsOutput('Corrected 1 opening balance transaction(s).')
- ->assertExitCode(0);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\CorrectOpeningBalanceCurrencies
- */
- public function testHandleNoAccount(): void
- {
- Log::debug('Now in testHandleNoAccount');
- // create opening balance journal for test. Is enough to trigger this test.
- $journal = TransactionJournal::factory()->brokenOpeningBalance()->create();
-
- // run command
- $this->artisan('firefly-iii:fix-ob-currencies')
- ->expectsOutput(sprintf('Transaction journal #%d has no valid account. Cant fix this line.', $journal->id))
- //->expectsOutput('Cant fix this line.')
- ->assertExitCode(0);
-
- $journal->forceDelete();
- }
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/CreateAccessTokensTest.php b/tests/Feature/Console/Commands/Correction/CreateAccessTokensTest.php
deleted file mode 100644
index 63b336279b..0000000000
--- a/tests/Feature/Console/Commands/Correction/CreateAccessTokensTest.php
+++ /dev/null
@@ -1,64 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\Preference;
-use Tests\TestCase;
-
-/**
- * Class CreateAccessTokensTest
- */
-class CreateAccessTokensTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\CreateAccessTokens
- */
- public function testHandle(): void
- {
- // remove preferences so token will be generated
- Preference::where('name', 'access_token')->delete();
-
- $this->artisan('firefly-iii:create-access-tokens')
- ->expectsOutput(sprintf('Generated access token for user %s', $this->user()->email))
- ->assertExitCode(0);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\CreateAccessTokens
- */
- public function testHandlePrefExists(): void
- {
- $preference = new Preference;
- $preference->data = '123';
- $preference->name = 'access_token';
- $preference->user_id = $this->user()->id;
- $preference->save();
-
- $this->artisan('firefly-iii:create-access-tokens')
- ->expectsOutput('All access tokens OK!')
- ->assertExitCode(0);
- }
-}
diff --git a/tests/Feature/Console/Commands/Correction/CreateLinkTypesTest.php b/tests/Feature/Console/Commands/Correction/CreateLinkTypesTest.php
deleted file mode 100644
index 119b5dfa6b..0000000000
--- a/tests/Feature/Console/Commands/Correction/CreateLinkTypesTest.php
+++ /dev/null
@@ -1,72 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\LinkType;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class CreateLinkTypesTest
- */
-class CreateLinkTypesTest extends TestCase
-{
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\CreateLinkTypes
- */
- public function testHandle(): void
- {
- // delete all other link types:
- LinkType::whereNotIn('name', ['Related', 'Refund', 'Paid', 'Reimbursement'])->forceDelete();
-
- // delete link type:
- LinkType::where('name', 'Reimbursement')->forceDelete();
- $this->assertCount(3, LinkType::get());
-
- // run command, expect output:
- $this->artisan('firefly-iii:create-link-types')
- ->expectsOutput('Created missing link type "Reimbursement"')
- ->assertExitCode(0);
-
- $this->assertCount(4, LinkType::get());
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\CreateLinkTypes
- */
- public function testHandleNothing(): void
- {
- $this->assertCount(4, LinkType::get());
-
- // run command, expect output:
- $this->artisan('firefly-iii:create-link-types')
- ->expectsOutput('All link types OK!')
- ->assertExitCode(0);
-
- $this->assertCount(4, LinkType::get());
- }
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/DeleteEmptyGroupsTest.php b/tests/Feature/Console/Commands/Correction/DeleteEmptyGroupsTest.php
deleted file mode 100644
index c188ca47fb..0000000000
--- a/tests/Feature/Console/Commands/Correction/DeleteEmptyGroupsTest.php
+++ /dev/null
@@ -1,62 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\TransactionGroup;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class DeleteEmptyGroupsTest
- */
-class DeleteEmptyGroupsTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteEmptyGroups
- */
- public function testHandle(): void
- {
- // assume there are no empty groups..
- $this->artisan('firefly-iii:delete-empty-groups')
- ->assertExitCode(0);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteEmptyGroups
- */
- public function testHandleWithGroup(): void
- {
- // create new group:
- $group = TransactionGroup::create(['user_id' => 1]);
-
- // command should delete it.
- $this->artisan('firefly-iii:delete-empty-groups')
- ->expectsOutput('Deleted 1 empty transaction group(s).')
- ->assertExitCode(0);
-
- // should not be able to find it:
- $this->assertCount(0, TransactionGroup::where('id', $group->id)->whereNull('deleted_at')->get());
- }
-}
diff --git a/tests/Feature/Console/Commands/Correction/DeleteEmptyJournalsTest.php b/tests/Feature/Console/Commands/Correction/DeleteEmptyJournalsTest.php
deleted file mode 100644
index 3c99313209..0000000000
--- a/tests/Feature/Console/Commands/Correction/DeleteEmptyJournalsTest.php
+++ /dev/null
@@ -1,112 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\Transaction;
-use FireflyIII\Models\TransactionJournal;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class DeleteEmptyJournalsTest
- */
-class DeleteEmptyJournalsTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteEmptyJournals
- */
- public function testHandle(): void
- {
- // assume there are no empty journals or uneven journals
- $this->artisan('firefly-iii:delete-empty-journals')
- ->expectsOutput('No uneven transaction journals.')
- ->expectsOutput('No empty transaction journals.')
- ->assertExitCode(0);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteEmptyJournals
- */
- public function testHandleEmptyJournals(): void
- {
- // create empty journal:
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => 1,
- 'description' => 'Hello',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $this->artisan('firefly-iii:delete-empty-journals')
- ->expectsOutput('No uneven transaction journals.')
- ->expectsOutput(sprintf('Deleted empty transaction journal #%d', $journal->id))
- ->assertExitCode(0);
-
- // verify its indeed gone
- $this->assertCount(0, TransactionJournal::where('id', $journal->id)->whereNull('deleted_at')->get());
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteEmptyJournals
- */
- public function testHandleUnevenJournals(): void
- {
- // create empty journal:
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => 1,
- 'description' => 'Hello',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
-
- // link empty transaction
- $transaction = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => 1,
- 'amount' => '5',
- ]
- );
-
-
- $this->artisan('firefly-iii:delete-empty-journals')
- ->expectsOutput(sprintf('Deleted transaction journal #%d because it had an uneven number of transactions.', $journal->id))
- ->expectsOutput('No empty transaction journals.')
- ->assertExitCode(0);
-
- // verify both are gone
- $this->assertCount(0, TransactionJournal::where('id', $journal->id)->whereNull('deleted_at')->get());
- $this->assertCount(0, Transaction::where('id', $transaction->id)->whereNull('deleted_at')->get());
- }
-
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/DeleteOrphanedTransactionsTest.php b/tests/Feature/Console/Commands/Correction/DeleteOrphanedTransactionsTest.php
deleted file mode 100644
index a837a2e93e..0000000000
--- a/tests/Feature/Console/Commands/Correction/DeleteOrphanedTransactionsTest.php
+++ /dev/null
@@ -1,137 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\Account;
-use FireflyIII\Models\Transaction;
-use FireflyIII\Models\TransactionJournal;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class DeleteOrphanedTransactionsTest
- */
-class DeleteOrphanedTransactionsTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteOrphanedTransactions
- */
- public function testHandle(): void
- {
- // assume there are no orphaned transactions.
- $this->artisan('firefly-iii:delete-orphaned-transactions')
- ->expectsOutput('No orphaned transactions.')
- ->expectsOutput('No orphaned accounts.')
- ->assertExitCode(0);
- }
-
- /**
- *
- */
- public function testHandleOrphanedAccounts(): void
- {
-
- // create deleted account:
- $account = Account::create(
- [
- 'user_id' => 1,
- 'name' => 'Some account',
- 'account_type_id' => 1,
-
- ]
- );
- $account->delete();
-
- // create NOT deleted journal + transaction.
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => 1,
- 'description' => 'Hello',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
-
- $transaction = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $account->id,
- 'amount' => '5',
- ]
- );
-
- $this->artisan('firefly-iii:delete-orphaned-transactions')
- ->expectsOutput('No orphaned transactions.')
- ->expectsOutput(sprintf('Deleted transaction journal #%d because account #%d was already deleted.',
- $journal->id, $account->id))
- ->assertExitCode(0);
-
- // verify bad objects are gone.
- $this->assertCount(0, Transaction::where('id', $transaction->id)->whereNull('deleted_at')->get());
- $this->assertCount(0, TransactionJournal::where('id', $journal->id)->whereNull('deleted_at')->get());
- $this->assertCount(0, Account::where('id', $account->id)->whereNull('deleted_at')->get());
-
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteOrphanedTransactions
- */
- public function testHandleOrphanedTransactions(): void
- {
- // create deleted journal:
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => 1,
- 'description' => 'Hello',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $journal->delete();
-
- // create NOT deleted transaction.
- $transaction = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => 1,
- 'amount' => '5',
- ]
- );
-
- $this->artisan('firefly-iii:delete-orphaned-transactions')
- ->expectsOutput(sprintf('Transaction #%d (part of deleted transaction journal #%d) has been deleted as well.',
- $transaction->id, $journal->id))
- ->expectsOutput('No orphaned accounts.')
- ->assertExitCode(0);
-
- // verify objects are gone.
- $this->assertCount(0, TransactionJournal::where('id', $journal->id)->whereNull('deleted_at')->get());
- $this->assertCount(0, Transaction::where('id', $transaction->id)->whereNull('deleted_at')->get());
- }
-}
diff --git a/tests/Feature/Console/Commands/Correction/DeleteZeroAmountTest.php b/tests/Feature/Console/Commands/Correction/DeleteZeroAmountTest.php
deleted file mode 100644
index 0642eca92b..0000000000
--- a/tests/Feature/Console/Commands/Correction/DeleteZeroAmountTest.php
+++ /dev/null
@@ -1,84 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\Transaction;
-use FireflyIII\Models\TransactionJournal;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class DeleteZeroAmountTest
- */
-class DeleteZeroAmountTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteZeroAmount
- */
- public function testHandle(): void
- {
- // assume there are no transactions with a zero amount.
- $this->artisan('firefly-iii:delete-zero-amount')
- ->expectsOutput('No zero-amount transaction journals.')
- ->assertExitCode(0);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\DeleteZeroAmount
- */
- public function testHandleTransactions(): void
- {
- $account = $this->getRandomAsset();
- // create NOT deleted journal + transaction.
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => 1,
- 'description' => 'Hello',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
-
- $transaction = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $account->id,
- 'amount' => '0',
- ]
- );
-
-
- // assume there are no transactions with a zero amount.
- $this->artisan('firefly-iii:delete-zero-amount')
- ->expectsOutput(sprintf('Deleted transaction journal #%d because the amount is zero (0.00).', $journal->id))
- ->assertExitCode(0);
-
- // verify objects are gone.
- $this->assertCount(0, Transaction::where('id', $transaction->id)->whereNull('deleted_at')->get());
- $this->assertCount(0, TransactionJournal::where('id', $journal->id)->whereNull('deleted_at')->get());
- }
-}
diff --git a/tests/Feature/Console/Commands/Correction/EnableCurrenciesTest.php b/tests/Feature/Console/Commands/Correction/EnableCurrenciesTest.php
deleted file mode 100644
index 4ecbaca911..0000000000
--- a/tests/Feature/Console/Commands/Correction/EnableCurrenciesTest.php
+++ /dev/null
@@ -1,78 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\BudgetLimit;
-use FireflyIII\Models\TransactionCurrency;
-use Tests\TestCase;
-
-/**
- * Class EnableCurrenciesTest
- */
-class EnableCurrenciesTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\EnableCurrencies
- */
- public function testHandleEnabled(): void
- {
- $count = TransactionCurrency::where('enabled', 1)->count();
-
- $this->artisan('firefly-iii:enable-currencies')
- ->expectsOutput('All currencies are correctly enabled or disabled.')
- ->assertExitCode(0);
-
-
- $this->assertCount($count, TransactionCurrency::where('enabled', 1)->get());
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\EnableCurrencies
- */
- public function testHandleDisabled(): void
- {
- // find a disabled currency, update a budget limit with it.
- $currency = TransactionCurrency::where('enabled', 0)->first();
- $budget = $this->getRandomBudget();
- $budgetLimit = new BudgetLimit;
- $budgetLimit->transaction_currency_id = $currency->id;
- $budgetLimit->budget_id = $budget->id;
- $budgetLimit->start_date = '2020-01-01';
- $budgetLimit->end_date = '2020-01-02';
- $budgetLimit->amount = '4';
- $budgetLimit->save();
-
- // assume the current database is intact.
- $count = TransactionCurrency::where('enabled', 1)->count();
- $this->artisan('firefly-iii:enable-currencies')
- ->expectsOutput(sprintf('%d were (was) still disabled. This has been corrected.', 1))
- ->assertExitCode(0);
-
- // assume its been enabled.
- $this->assertCount($count + 1, TransactionCurrency::where('enabled', 1)->get());
- $budgetLimit->forceDelete();
- }
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/FixAccountOrderTest.php b/tests/Feature/Console/Commands/Correction/FixAccountOrderTest.php
deleted file mode 100644
index caa9519afb..0000000000
--- a/tests/Feature/Console/Commands/Correction/FixAccountOrderTest.php
+++ /dev/null
@@ -1,69 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-/*
- * FixAccountOrderTest.php
- * Copyright (c) 2020 james@firefly-iii.org
- *
- * This file is part of Firefly III (https://github.com/firefly-iii).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use DB;
-use FireflyIII\Models\Account;
-use Tests\TestCase;
-
-class FixAccountOrderTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixAccountOrder
- */
- public function testHandle(): void
- {
-
- // reset all asset accounts accounts:
- Account::select()->update(['order' => 0]);
-
- $this->artisan('firefly-iii:fix-account-order')
- ->assertExitCode(0);
-
- $this->assertCount(0, Account::where('order', '=',0)->get());
-
- }
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/FixAccountTypesTest.php b/tests/Feature/Console/Commands/Correction/FixAccountTypesTest.php
deleted file mode 100644
index d825bddb49..0000000000
--- a/tests/Feature/Console/Commands/Correction/FixAccountTypesTest.php
+++ /dev/null
@@ -1,364 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\Account;
-use FireflyIII\Models\AccountType;
-use FireflyIII\Models\Transaction;
-use FireflyIII\Models\TransactionJournal;
-use FireflyIII\Models\TransactionType;
-use Tests\TestCase;
-
-/**
- * Class FixAccountTypesTest
- */
-class FixAccountTypesTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixAccountTypes
- */
- public function testHandleUneven(): void
- {
- $source = $this->getRandomDebt();
- $type = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => $type->id,
- 'description' => 'Test',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $one = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $source->id,
- 'amount' => '-10',
- ]
- );
-
- // assume there's nothing to fix.
- $this->artisan('firefly-iii:fix-account-types')
- ->expectsOutput(sprintf('Cannot inspect transaction journal #%d because it has 1 transaction(s) instead of 2.', $journal->id))
- ->assertExitCode(0);
- $one->forceDelete();
- $journal->forceDelete();
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixAccountTypes
- */
- public function testHandle(): void
- {
- // assume there's nothing to fix.
- $this->artisan('firefly-iii:fix-account-types')
- ->expectsOutput('All account types are OK!')
- ->assertExitCode(0);
- }
-
- /**
- * Try to fix a withdrawal that goes from a loan to another loan.
- *
- * @covers \FireflyIII\Console\Commands\Correction\FixAccountTypes
- */
- public function testHandleWithdrawalLoanLoan(): void
- {
- $source = $this->getRandomLoan();
- $destination = $this->getRandomLoan($source->id);
- $type = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => $type->id,
- 'description' => 'Test',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $one = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $source->id,
- 'amount' => '-10',
- ]
- );
- $two = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $destination->id,
- 'amount' => '10',
- ]
- );
-
-
- $this->artisan('firefly-iii:fix-account-types')
- ->expectsOutput(sprintf('The source account of %s #%d cannot be of type "%s".', $type->type, $journal->id, 'Loan'))
- ->expectsOutput(sprintf('The destination account of %s #%d cannot be of type "%s".', $type->type, $journal->id, 'Loan'))
- ->expectsOutput('Acted on 1 transaction(s)!')
- ->assertExitCode(0);
-
- // since system cant handle this problem, dont look for changed transactions.
- $one->forceDelete();
- $two->forceDelete();
- $journal->forceDelete();
- }
-
- /**
- * Transferring from an asset to a loan should be a withdrawal, not a transfer
- */
- public function testHandleTransferAssetLoan(): void
- {
- $source = $this->getRandomAsset();
- $destination = $this->getRandomLoan();
- $type = TransactionType::where('type', TransactionType::TRANSFER)->first();
- $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => $type->id,
- 'description' => 'Test',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $one = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $source->id,
- 'amount' => '-10',
- ]
- );
- $two = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $destination->id,
- 'amount' => '10',
- ]
- );
-
- $this->artisan('firefly-iii:fix-account-types')
- ->expectsOutput(sprintf('Converted transaction #%d from a transfer to a withdrawal.', $journal->id))
- ->expectsOutput('Acted on 1 transaction(s)!')
- ->assertExitCode(0);
-
- // verify the change has been made.
- $this->assertCount(1, TransactionJournal::where('id', $journal->id)->where('transaction_type_id', $withdrawal->id)->get());
- $this->assertCount(0, TransactionJournal::where('id', $journal->id)->where('transaction_type_id', $type->id)->get());
-
- $one->forceDelete();
- $two->forceDelete();
- $journal->forceDelete();
- }
-
- /**
- * Transferring from a loan to an asset should be a deposit, not a transfer
- */
- public function testHandleTransferLoanAsset(): void
- {
- $source = $this->getRandomLoan();
- $destination = $this->getRandomAsset();
- $type = TransactionType::where('type', TransactionType::TRANSFER)->first();
- $deposit = TransactionType::where('type', TransactionType::DEPOSIT)->first();
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => $type->id,
- 'description' => 'Test',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $one = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $source->id,
- 'amount' => '-10',
- ]
- );
- $two = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $destination->id,
- 'amount' => '10',
- ]
- );
-
- $this->artisan('firefly-iii:fix-account-types')
- ->expectsOutput(sprintf('Converted transaction #%d from a transfer to a deposit.', $journal->id))
- ->expectsOutput('Acted on 1 transaction(s)!')
- ->assertExitCode(0);
-
- // verify the change has been made.
- $this->assertCount(1, TransactionJournal::where('id', $journal->id)->where('transaction_type_id', $deposit->id)->get());
- $this->assertCount(0, TransactionJournal::where('id', $journal->id)->where('transaction_type_id', $type->id)->get());
-
- $one->forceDelete();
- $two->forceDelete();
- $journal->forceDelete();
- }
-
- /**
- * Withdrawal with a revenue account as a destination must be converted.
- */
- public function testHandleWithdrawalAssetRevenue(): void
- {
- $source = $this->getRandomAsset();
- $destination = $this->getRandomRevenue(); // is revenue account.
- $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => $withdrawal->id,
- 'description' => 'Test',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $one = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $source->id,
- 'amount' => '-10',
- ]
- );
- $two = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $destination->id, // revenue cannot be destination.
- 'amount' => '10',
- ]
- );
-
- // create expense account with the same name:
- $expense = AccountType::where('type', AccountType::EXPENSE)->first();
- $newDestination = Account::create(
- [
- 'name' => $destination->name,
- 'account_type_id' => $expense->id,
- 'user_id' => 1,
- ]
- );
-
- // asset we find bad destination.
- $this->assertCount(0, Transaction::where('id', $two->id)->where('account_id', $newDestination->id)->get());
- $this->assertCount(1, Transaction::where('id', $two->id)->where('account_id', $destination->id)->get());
-
- // Transaction journal #137, destination account changed from #1 ("Checking Account") to #29 ("Land lord").
- $this->artisan('firefly-iii:fix-account-types')
- ->expectsOutput(
- sprintf(
- 'Transaction journal #%d, destination account changed from #%d ("%s") to #%d ("%s").',
- $journal->id,
- $destination->id, $destination->name,
- $newDestination->id, $newDestination->name
- )
- )
- ->expectsOutput('Acted on 1 transaction(s)!')
- ->assertExitCode(0);
-
- // verify the change has been made
- $this->assertCount(1, Transaction::where('id', $two->id)->where('account_id', $newDestination->id)->get());
- $this->assertCount(0, Transaction::where('id', $two->id)->where('account_id', $destination->id)->get());
-
- $one->forceDelete();
- $two->forceDelete();
- $journal->forceDelete();
- }
-
- /**
- * Deposit with an expense account as a source instead of a revenue account must be converted.
- */
- public function testHandleDepositAssetExpense(): void
- {
- $source = $this->getRandomExpense(); // expense account
- //$newSource = $this->getRandomRevenue();
- $destination = $this->getRandomAsset();
-
- $deposit = TransactionType::where('type', TransactionType::DEPOSIT)->first();
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => $deposit->id,
- 'description' => 'Test',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $one = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $source->id, // expense account cannot be source.
- 'amount' => '-10',
- ]
- );
- $two = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $destination->id,
- 'amount' => '10',
- ]
- );
- // create revenue account with the same name:
- $revenue = AccountType::where('type', AccountType::REVENUE)->first();
- $newSource = Account::create(
- [
- 'name' => $source->name,
- 'account_type_id' => $revenue->id,
- 'user_id' => 1,
- ]
- );
-
- $this->assertCount(0, Transaction::where('id', $one->id)->where('account_id', $newSource->id)->get());
- $this->assertCount(1, Transaction::where('id', $one->id)->where('account_id', $source->id)->get());
-
-
- // Transaction journal #137, destination account changed from #1 ("Checking Account") to #29 ("Land lord").
- $this->artisan('firefly-iii:fix-account-types')
- ->expectsOutput(
- sprintf(
- 'Transaction journal #%d, source account changed from #%d ("%s") to #%d ("%s").',
- $journal->id,
- $destination->id, $destination->name,
- $newSource->id, $newSource->name
- )
- )
- ->expectsOutput('Acted on 1 transaction(s)!')
- ->assertExitCode(0);
-
- $this->assertCount(1, Transaction::where('id', $one->id)->where('account_id', $newSource->id)->get());
- $this->assertCount(0, Transaction::where('id', $one->id)->where('account_id', $source->id)->get());
-
- $one->forceDelete();
- $two->forceDelete();
- $journal->forceDelete();
- }
-}
diff --git a/tests/Feature/Console/Commands/Correction/FixGroupAccountsTest.php b/tests/Feature/Console/Commands/Correction/FixGroupAccountsTest.php
deleted file mode 100644
index 08c670bd96..0000000000
--- a/tests/Feature/Console/Commands/Correction/FixGroupAccountsTest.php
+++ /dev/null
@@ -1,69 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-/*
- * FixGroupAccountsTest.php
- * Copyright (c) 2020 james@firefly-iii.org
- *
- * This file is part of Firefly III (https://github.com/firefly-iii).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use Tests\TestCase;
-
-/**
- * Class FixGroupAccountsTest
- */
-class FixGroupAccountsTest extends TestCase
-{
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixGroupAccounts
- */
- public function testHandle(): void
- {
- // basic group with multiple journals, should trigger event.
- $this->artisan('firefly-iii:unify-group-accounts')
- ->expectsOutput('Updated inconsistent transaction groups.')
- ->assertExitCode(0);
-
- // This just triggers the events. No real test.
- }
-
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/FixLongDescriptionsTest.php b/tests/Feature/Console/Commands/Correction/FixLongDescriptionsTest.php
deleted file mode 100644
index 3263ed8ad5..0000000000
--- a/tests/Feature/Console/Commands/Correction/FixLongDescriptionsTest.php
+++ /dev/null
@@ -1,95 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-/*
- * FixLongDescriptionsTest.php
- * Copyright (c) 2020 james@firefly-iii.org
- *
- * This file is part of Firefly III (https://github.com/firefly-iii).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use Tests\TestCase;
-
-/**
- * Class FixLongDescriptionsTest
- */
-class FixLongDescriptionsTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixLongDescriptions
- */
- public function testHandle(): void
- {
- $journal = $this->getRandomWithdrawal();
- $original = $journal->description;
- $journal->description = str_repeat('ABCDEF123456x', 200);
- $journal->save();
-
-
- $this->artisan('firefly-iii:fix-long-descriptions')
- ->expectsOutput(sprintf('Truncated description of transaction journal #%d', $journal->id))
- ->expectsOutput('Verified all transaction group and journal title lengths.')
- ->assertExitCode(0);
-
- $journal->description = $original;
- $journal->save();
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixLongDescriptions
- */
- public function testHandleGroup(): void
- {
- $journal = $this->getRandomWithdrawal();
- $group = $journal->transactionGroup;
- $original = $group->title;
- $group->title = str_repeat('ABCDEF123456x', 200);
- $group->save();
-
-
- $this->artisan('firefly-iii:fix-long-descriptions')
- ->expectsOutput(sprintf('Truncated description of transaction group #%d', $group->id))
- ->expectsOutput('Verified all transaction group and journal title lengths.')
- ->assertExitCode(0);
-
- $group->title = $original;
- $group->save();
- }
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/FixPiggiesTest.php b/tests/Feature/Console/Commands/Correction/FixPiggiesTest.php
deleted file mode 100644
index 7b59548792..0000000000
--- a/tests/Feature/Console/Commands/Correction/FixPiggiesTest.php
+++ /dev/null
@@ -1,123 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\PiggyBank;
-use FireflyIII\Models\PiggyBankEvent;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class FixPiggiesTest
- */
-class FixPiggiesTest extends TestCase
-{
- /**
- * Null event.
- *
- * @covers \FireflyIII\Console\Commands\Correction\FixPiggies
- */
- public function testHandleNull(): void
- {
- /** @var PiggyBank $piggy */
- $piggy = $this->user()->piggyBanks()->inRandomOrder()->first();
-
- // create event to trigger console commands.
- $event = PiggyBankEvent::create(
- [
- 'piggy_bank_id' => $piggy->id,
- 'date' => '2019-01-01',
- 'amount' => 5,
- ]
- );
-
- // assume there's nothing to fix.
- $this->artisan('firefly-iii:fix-piggies')
- ->expectsOutput('All piggy bank events are correct.')
- ->assertExitCode(0);
- $event->forceDelete();
- }
-
- /**
- * Withdrawal instead of transfer
- *
- * @covers \FireflyIII\Console\Commands\Correction\FixPiggies
- */
- public function testHandleBadJournal(): void
- {
- /** @var PiggyBank $piggy */
- $piggy = $this->user()->piggyBanks()->inRandomOrder()->first();
- $withdrawal = $this->getRandomWithdrawal();
- // create event to trigger console commands.
- $event = PiggyBankEvent::create(
- [
- 'piggy_bank_id' => $piggy->id,
- 'date' => '2019-01-01',
- 'amount' => 5,
- 'transaction_journal_id' => $withdrawal->id,
- ]
- );
-
- // assume there's nothing to fix.
- $this->artisan('firefly-iii:fix-piggies')
- ->expectsOutput(sprintf('Piggy bank #%d was referenced by an invalid event. This has been fixed.', $piggy->id))
- ->expectsOutput('Fixed 1 piggy bank event(s).')
- ->assertExitCode(0);
-
- // verify update
- $this->assertCount(0, PiggyBankEvent::where('id', $event->id)->where('transaction_journal_id', $withdrawal->id)->get());
- }
-
- /**
- * Withdrawal instead of transfer
- *
- * @covers \FireflyIII\Console\Commands\Correction\FixPiggies
- */
- public function testHandleDeletedJournal(): void
- {
- /** @var PiggyBank $piggy */
- $piggy = $this->user()->piggyBanks()->inRandomOrder()->first();
- $transfer = $this->getRandomTransfer();
- $event = PiggyBankEvent::create(
- [
- 'piggy_bank_id' => $piggy->id,
- 'date' => '2019-01-01',
- 'amount' => 5,
- 'transaction_journal_id' => $transfer->id,
- ]
- );
- $transfer->deleted_at = '2019-01-01 12:00:00';
- $transfer->save();
- $transfer->refresh();
-
- $this->artisan('firefly-iii:fix-piggies')
- ->expectsOutput('Fixed 1 piggy bank event(s).')
- ->assertExitCode(0);
-
- // verify update
- $this->assertCount(0, PiggyBankEvent::where('id', $event->id)->where('transaction_journal_id', $transfer->id)->get());
- $event->forceDelete();
- }
-}
diff --git a/tests/Feature/Console/Commands/Correction/FixRecurringTransactionsTest.php b/tests/Feature/Console/Commands/Correction/FixRecurringTransactionsTest.php
deleted file mode 100644
index a84b8791e0..0000000000
--- a/tests/Feature/Console/Commands/Correction/FixRecurringTransactionsTest.php
+++ /dev/null
@@ -1,70 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-/*
- * FixRecurringTransactionsTest.php
- * Copyright (c) 2020 james@firefly-iii.org
- *
- * This file is part of Firefly III (https://github.com/firefly-iii).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\Recurrence;
-use Tests\TestCase;
-
-/**
- * Class FixRecurringTransactionsTest
- */
-class FixRecurringTransactionsTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixRecurringTransactions
- */
- public function testHandle(): void
- {
- // test DB contains a broken recurring transaction.
- $recurring = Recurrence::whereTitle('broken_recurrence')->first();
-
-
- $this->artisan('firefly-iii:fix-recurring-transactions')
- ->expectsOutput(sprintf('Recurring transaction #%d should be a "%s" but is a "%s" and will be corrected.',
- $recurring->id, 'Withdrawal','Transfer',
- ))
- ->assertExitCode(0);
- }
-}
diff --git a/tests/Feature/Console/Commands/Correction/FixTransactionTypesTest.php b/tests/Feature/Console/Commands/Correction/FixTransactionTypesTest.php
deleted file mode 100644
index 24d02606cf..0000000000
--- a/tests/Feature/Console/Commands/Correction/FixTransactionTypesTest.php
+++ /dev/null
@@ -1,65 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-/*
- * FixTransactionTypesTest.php
- * Copyright (c) 2020 james@firefly-iii.org
- *
- * This file is part of Firefly III (https://github.com/firefly-iii).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use Tests\TestCase;
-
-/**
- * Class FixTransactionTypesTest
- */
-class FixTransactionTypesTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixTransactionTypes
- */
- public function testHandle(): void
- {
- $this->artisan('firefly-iii:fix-transaction-types')
- //->expectsOutput()
- ->assertExitCode(0);
- }
-
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/FixUnevenAmountTest.php b/tests/Feature/Console/Commands/Correction/FixUnevenAmountTest.php
deleted file mode 100644
index cab85a0cb2..0000000000
--- a/tests/Feature/Console/Commands/Correction/FixUnevenAmountTest.php
+++ /dev/null
@@ -1,95 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\Transaction;
-use FireflyIII\Models\TransactionJournal;
-use FireflyIII\Models\TransactionType;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class FixUnevenAmountTest
- */
-class FixUnevenAmountTest extends TestCase
-{
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\FixUnevenAmount
- */
- public function testHandle(): void
- {
- // assume there's nothing to fix.
- $this->artisan('firefly-iii:fix-uneven-amount')
- ->expectsOutput('Amount integrity OK!')
- ->assertExitCode(0);
-
- // dont verify anything
- }
-
- /**
- * Create uneven journal
- * @covers \FireflyIII\Console\Commands\Correction\FixUnevenAmount
- */
- public function testHandleUneven(): void
- {
- $asset = $this->getRandomAsset();
- $expense = $this->getRandomExpense();
- $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
- $journal = TransactionJournal::create(
- [
- 'user_id' => 1,
- 'transaction_currency_id' => 1,
- 'transaction_type_id' => $withdrawal->id,
- 'description' => 'Test',
- 'tag_count' => 0,
- 'date' => '2019-01-01',
- ]
- );
- $one = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $asset->id,
- 'amount' => '-10',
- ]
- );
- $two = Transaction::create(
- [
- 'transaction_journal_id' => $journal->id,
- 'account_id' => $expense->id,
- 'amount' => '12',
- ]
- );
-
- $this->artisan('firefly-iii:fix-uneven-amount')
- ->expectsOutput(sprintf('Corrected amount in transaction journal #%d', $journal->id))
- ->assertExitCode(0);
-
- // verify change.
- $this->assertCount(1, Transaction::where('id', $one->id)->where('amount', '-10')->get());
- $this->assertCount(1, Transaction::where('id', $two->id)->where('amount', '10')->get());
- }
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/RemoveBillsTest.php b/tests/Feature/Console/Commands/Correction/RemoveBillsTest.php
deleted file mode 100644
index 510bda424d..0000000000
--- a/tests/Feature/Console/Commands/Correction/RemoveBillsTest.php
+++ /dev/null
@@ -1,69 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\TransactionJournal;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class RemoveBillsTest
- */
-class RemoveBillsTest extends TestCase
-{
-
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\RemoveBills
- */
- public function testHandle(): void
- {
- // assume there's nothing to fix.
- $this->artisan('firefly-iii:remove-bills')
- ->expectsOutput('All transaction journals have correct bill information.')
- ->assertExitCode(0);
-
- // dont verify anything
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\RemoveBills
- */
- public function testHandleWithdrawal(): void
- {
- $bill = $this->getRandomBill();
- $journal = $this->getRandomDeposit();
-
- $journal->bill_id = $bill->id;
- $journal->save();
-
- $this->artisan('firefly-iii:remove-bills')
- ->expectsOutput(sprintf('Transaction journal #%d should not be linked to bill #%d.', $journal->id, $bill->id))
- ->assertExitCode(0);
-
- // verify change
- $this->assertCount(0, TransactionJournal::where('id', $journal->id)->whereNotNull('bill_id')->get());
- }
-}
diff --git a/tests/Feature/Console/Commands/Correction/RenameMetaFieldsTest.php b/tests/Feature/Console/Commands/Correction/RenameMetaFieldsTest.php
deleted file mode 100644
index 444dd506a6..0000000000
--- a/tests/Feature/Console/Commands/Correction/RenameMetaFieldsTest.php
+++ /dev/null
@@ -1,70 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use FireflyIII\Models\TransactionJournalMeta;
-use Log;
-use Tests\TestCase;
-
-/**
- * Class RenameMetaFieldsTest
- */
-class RenameMetaFieldsTest extends TestCase
-{
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\RenameMetaFields
- */
- public function testHandle(): void
- {
- $this->artisan('firefly-iii:rename-meta-fields')
- ->expectsOutput('All meta fields are correct.')
- ->assertExitCode(0);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\RenameMetaFields
- */
- public function testHandleFixed(): void
- {
- $withdrawal = $this->getRandomWithdrawal();
- $entry = TransactionJournalMeta::create(
- [
- 'transaction_journal_id' => $withdrawal->id,
- 'name' => 'importHashV2',
- 'data' => 'Fake data',
-
- ]
- );
-
- $this->artisan('firefly-iii:rename-meta-fields')
- ->expectsOutput('Renamed 1 meta field(s).')
- ->assertExitCode(0);
-
- // verify update
- $this->assertCount(1, TransactionJournalMeta::where('id', $entry->id)->where('name', 'import_hash_v2')->get());
- }
-
-}
diff --git a/tests/Feature/Console/Commands/Correction/TransferBudgetsTest.php b/tests/Feature/Console/Commands/Correction/TransferBudgetsTest.php
deleted file mode 100644
index e3621b8620..0000000000
--- a/tests/Feature/Console/Commands/Correction/TransferBudgetsTest.php
+++ /dev/null
@@ -1,64 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace Tests\Feature\Console\Commands\Correction;
-
-
-use Log;
-use Tests\TestCase;
-
-/**
- * Class TransferBudgetsTest
- */
-class TransferBudgetsTest extends TestCase
-{
- /**
- * @covers \FireflyIII\Console\Commands\Correction\TransferBudgets
- */
- public function testHandle(): void
- {
- $this->artisan('firefly-iii:fix-transfer-budgets')
- ->expectsOutput('No invalid budget/journal entries.')
- ->assertExitCode(0);
- }
-
- /**
- * @covers \FireflyIII\Console\Commands\Correction\TransferBudgets
- */
- public function testHandleBudget(): void
- {
- $deposit = $this->getRandomDeposit();
- $budget = $this->getRandomBudget();
-
- $deposit->budgets()->save($budget);
-
- $this->artisan('firefly-iii:fix-transfer-budgets')
- ->expectsOutput(sprintf('Transaction journal #%d is a %s, so has no longer a budget.', $deposit->id, $deposit->transactionType->type))
- ->expectsOutput('Corrected 1 invalid budget/journal entries (entry).')
- ->assertExitCode(0);
-
- // verify change
- $this->assertCount(0, $deposit->budgets()->get());
- }
-
-}