mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Expand test coverage and improve transaction management code.
This commit is contained in:
parent
94acb50a6f
commit
5bbe1eab7c
@ -153,7 +153,7 @@ class BudgetReportController extends Controller
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
if ($cache->has()) {
|
||||
//return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||
}
|
||||
$format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
|
||||
$function = app('navigation')->preferredEndOfPeriod($start, $end);
|
||||
|
@ -30,8 +30,10 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Repositories\TransactionType\TransactionTypeRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
@ -54,7 +56,7 @@ class AutoCompleteController extends Controller
|
||||
public function accounts(Request $request): JsonResponse
|
||||
{
|
||||
$accountTypes = explode(',', $request->get('types') ?? '');
|
||||
$search = $request->get('query');
|
||||
$search = $request->get('search');
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
|
||||
@ -92,15 +94,45 @@ class AutoCompleteController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches in the titles of all transaction journals.
|
||||
* The result is limited to the top 15 unique results.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function budgets(): JsonResponse
|
||||
public function allJournals(Request $request): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
/** @var JournalRepositoryInterface $repository */
|
||||
$repository = app(JournalRepositoryInterface::class);
|
||||
$result = $repository->searchJournalDescriptions($search);
|
||||
|
||||
// limit and unique
|
||||
$filtered = $result->unique('description');
|
||||
$limited = $filtered->slice(0, 15);
|
||||
$array = $limited->toArray();
|
||||
foreach ($array as $index => $item) {
|
||||
// give another key for consistency
|
||||
$array[$index]['name'] = $item['description'];
|
||||
}
|
||||
|
||||
|
||||
return response()->json($array);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function budgets(Request $request): JsonResponse
|
||||
{
|
||||
$search = (string)$request->get('search');
|
||||
/** @var BudgetRepositoryInterface $repository */
|
||||
$repository = app(BudgetRepositoryInterface::class);
|
||||
$result = $repository->searchBudget($search);
|
||||
|
||||
return response()->json($repository->getActiveBudgets()->toArray());
|
||||
return response()->json($result->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +143,7 @@ class AutoCompleteController extends Controller
|
||||
*/
|
||||
public function categories(Request $request): JsonResponse
|
||||
{
|
||||
$query = (string)$request->get('query');
|
||||
$query = (string)$request->get('search');
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$result = $repository->searchCategory($query);
|
||||
@ -119,6 +151,44 @@ class AutoCompleteController extends Controller
|
||||
return response()->json($result->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function currencyNames(Request $request): JsonResponse
|
||||
{
|
||||
$query = (string)$request->get('search');
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$result = $repository->searchCurrency($query)->toArray();
|
||||
foreach ($result as $index => $item) {
|
||||
$result[$index]['name'] = sprintf('%s (%s)', $item['name'], $item['code']);
|
||||
}
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function transactionTypes(Request $request): JsonResponse
|
||||
{
|
||||
$query = (string)$request->get('search');
|
||||
/** @var TransactionTypeRepositoryInterface $repository */
|
||||
$repository = app(TransactionTypeRepositoryInterface::class);
|
||||
$array = $repository->searchTypes($query)->toArray();
|
||||
|
||||
foreach ($array as $index => $item) {
|
||||
// different key for consistency.
|
||||
$array[$index]['name'] = $item['type'];
|
||||
}
|
||||
|
||||
return response()->json($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsonResponse
|
||||
* @codeCoverageIgnore
|
||||
@ -164,13 +234,18 @@ class AutoCompleteController extends Controller
|
||||
*/
|
||||
public function tags(Request $request): JsonResponse
|
||||
{
|
||||
$query = (string)$request->get('query');
|
||||
$search = (string)$request->get('search');
|
||||
/** @var TagRepositoryInterface $repository */
|
||||
$repository = app(TagRepositoryInterface::class);
|
||||
$result = $repository->searchTags($query);
|
||||
$result = $repository->searchTags($search);
|
||||
$array = $result->toArray();
|
||||
foreach ($array as $index => $item) {
|
||||
// rename field for consistency.
|
||||
$array[$index]['name'] = $item['tag'];
|
||||
}
|
||||
|
||||
|
||||
return response()->json($result->toArray());
|
||||
return response()->json($array);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ class CreateController extends Controller
|
||||
|
||||
/**
|
||||
* CreateController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -39,6 +39,7 @@ class DeleteController extends Controller
|
||||
|
||||
/**
|
||||
* DeleteController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -79,8 +80,8 @@ class DeleteController extends Controller
|
||||
* Destroy the recurring transaction.
|
||||
*
|
||||
* @param RecurringRepositoryInterface $repository
|
||||
* @param Request $request
|
||||
* @param Recurrence $recurrence
|
||||
* @param Request $request
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
|
@ -47,6 +47,7 @@ class EditController extends Controller
|
||||
|
||||
/**
|
||||
* EditController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -70,7 +71,7 @@ class EditController extends Controller
|
||||
/**
|
||||
* Edit a recurring transaction.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Request $request
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
@ -92,7 +93,7 @@ class EditController extends Controller
|
||||
$repetition = $recurrence->recurrenceRepetitions()->first();
|
||||
$currentRepType = $repetition->repetition_type;
|
||||
if ('' !== $repetition->repetition_moment) {
|
||||
$currentRepType .= ',' . $repetition->repetition_moment;
|
||||
$currentRepType .= ',' . $repetition->repetition_moment; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
@ -123,9 +124,12 @@ class EditController extends Controller
|
||||
|
||||
$hasOldInput = null !== $request->old('_token');
|
||||
$preFilled = [
|
||||
'transaction_type' => strtolower($recurrence->transactionType->type),
|
||||
'active' => $hasOldInput ? (bool)$request->old('active') : $recurrence->active,
|
||||
'apply_rules' => $hasOldInput ? (bool)$request->old('apply_rules') : $recurrence->apply_rules,
|
||||
'transaction_type' => strtolower($recurrence->transactionType->type),
|
||||
'active' => $hasOldInput ? (bool)$request->old('active') : $recurrence->active,
|
||||
'apply_rules' => $hasOldInput ? (bool)$request->old('apply_rules') : $recurrence->apply_rules,
|
||||
'deposit_source_id' => $array['transactions'][0]['source_id'],
|
||||
'withdrawal_destination_id' => $array['transactions'][0]['destination_id'],
|
||||
|
||||
];
|
||||
|
||||
return view(
|
||||
@ -138,7 +142,7 @@ class EditController extends Controller
|
||||
* Update the recurring transaction.
|
||||
*
|
||||
* @param RecurrenceFormRequest $request
|
||||
* @param Recurrence $recurrence
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
|
@ -48,6 +48,7 @@ class IndexController extends Controller
|
||||
|
||||
/**
|
||||
* IndexController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -121,8 +122,8 @@ class IndexController extends Controller
|
||||
$transformer = app(RecurrenceTransformer::class);
|
||||
$transformer->setParameters(new ParameterBag);
|
||||
|
||||
$array = $transformer->transform($recurrence);
|
||||
$transactions = $this->recurring->getTransactions($recurrence);
|
||||
$array = $transformer->transform($recurrence);
|
||||
$groups = $this->recurring->getTransactions($recurrence);
|
||||
|
||||
// transform dates back to Carbon objects:
|
||||
foreach ($array['recurrence_repetitions'] as $index => $repetition) {
|
||||
@ -133,7 +134,7 @@ class IndexController extends Controller
|
||||
|
||||
$subTitle = (string)trans('firefly.overview_for_recurrence', ['title' => $recurrence->title]);
|
||||
|
||||
return view('recurring.show', compact('recurrence', 'subTitle', 'array', 'transactions'));
|
||||
return view('recurring.show', compact('recurrence', 'subTitle', 'array', 'groups'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ class ExpenseController extends Controller
|
||||
|
||||
/**
|
||||
* Constructor for ExpenseController
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@ -252,11 +253,11 @@ class ExpenseController extends Controller
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('expense-budget');
|
||||
$cache->addProperty('top-expense');
|
||||
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||
$cache->addProperty($expense->pluck('id')->toArray());
|
||||
if ($cache->has()) {
|
||||
return $cache->get(); // @codeCoverageIgnore
|
||||
//return $cache->get(); // @codeCoverageIgnore
|
||||
}
|
||||
$combined = $this->combineAccounts($expense);
|
||||
$all = new Collection;
|
||||
@ -268,11 +269,11 @@ class ExpenseController extends Controller
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setAccounts($accounts);
|
||||
$collector->setAccounts($all);
|
||||
$set = $collector->getExtractedJournals();
|
||||
$collector->setAccounts($all)->withAccountInformation();
|
||||
$sorted = $collector->getExtractedJournals();
|
||||
|
||||
usort($set, function ($a, $b) {
|
||||
return $a['amount'] <=> $b['amount'];
|
||||
usort($sorted, function ($a, $b) {
|
||||
return $a['amount'] <=> $b['amount']; // @codeCoverageIgnore
|
||||
});
|
||||
|
||||
try {
|
||||
@ -304,11 +305,11 @@ class ExpenseController extends Controller
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('expense-budget');
|
||||
$cache->addProperty('top-income');
|
||||
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||
$cache->addProperty($expense->pluck('id')->toArray());
|
||||
if ($cache->has()) {
|
||||
return $cache->get(); // @codeCoverageIgnore
|
||||
//return $cache->get(); // @codeCoverageIgnore
|
||||
}
|
||||
$combined = $this->combineAccounts($expense);
|
||||
$all = new Collection;
|
||||
@ -321,11 +322,15 @@ class ExpenseController extends Controller
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
$total = $accounts->merge($all);
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAccounts($total);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAccounts($total)->withAccountInformation();
|
||||
$sorted = $collector->getExtractedJournals();
|
||||
|
||||
usort($journals, function ($a, $b) {
|
||||
return $a['amount'] <=> $b['amount'];
|
||||
foreach (array_keys($sorted) as $key) {
|
||||
$sorted[$key]['amount'] = bcmul($sorted[$key]['amount'], '-1');
|
||||
}
|
||||
|
||||
usort($sorted, function ($a, $b) {
|
||||
return $a['amount'] <=> $b['amount']; // @codeCoverageIgnore
|
||||
});
|
||||
|
||||
try {
|
||||
|
@ -41,6 +41,7 @@ class OperationsController extends Controller
|
||||
|
||||
/**
|
||||
* OperationsController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -45,6 +45,7 @@ class CreateController extends Controller
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -39,6 +39,7 @@ class DeleteController extends Controller
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -45,6 +45,7 @@ class EditController extends Controller
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -45,6 +45,7 @@ class IndexController extends Controller
|
||||
|
||||
/**
|
||||
* RuleController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ class SelectController extends Controller
|
||||
* Execute the given rule on a set of existing transactions.
|
||||
*
|
||||
* @param SelectTransactionsRequest $request
|
||||
* @param Rule $rule
|
||||
* @param Rule $rule
|
||||
*
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
@ -181,11 +181,12 @@ class SelectController extends Controller
|
||||
// Return json response
|
||||
$view = 'ERROR, see logs.';
|
||||
try {
|
||||
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
|
||||
$view = view('list.journals-array-tiny', ['journals' => $matchingTransactions])->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $exception) {
|
||||
Log::error(sprintf('Could not render view in testTriggers(): %s', $exception->getMessage()));
|
||||
Log::error($exception->getTraceAsString());
|
||||
$view = sprintf('Could not render list.journals-tiny: %s', $exception->getMessage());
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
@ -236,17 +237,17 @@ class SelectController extends Controller
|
||||
|
||||
// Warn the user if only a subset of transactions is returned
|
||||
$warning = '';
|
||||
if ($matchingTransactions->count() === $limit) {
|
||||
if (count($matchingTransactions) === $limit) {
|
||||
$warning = (string)trans('firefly.warning_transaction_subset', ['max_num_transactions' => $limit]); // @codeCoverageIgnore
|
||||
}
|
||||
if (0 === $matchingTransactions->count()) {
|
||||
if (0 === count($matchingTransactions)) {
|
||||
$warning = (string)trans('firefly.warning_no_matching_transactions', ['num_transactions' => $range]); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// Return json response
|
||||
$view = 'ERROR, see logs.';
|
||||
try {
|
||||
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
|
||||
$view = view('list.journals-array-tiny', ['journals' => $matchingTransactions])->render();
|
||||
// @codeCoverageIgnoreStart
|
||||
} catch (Throwable $exception) {
|
||||
Log::error(sprintf('Could not render view in testTriggersByRule(): %s', $exception->getMessage()));
|
||||
|
@ -36,7 +36,31 @@ use Illuminate\Http\Request;
|
||||
*/
|
||||
class IndexController extends Controller
|
||||
{
|
||||
use PeriodOverview;
|
||||
use PeriodOverview;
|
||||
|
||||
/** @var JournalRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* IndexController constructor.
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// translations:
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
app('view')->share('mainTitleIcon', 'fa-credit-card');
|
||||
app('view')->share('title', (string)trans('firefly.accounts'));
|
||||
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Index for a range of transactions.
|
||||
@ -54,6 +78,7 @@ class IndexController extends Controller
|
||||
$types = config('firefly.transactionTypesByType.' . $objectType);
|
||||
$page = (int)$request->get('page');
|
||||
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
||||
$pageSize =3;
|
||||
if (null === $start) {
|
||||
$start = session('start');
|
||||
$end = session('end');
|
||||
@ -62,16 +87,16 @@ class IndexController extends Controller
|
||||
$end = session('end');
|
||||
}
|
||||
|
||||
if ($end < $start) {
|
||||
[$start, $end] = [$end, $start];
|
||||
}
|
||||
|
||||
$path = route('transactions.index', [$objectType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
|
||||
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
$path = route('transactions.index', [$objectType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
|
||||
$startStr = $start->formatLocalized($this->monthAndDayFormat);
|
||||
$endStr = $end->formatLocalized($this->monthAndDayFormat);
|
||||
$subTitle = (string)trans(sprintf('firefly.title_%s_between', $objectType), ['start' => $startStr, 'end' => $endStr]);
|
||||
$periods = $this->getTransactionPeriodOverview($objectType, $end);
|
||||
|
||||
$firstJournal = $this->repository->firstNull();
|
||||
$startPeriod = null === $firstJournal ? new Carbon : $firstJournal->date;
|
||||
$endPeriod = clone $end;
|
||||
$periods = $this->getTransactionPeriodOverview($objectType, $startPeriod, $endPeriod);
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
@ -53,10 +53,10 @@ class StartFireflySession extends StartSession
|
||||
&& 'GET' === $request->method()
|
||||
&& !$request->ajax()) {
|
||||
$session->setPreviousUrl($uri);
|
||||
Log::debug(sprintf('Will set previous URL to %s', $uri));
|
||||
//Log::debug(sprintf('Will set previous URL to %s', $uri));
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug(sprintf('Will NOT set previous URL to %s', $uri));
|
||||
//Log::debug(sprintf('Will NOT set previous URL to %s', $uri));
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Rules\ValidRecurrenceRepetitionType;
|
||||
use FireflyIII\Rules\ValidRecurrenceRepetitionValue;
|
||||
use FireflyIII\Validation\AccountValidator;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class RecurrenceFormRequest
|
||||
@ -136,6 +139,86 @@ class RecurrenceFormRequest extends Request
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure the validator instance with special rules for after the basic validation rules.
|
||||
*
|
||||
* @param Validator $validator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(
|
||||
function (Validator $validator) {
|
||||
// validate all account info
|
||||
$this->validateAccountInformation($validator);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given account information. Switches on given transaction type.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function validateAccountInformation(Validator $validator): void
|
||||
{
|
||||
Log::debug('Now in validateAccountInformation()');
|
||||
/** @var AccountValidator $accountValidator */
|
||||
$accountValidator = app(AccountValidator::class);
|
||||
$data = $validator->getData();
|
||||
$transactionType = $data['transaction_type'] ?? 'invalid';
|
||||
|
||||
$accountValidator->setTransactionType($transactionType);
|
||||
|
||||
// default values:
|
||||
$sourceId = null;
|
||||
$destinationId = null;
|
||||
|
||||
switch ($this->string('transaction_type')) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot handle transaction type "%s"', $this->string('transaction_type'))); // @codeCoverageIgnore
|
||||
case 'withdrawal':
|
||||
$sourceId = (int)$data['source_id'];
|
||||
$destinationId = (int)$data['withdrawal_destination_id'];
|
||||
break;
|
||||
case 'deposit':
|
||||
$sourceId = (int)$data['deposit_source_id'];
|
||||
$destinationId = (int)$data['destination_id'];
|
||||
break;
|
||||
case 'transfer':
|
||||
$sourceId = (int)$data['source_id'];
|
||||
$destinationId = (int)$data['destination_id'];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// validate source account.
|
||||
$validSource = $accountValidator->validateSource($sourceId, null);
|
||||
|
||||
// do something with result:
|
||||
if (false === $validSource) {
|
||||
$message = (string)trans('validation.generic_invalid_source');
|
||||
$validator->errors()->add('source_id', $message);
|
||||
$validator->errors()->add('deposit_source_id', $message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// validate destination account
|
||||
$validDestination = $accountValidator->validateDestination($destinationId, null);
|
||||
// do something with result:
|
||||
if (false === $validDestination) {
|
||||
$message = (string)trans('validation.generic_invalid_destination');
|
||||
$validator->errors()->add('destination_id', $message);
|
||||
$validator->errors()->add('withdrawal_destination_id', $message);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The rules for this request.
|
||||
*
|
||||
|
@ -647,9 +647,13 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
*/
|
||||
public function searchBudget(string $query): Collection
|
||||
{
|
||||
$query = sprintf('%%%s%%', $query);
|
||||
|
||||
return $this->user->budgets()->where('name', 'LIKE', $query)->get();
|
||||
$search = $this->user->budgets();
|
||||
if ('' !== $query) {
|
||||
$search->where('name', 'LIKE', sprintf('%%%s%%', $query));
|
||||
}
|
||||
|
||||
return $search->get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,22 +111,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $collector->getExtractedJournals();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $journals
|
||||
* @return string
|
||||
*/
|
||||
private function sumJournals(array $journals): string
|
||||
{
|
||||
$sum = '0';
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$amount = (string)$journal['amount'];
|
||||
$sum = bcadd($sum, $amount);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* A very cryptic method name that means:
|
||||
*
|
||||
@ -156,7 +140,7 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
$currencyId = (int)$journal['currency_id'];
|
||||
if (!isset($return[$currencyId])) {
|
||||
$return[$currencyId] = [
|
||||
'earned' => '0',
|
||||
'earned' => '0',
|
||||
'currency_id' => $currencyId,
|
||||
'currency_symbol' => $journal['currency_symbol'],
|
||||
'currency_code' => $journal['currency_code'],
|
||||
@ -264,8 +248,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* Find a category or return NULL
|
||||
*
|
||||
@ -278,6 +260,8 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $this->user->categories()->find($categoryId);
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* Find a category.
|
||||
*
|
||||
@ -297,8 +281,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
@ -313,6 +295,8 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $factory->findOrCreate(null, $data['name']);
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
@ -341,47 +325,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $firstJournalDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getFirstJournalDate(Category $category): ?Carbon
|
||||
{
|
||||
$query = $category->transactionJournals()->orderBy('date', 'ASC');
|
||||
$result = $query->first(['transaction_journals.*']);
|
||||
|
||||
if (null !== $result) {
|
||||
return $result->date;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getFirstTransactionDate(Category $category): ?Carbon
|
||||
{
|
||||
// check transactions:
|
||||
$query = $category->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->orderBy('transaction_journals.date', 'ASC');
|
||||
|
||||
$lastTransaction = $query->first(['transaction_journals.*']);
|
||||
if (null !== $lastTransaction) {
|
||||
return new Carbon($lastTransaction->date);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* Get all categories with ID's.
|
||||
*
|
||||
@ -394,8 +337,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $this->user->categories()->whereIn('id', $categoryIds)->get();
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
@ -426,55 +367,7 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $lastJournalDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getLastJournalDate(Category $category, Collection $accounts): ?Carbon
|
||||
{
|
||||
$query = $category->transactionJournals()->orderBy('date', 'DESC');
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$query->leftJoin('transactions as t', 't.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
$query->whereIn('t.account_id', $accounts->pluck('id')->toArray());
|
||||
}
|
||||
|
||||
$result = $query->first(['transaction_journals.*']);
|
||||
|
||||
if (null !== $result) {
|
||||
return $result->date;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Carbon|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function getLastTransactionDate(Category $category, Collection $accounts): ?Carbon
|
||||
{
|
||||
// check transactions:
|
||||
$query = $category->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->orderBy('transaction_journals.date', 'DESC');
|
||||
if ($accounts->count() > 0) {
|
||||
// filter journals:
|
||||
$query->whereIn('transactions.account_id', $accounts->pluck('id')->toArray());
|
||||
}
|
||||
|
||||
$lastTransaction = $query->first(['transaction_journals.*']);
|
||||
if (null !== $lastTransaction) {
|
||||
return new Carbon($lastTransaction->date);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
@ -518,6 +411,8 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $data;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
@ -555,6 +450,8 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
@ -644,9 +541,12 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
*/
|
||||
public function searchCategory(string $query): Collection
|
||||
{
|
||||
$query = sprintf('%%%s%%', $query);
|
||||
$search = $this->user->categories();
|
||||
if ('' !== $query) {
|
||||
$search->where('name', 'LIKE', sprintf('%%%s%%', $query));
|
||||
}
|
||||
|
||||
return $this->user->categories()->where('name', 'LIKE', $query)->get();
|
||||
return $search->get();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -831,4 +731,107 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
|
||||
return $service->update($category, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $journals
|
||||
* @return string
|
||||
*/
|
||||
private function sumJournals(array $journals): string
|
||||
{
|
||||
$sum = '0';
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$amount = (string)$journal['amount'];
|
||||
$sum = bcadd($sum, $amount);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getFirstJournalDate(Category $category): ?Carbon
|
||||
{
|
||||
$query = $category->transactionJournals()->orderBy('date', 'ASC');
|
||||
$result = $query->first(['transaction_journals.*']);
|
||||
|
||||
if (null !== $result) {
|
||||
return $result->date;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getFirstTransactionDate(Category $category): ?Carbon
|
||||
{
|
||||
// check transactions:
|
||||
$query = $category->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->orderBy('transaction_journals.date', 'ASC');
|
||||
|
||||
$lastTransaction = $query->first(['transaction_journals.*']);
|
||||
if (null !== $lastTransaction) {
|
||||
return new Carbon($lastTransaction->date);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
private function getLastJournalDate(Category $category, Collection $accounts): ?Carbon
|
||||
{
|
||||
$query = $category->transactionJournals()->orderBy('date', 'DESC');
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$query->leftJoin('transactions as t', 't.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
$query->whereIn('t.account_id', $accounts->pluck('id')->toArray());
|
||||
}
|
||||
|
||||
$result = $query->first(['transaction_journals.*']);
|
||||
|
||||
if (null !== $result) {
|
||||
return $result->date;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return Carbon|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function getLastTransactionDate(Category $category, Collection $accounts): ?Carbon
|
||||
{
|
||||
// check transactions:
|
||||
$query = $category->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->orderBy('transaction_journals.date', 'DESC');
|
||||
if ($accounts->count() > 0) {
|
||||
// filter journals:
|
||||
$query->whereIn('transactions.account_id', $accounts->pluck('id')->toArray());
|
||||
}
|
||||
|
||||
$lastTransaction = $query->first(['transaction_journals.*']);
|
||||
if (null !== $lastTransaction) {
|
||||
return new Carbon($lastTransaction->date);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
/**
|
||||
* Find by object, ID or code. Returns user default or system default.
|
||||
*
|
||||
* @param int|null $currencyId
|
||||
* @param int|null $currencyId
|
||||
* @param string|null $currencyCode
|
||||
*
|
||||
* @return TransactionCurrency|null
|
||||
@ -288,7 +288,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
/**
|
||||
* Find by object, ID or code. Returns NULL if nothing found.
|
||||
*
|
||||
* @param int|null $currencyId
|
||||
* @param int|null $currencyId
|
||||
* @param string|null $currencyCode
|
||||
*
|
||||
* @return TransactionCurrency|null
|
||||
@ -369,7 +369,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
*
|
||||
* @param TransactionCurrency $fromCurrency
|
||||
* @param TransactionCurrency $toCurrency
|
||||
* @param Carbon $date
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return CurrencyExchangeRate|null
|
||||
*/
|
||||
@ -438,7 +438,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
@ -449,4 +449,18 @@ class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
|
||||
return $service->update($currency, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchCurrency(string $search): Collection
|
||||
{
|
||||
$query = TransactionCurrency::where('enabled', 1);
|
||||
if ('' !== $search) {
|
||||
$query->where('name', 'LIKE', sprintf('%%%s%%', $search));
|
||||
}
|
||||
|
||||
return $query->get();
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,12 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
interface CurrencyRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param string $search
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchCurrency(string $search): Collection;
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
|
@ -54,6 +54,8 @@ use stdClass;
|
||||
*/
|
||||
class JournalRepository implements JournalRepositoryInterface
|
||||
{
|
||||
|
||||
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
@ -67,7 +69,25 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search in journal descriptions.
|
||||
*
|
||||
* @param string $search
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchJournalDescriptions(string $search): Collection
|
||||
{
|
||||
$query = $this->user->transactionJournals()
|
||||
->orderBy('date', 'DESC');
|
||||
if ('' !== $query) {
|
||||
$query->where('description', 'LIKE', sprintf('%%%s%%', $search));
|
||||
}
|
||||
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param TransactionType $type
|
||||
|
@ -41,6 +41,14 @@ use Illuminate\Support\MessageBag;
|
||||
interface JournalRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Search in journal descriptions.
|
||||
*
|
||||
* @param string $search
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchJournalDescriptions(string $search): Collection;
|
||||
|
||||
/**
|
||||
* Get all transaction journals with a specific type, regardless of user.
|
||||
*
|
||||
|
@ -303,13 +303,11 @@ class RecurringRepository implements RecurringRepositoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO check usage and verify it still works.
|
||||
*
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getTransactions(Recurrence $recurrence): array
|
||||
public function getTransactions(Recurrence $recurrence): Collection
|
||||
{
|
||||
$journalMeta = TransactionJournalMeta
|
||||
::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
|
||||
@ -319,9 +317,17 @@ class RecurringRepository implements RecurringRepositoryInterface
|
||||
->where('data', json_encode((string)$recurrence->id))
|
||||
->get()->pluck('transaction_journal_id')->toArray();
|
||||
$search = [];
|
||||
|
||||
|
||||
|
||||
foreach ($journalMeta as $journalId) {
|
||||
$search[] = (int)$journalId;
|
||||
}
|
||||
if (0 === count($search)) {
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
||||
@ -330,7 +336,7 @@ class RecurringRepository implements RecurringRepositoryInterface
|
||||
// filter on specific journals.
|
||||
$collector->setJournalIds($search);
|
||||
|
||||
return $collector->getExtractedJournals();
|
||||
return $collector->getGroups();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,9 +141,9 @@ interface RecurringRepositoryInterface
|
||||
/**
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return array
|
||||
* @return Collection
|
||||
*/
|
||||
public function getTransactions(Recurrence $recurrence): array;
|
||||
public function getTransactions(Recurrence $recurrence): Collection;
|
||||
|
||||
/**
|
||||
* Calculate the next X iterations starting on the date given in $date.
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Repositories\TransactionType;
|
||||
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
@ -46,7 +47,7 @@ class TransactionTypeRepository implements TransactionTypeRepositoryInterface
|
||||
|
||||
/**
|
||||
* @param TransactionType|null $type
|
||||
* @param string|null $typeString
|
||||
* @param string|null $typeString
|
||||
*
|
||||
* @return TransactionType
|
||||
*/
|
||||
@ -67,4 +68,17 @@ class TransactionTypeRepository implements TransactionTypeRepositoryInterface
|
||||
|
||||
return $search;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchTypes(string $query): Collection
|
||||
{
|
||||
if ('' === $query) {
|
||||
return TransactionType::get();
|
||||
}
|
||||
|
||||
return TransactionType::where('type', 'LIKE', sprintf('%%%s%%', $query))->get();
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Repositories\TransactionType;
|
||||
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface TransactionTypeRepositoryInterface
|
||||
@ -44,4 +45,10 @@ interface TransactionTypeRepositoryInterface
|
||||
* @return TransactionType|null
|
||||
*/
|
||||
public function findByType(string $type): ?TransactionType;
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchTypes(string $query): Collection;
|
||||
}
|
@ -36,7 +36,7 @@ class AccountList implements BinderInterface
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param Route $route
|
||||
*
|
||||
* @return Collection
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
@ -44,25 +44,29 @@ class AccountList implements BinderInterface
|
||||
*/
|
||||
public static function routeBinder(string $value, Route $route): Collection
|
||||
{
|
||||
Log::debug(sprintf('Now in AccountList::routeBinder("%s")', $value));
|
||||
if (auth()->check()) {
|
||||
Log::debug('User is logged in.');
|
||||
$collection = new Collection;
|
||||
if ('allAssetAccounts' === $value) {
|
||||
/** @var \Illuminate\Support\Collection $collection */
|
||||
/** @var Collection $collection */
|
||||
$collection = auth()->user()->accounts()
|
||||
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.type', AccountType::ASSET)
|
||||
->orderBy('accounts.name', 'ASC')
|
||||
->get(['accounts.*']);
|
||||
Log::debug(sprintf('Collection length is %d', $collection->count()));
|
||||
}
|
||||
if ('allAssetAccounts' !== $value) {
|
||||
$incoming = array_map('\intval', explode(',', $value));
|
||||
$list = array_merge(array_unique($incoming), [0]);
|
||||
/** @var \Illuminate\Support\Collection $collection */
|
||||
/** @var Collection $collection */
|
||||
$collection = auth()->user()->accounts()
|
||||
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->whereIn('accounts.id', $list)
|
||||
->orderBy('accounts.name', 'ASC')
|
||||
->get(['accounts.*']);
|
||||
Log::debug(sprintf('Collection length is %d', $collection->count()));
|
||||
}
|
||||
|
||||
if ($collection->count() > 0) {
|
||||
|
@ -25,6 +25,7 @@ namespace FireflyIII\Support\Binder;
|
||||
use FireflyIII\Models\Budget;
|
||||
use Illuminate\Routing\Route;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
@ -34,7 +35,7 @@ class BudgetList implements BinderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Route $route
|
||||
* @param Route $route
|
||||
*
|
||||
* @return Collection
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
@ -42,27 +43,36 @@ class BudgetList implements BinderInterface
|
||||
*/
|
||||
public static function routeBinder(string $value, Route $route): Collection
|
||||
{
|
||||
Log::debug(sprintf('Now in BudgetList::routeBinder("%s")', $value));
|
||||
if (auth()->check()) {
|
||||
$list = array_unique(array_map('\intval', explode(',', $value)));
|
||||
Log::debug('List is now', $list);
|
||||
if (0 === count($list)) {
|
||||
Log::warning('List count is zero, return 404.');
|
||||
throw new NotFoundHttpException; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/** @var \Illuminate\Support\Collection $collection */
|
||||
/** @var Collection $collection */
|
||||
$collection = auth()->user()->budgets()
|
||||
->where('active', 1)
|
||||
->whereIn('id', $list)
|
||||
->get();
|
||||
Log::debug(sprintf('Found %d active budgets', $collection->count()), $list);
|
||||
|
||||
// add empty budget if applicable.
|
||||
if (in_array(0, $list, true)) {
|
||||
Log::debug('Add empty budget because $list contains 0.');
|
||||
$collection->push(new Budget);
|
||||
}
|
||||
|
||||
if ($collection->count() > 0) {
|
||||
Log::debug(sprintf('List length is > 0 (%d), so return it.', $collection->count()));
|
||||
|
||||
return $collection;
|
||||
}
|
||||
Log::debug('List length is zero, fall back to 404.');
|
||||
}
|
||||
Log::debug('Final fallback to 404.');
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
}
|
||||
|
@ -102,10 +102,7 @@ class ExpandedForm
|
||||
{
|
||||
// make repositories
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
/** @var CurrencyRepositoryInterface $currencyRepos */
|
||||
$currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$accountList = $repository->getActiveAccountsByType(
|
||||
[AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN,]
|
||||
);
|
||||
@ -113,12 +110,15 @@ class ExpandedForm
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$grouped = [];
|
||||
// group accounts:
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accountList as $account) {
|
||||
$balance = app('steam')->balance($account, new Carbon);
|
||||
$currencyId = (int)$repository->getMetaValue($account, 'currency_id');
|
||||
$currency = $currencyRepos->findNull($currencyId);
|
||||
$role = $repository->getMetaValue($account, 'account_role');
|
||||
$balance = app('steam')->balance($account, new Carbon);
|
||||
|
||||
$currency = $repository->getAccountCurrency($account) ?? $defaultCurrency;
|
||||
|
||||
$role = $repository->getMetaValue($account, 'account_role');
|
||||
|
||||
if ('' === $role && !in_array($account->accountType->type, $liabilityTypes, true)) {
|
||||
$role = 'no_account_type'; // @codeCoverageIgnore
|
||||
}
|
||||
@ -126,15 +126,11 @@ class ExpandedForm
|
||||
if (in_array($account->accountType->type, $liabilityTypes, true)) {
|
||||
$role = 'l_' . $account->accountType->type; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
if (null === $currency) {
|
||||
$currency = $defaultCurrency;
|
||||
}
|
||||
|
||||
$key = (string)trans('firefly.opt_group_' . $role);
|
||||
$grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')';
|
||||
}
|
||||
|
||||
|
||||
return $this->select($name, $grouped, $value, $options);
|
||||
}
|
||||
|
||||
@ -152,8 +148,6 @@ class ExpandedForm
|
||||
// make repositories
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
/** @var CurrencyRepositoryInterface $currencyRepos */
|
||||
$currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
$accountList = $repository->getActiveAccountsByType(
|
||||
[
|
||||
@ -176,10 +170,9 @@ class ExpandedForm
|
||||
// group accounts:
|
||||
/** @var Account $account */
|
||||
foreach ($accountList as $account) {
|
||||
$balance = app('steam')->balance($account, new Carbon);
|
||||
$currencyId = (int)$repository->getMetaValue($account, 'currency_id');
|
||||
$currency = $currencyRepos->findNull($currencyId);
|
||||
$role = (string)$repository->getMetaValue($account, 'account_role');
|
||||
$balance = app('steam')->balance($account, new Carbon);
|
||||
$currency = $repository->getAccountCurrency($account) ?? $defaultCurrency;
|
||||
$role = (string)$repository->getMetaValue($account, 'account_role');
|
||||
if ('' === $role && !in_array($account->accountType->type, $liabilityTypes, true)) {
|
||||
$role = 'no_account_type'; // @codeCoverageIgnore
|
||||
}
|
||||
@ -217,8 +210,6 @@ class ExpandedForm
|
||||
// make repositories
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
/** @var CurrencyRepositoryInterface $currencyRepos */
|
||||
$currencyRepos = app(CurrencyRepositoryInterface::class);
|
||||
|
||||
$accountList = $repository->getActiveAccountsByType(
|
||||
[
|
||||
@ -241,10 +232,9 @@ class ExpandedForm
|
||||
// group accounts:
|
||||
/** @var Account $account */
|
||||
foreach ($accountList as $account) {
|
||||
$balance = app('steam')->balance($account, new Carbon);
|
||||
$currencyId = (int)$repository->getMetaValue($account, 'currency_id');
|
||||
$currency = $currencyRepos->findNull($currencyId);
|
||||
$role = (string)$repository->getMetaValue($account, 'account_role');
|
||||
$balance = app('steam')->balance($account, new Carbon);
|
||||
$currency = $repository->getAccountCurrency($account) ?? $defaultCurrency;
|
||||
$role = (string)$repository->getMetaValue($account, 'account_role');
|
||||
if ('' === $role && !in_array($account->accountType->type, $liabilityTypes, true)) {
|
||||
$role = 'no_account_type'; // @codeCoverageIgnore
|
||||
}
|
||||
@ -257,10 +247,6 @@ class ExpandedForm
|
||||
$role = 'l_' . $account->accountType->type; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
if (null === $currency) {
|
||||
$currency = $defaultCurrency;
|
||||
}
|
||||
|
||||
$key = (string)trans('firefly.opt_group_' . $role);
|
||||
$grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')';
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -81,10 +80,7 @@ trait PeriodOverview
|
||||
protected function getAccountPeriodOverview(Account $account, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||
|
||||
if ($end < $start) {
|
||||
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||
}
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
|
||||
// properties for cache
|
||||
$cache = new CacheProperties;
|
||||
@ -159,10 +155,7 @@ trait PeriodOverview
|
||||
protected function getCategoryPeriodOverview(Category $category, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||
|
||||
if ($end < $start) {
|
||||
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||
}
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
|
||||
// properties for entries with their amounts.
|
||||
$cache = new CacheProperties();
|
||||
@ -173,7 +166,7 @@ trait PeriodOverview
|
||||
$cache->addProperty($category->id);
|
||||
|
||||
if ($cache->has()) {
|
||||
//return $cache->get(); // @codeCoverageIgnore
|
||||
return $cache->get(); // @codeCoverageIgnore
|
||||
}
|
||||
/** @var array $dates */
|
||||
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
||||
@ -240,9 +233,7 @@ trait PeriodOverview
|
||||
{
|
||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||
|
||||
if ($end < $start) {
|
||||
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||
}
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
@ -250,7 +241,7 @@ trait PeriodOverview
|
||||
$cache->addProperty('no-budget-period-entries');
|
||||
|
||||
if ($cache->has()) {
|
||||
//return $cache->get(); // @codeCoverageIgnore
|
||||
return $cache->get(); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/** @var array $dates */
|
||||
@ -284,6 +275,8 @@ trait PeriodOverview
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO fix date.
|
||||
*
|
||||
* Show period overview for no category view.
|
||||
*
|
||||
* @param Carbon $theDate
|
||||
@ -309,7 +302,7 @@ trait PeriodOverview
|
||||
$cache->addProperty('no-category-period-entries');
|
||||
|
||||
if ($cache->has()) {
|
||||
//return $cache->get(); // @codeCoverageIgnore
|
||||
return $cache->get(); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
||||
@ -379,11 +372,7 @@ trait PeriodOverview
|
||||
/** @var Carbon $end */
|
||||
$start = clone $date;
|
||||
$end = $repository->firstUseDate($tag) ?? new Carbon;
|
||||
|
||||
|
||||
if ($end < $start) {
|
||||
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||
}
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
|
||||
// properties for entries with their amounts.
|
||||
$cache = new CacheProperties;
|
||||
@ -431,63 +420,60 @@ trait PeriodOverview
|
||||
* @param string $transactionType
|
||||
* @param Carbon $endDate
|
||||
*
|
||||
* @return Collection
|
||||
* @return array
|
||||
*/
|
||||
protected function getTransactionPeriodOverview(string $transactionType, Carbon $endDate): Collection
|
||||
protected function getTransactionPeriodOverview(string $transactionType, Carbon $start, Carbon $end): array
|
||||
{
|
||||
die('not yet complete');
|
||||
/** @var JournalRepositoryInterface $repository */
|
||||
$repository = app(JournalRepositoryInterface::class);
|
||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||
$endJournal = $repository->firstNull();
|
||||
$end = null === $endJournal ? new Carbon : $endJournal->date;
|
||||
$start = clone $endDate;
|
||||
$types = config('firefly.transactionTypesByType.' . $transactionType);
|
||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||
$types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType));
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
|
||||
if ($end < $start) {
|
||||
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||
// properties for cache
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('transactions-period-entries');
|
||||
$cache->addProperty($transactionType);
|
||||
if ($cache->has()) {
|
||||
// return $cache->get(); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/** @var array $dates */
|
||||
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
||||
$entries = new Collection;
|
||||
$entries = [];
|
||||
|
||||
// collect all journals in this period (regardless of type)
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes($types)->setRange($start, $end);
|
||||
$genericSet = $collector->getExtractedJournals();
|
||||
|
||||
foreach ($dates as $currentDate) {
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTypes($types)->setRange($currentDate['start'], $currentDate['end']);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$amounts = $this->getJournalsSum($journals);
|
||||
|
||||
$spent = [];
|
||||
$earned = [];
|
||||
$transferred = [];
|
||||
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
|
||||
|
||||
// set to correct array
|
||||
if ('expenses' === $transactionType || 'withdrawal' === $transactionType) {
|
||||
$spent = $amounts;
|
||||
$spent = $this->filterJournalsByDate($genericSet, $currentDate['start'], $currentDate['end']);
|
||||
}
|
||||
if ('revenue' === $transactionType || 'deposit' === $transactionType) {
|
||||
$earned = $amounts;
|
||||
$earned = $this->filterJournalsByDate($genericSet, $currentDate['start'], $currentDate['end']);
|
||||
}
|
||||
if ('transfer' === $transactionType || 'transfers' === $transactionType) {
|
||||
$transferred = $amounts;
|
||||
$transferred = $this->filterJournalsByDate($genericSet, $currentDate['start'], $currentDate['end']);
|
||||
}
|
||||
|
||||
|
||||
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
|
||||
$entries->push(
|
||||
$entries[] =
|
||||
[
|
||||
'transactions' => $amounts['count'],
|
||||
'title' => $title,
|
||||
'spent' => $spent,
|
||||
'earned' => $earned,
|
||||
'transferred' => $transferred,
|
||||
'route' => route(
|
||||
'transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
|
||||
),
|
||||
]
|
||||
);
|
||||
'title' => $title,
|
||||
'route' =>
|
||||
route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
||||
'spent' => $this->groupByCurrency($spent),
|
||||
'earned' => $this->groupByCurrency($earned),
|
||||
'transferred' => $this->groupByCurrency($transferred),
|
||||
];
|
||||
}
|
||||
|
||||
return $entries;
|
||||
|
@ -178,7 +178,7 @@ trait RequestInformation
|
||||
// both must be array and either must be > 0
|
||||
if (count($intro) > 0 || count($specialIntro) > 0) {
|
||||
$shownDemo = app('preferences')->get($key, false)->data;
|
||||
Log::debug(sprintf('Check if user has already seen intro with key "%s". Result is %s', $key, var_export($shownDemo, true)));
|
||||
//Log::debug(sprintf('Check if user has already seen intro with key "%s". Result is %s', $key, var_export($shownDemo, true)));
|
||||
}
|
||||
if (!is_bool($shownDemo)) {
|
||||
$shownDemo = true;
|
||||
|
@ -50,7 +50,7 @@ trait UserNavigation
|
||||
*/
|
||||
protected function getPreviousUri(string $identifier): string
|
||||
{
|
||||
Log::debug(sprintf('Trying to retrieve URL stored under "%s"', $identifier));
|
||||
// Log::debug(sprintf('Trying to retrieve URL stored under "%s"', $identifier));
|
||||
// "forbidden" words for specific identifiers:
|
||||
// if these are in the previous URI, don't refer back there.
|
||||
$array = [
|
||||
@ -67,24 +67,24 @@ trait UserNavigation
|
||||
'transactions.mass-delete.uri' => '/transactions/show/',
|
||||
];
|
||||
$forbidden = $array[$identifier] ?? '/show/';
|
||||
Log::debug(sprintf('The forbidden word for %s is "%s"', $identifier, $forbidden));
|
||||
//Log::debug(sprintf('The forbidden word for %s is "%s"', $identifier, $forbidden));
|
||||
|
||||
$uri = (string)session($identifier);
|
||||
Log::debug(sprintf('The URI is %s', $uri));
|
||||
//Log::debug(sprintf('The URI is %s', $uri));
|
||||
if (
|
||||
!(false === strpos($identifier, 'delete'))
|
||||
&& !(false === strpos($uri, $forbidden))) {
|
||||
$uri = $this->redirectUri;
|
||||
Log::debug(sprintf('URI is now %s (identifier contains "delete")', $uri));
|
||||
//Log::debug(sprintf('URI is now %s (identifier contains "delete")', $uri));
|
||||
}
|
||||
if (!(false === strpos($uri, 'jscript'))) {
|
||||
$uri = $this->redirectUri; // @codeCoverageIgnore
|
||||
Log::debug(sprintf('URI is now %s (uri contains jscript)', $uri));
|
||||
//Log::debug(sprintf('URI is now %s (uri contains jscript)', $uri));
|
||||
}
|
||||
|
||||
// more debug notes:
|
||||
Log::debug(sprintf('strpos($identifier, "delete"): %s', var_export(strpos($identifier, 'delete'), true)));
|
||||
Log::debug(sprintf('strpos($uri, $forbidden): %s', var_export(strpos($uri, $forbidden), true)));
|
||||
//Log::debug(sprintf('strpos($identifier, "delete"): %s', var_export(strpos($identifier, 'delete'), true)));
|
||||
//Log::debug(sprintf('strpos($uri, $forbidden): %s', var_export(strpos($uri, $forbidden), true)));
|
||||
|
||||
return $uri;
|
||||
}
|
||||
@ -154,10 +154,10 @@ trait UserNavigation
|
||||
if (null === $errors || (null !== $errors && 0 === $errors->count())) {
|
||||
$url = app('url')->previous();
|
||||
session()->put($identifier, $url);
|
||||
Log::debug(sprintf('Will put previous URI in cache under key %s: %s', $identifier, $url));
|
||||
//Log::debug(sprintf('Will put previous URI in cache under key %s: %s', $identifier, $url));
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug(sprintf('The users session contains errors somehow so we will not remember the URI!: %s', var_export($errors, true)));
|
||||
//Log::debug(sprintf('The users session contains errors somehow so we will not remember the URI!: %s', var_export($errors, true)));
|
||||
}
|
||||
}
|
||||
|
@ -265,10 +265,10 @@ class TransactionMatcher
|
||||
// - all transactions have been fetched from the database
|
||||
// - the maximum number of transactions to return has been found
|
||||
// - the maximum number of transactions to search in have been searched
|
||||
$pageSize = min($this->searchLimit, min($this->triggeredLimit, 50));
|
||||
$processed = 0;
|
||||
$page = 1;
|
||||
$result = [];
|
||||
$pageSize = min($this->searchLimit, min($this->triggeredLimit, 50));
|
||||
$processed = 0;
|
||||
$page = 1;
|
||||
$totalResult = [];
|
||||
|
||||
Log::debug(sprintf('Search limit is %d, triggered limit is %d, so page size is %d', $this->searchLimit, $this->triggeredLimit, $pageSize));
|
||||
|
||||
@ -322,8 +322,8 @@ class TransactionMatcher
|
||||
Log::debug(sprintf('Found %d journals that match.', count($filtered)));
|
||||
|
||||
// merge:
|
||||
$result = $result + $filtered;
|
||||
Log::debug(sprintf('Total count is now %d', count($result)));
|
||||
$totalResult = $totalResult + $filtered;
|
||||
Log::debug(sprintf('Total count is now %d', count($totalResult)));
|
||||
|
||||
// Update counters
|
||||
++$page;
|
||||
@ -333,7 +333,7 @@ class TransactionMatcher
|
||||
|
||||
// Check for conditions to finish the loop
|
||||
$reachedEndOfList = count($journals) < 1;
|
||||
$foundEnough = count($result) >= $this->triggeredLimit;
|
||||
$foundEnough = count($totalResult) >= $this->triggeredLimit;
|
||||
$searchedEnough = ($processed >= $this->searchLimit);
|
||||
|
||||
Log::debug(sprintf('reachedEndOfList: %s', var_export($reachedEndOfList, true)));
|
||||
@ -342,6 +342,6 @@ class TransactionMatcher
|
||||
} while (!$reachedEndOfList && !$foundEnough && !$searchedEnough);
|
||||
Log::debug('End of do-loop');
|
||||
|
||||
return $result;
|
||||
return $totalResult;
|
||||
}
|
||||
}
|
||||
|
@ -70,8 +70,15 @@ final class CurrencyIs extends AbstractTrigger implements TriggerInterface
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$currency = $repository->findByNameNull($this->triggerValue);
|
||||
$hit = true;
|
||||
|
||||
// if currency name contains " ("
|
||||
if (0 === strpos($this->triggerValue, ' (')) {
|
||||
$parts = explode(' (', $this->triggerValue);
|
||||
$this->triggerValue = $parts[0];
|
||||
}
|
||||
|
||||
$currency = $repository->findByNameNull($this->triggerValue);
|
||||
$hit = true;
|
||||
if (null !== $currency) {
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions as $transaction) {
|
||||
|
@ -41,7 +41,7 @@ trait TransactionValidation
|
||||
*/
|
||||
public function validateAccountInformation(Validator $validator): void
|
||||
{
|
||||
Log::debug('Now in validateAccountInformation()');
|
||||
//Log::debug('Now in validateAccountInformation()');
|
||||
$data = $validator->getData();
|
||||
|
||||
$transactionType = $data['type'] ?? 'invalid';
|
||||
|
4
public/v1/css/firefly.css
vendored
4
public/v1/css/firefly.css
vendored
@ -19,6 +19,10 @@
|
||||
*/
|
||||
|
||||
|
||||
.no-margin-pagination {padding-bottom:0;padding-top:0;}
|
||||
.no-margin-pagination ul.pagination {margin:0 !important;}
|
||||
|
||||
|
||||
input.ti-new-tag-input {
|
||||
font-size: 14px !important;
|
||||
line-height: 1.42857143;
|
||||
|
9
public/v1/js/ff/recurring/create.js
vendored
9
public/v1/js/ff/recurring/create.js
vendored
@ -189,13 +189,13 @@ function updateFormFields() {
|
||||
// show source account ID:
|
||||
$('#source_id_holder').show();
|
||||
|
||||
// show destination name:
|
||||
// $('#destination_name_holder').show(); // old one
|
||||
$('#withdrawal_destination_id_holder').show();
|
||||
|
||||
// hide destination ID:
|
||||
$('#destination_id_holder').hide();
|
||||
|
||||
// show destination name:
|
||||
//$('#destination_name_holder').show(); // old one
|
||||
$('#withdrawal_destination_id_holder').show();
|
||||
|
||||
// show budget
|
||||
$('#budget_id_holder').show();
|
||||
|
||||
@ -212,7 +212,6 @@ function updateFormFields() {
|
||||
// $('#destination_name_holder').hide(); // old one
|
||||
$('#withdrawal_destination_id_holder').hide();
|
||||
|
||||
|
||||
$('#destination_id_holder').show();
|
||||
$('#budget_id_holder').hide();
|
||||
$('#piggy_bank_id_holder').hide();
|
||||
|
24
public/v1/js/ff/recurring/edit.js
vendored
24
public/v1/js/ff/recurring/edit.js
vendored
@ -184,13 +184,15 @@ function updateFormFields() {
|
||||
|
||||
if (transactionType === 'withdrawal') {
|
||||
// hide source account name:
|
||||
$('#source_name_holder').hide();
|
||||
// $('#source_name_holder').hide(); // no longer used
|
||||
$('#deposit_source_id_holder').hide();
|
||||
|
||||
// show source account ID:
|
||||
$('#source_id_holder').show();
|
||||
|
||||
// show destination name:
|
||||
$('#destination_name_holder').show();
|
||||
// $('#destination_name_holder').show(); // no longer used.
|
||||
$('#withdrawal_destination_id_holder').show();
|
||||
|
||||
// hide destination ID:
|
||||
$('#destination_id_holder').hide();
|
||||
@ -203,18 +205,28 @@ function updateFormFields() {
|
||||
}
|
||||
|
||||
if (transactionType === 'deposit') {
|
||||
$('#source_name_holder').show();
|
||||
// $('#source_name_holder').show(); // no longer used
|
||||
$('#deposit_source_id_holder').show();
|
||||
|
||||
$('#source_id_holder').hide();
|
||||
$('#destination_name_holder').hide();
|
||||
|
||||
// $('#destination_name_holder').hide(); // no longer used
|
||||
$('#withdrawal_destination_id_holder').hide();
|
||||
|
||||
$('#destination_id_holder').show();
|
||||
$('#budget_id_holder').hide();
|
||||
$('#piggy_bank_id_holder').hide();
|
||||
}
|
||||
|
||||
if (transactionType === 'transfer') {
|
||||
$('#source_name_holder').hide();
|
||||
// $('#source_name_holder').hide(); // no longer used
|
||||
$('#deposit_source_id_holder').hide();
|
||||
|
||||
$('#source_id_holder').show();
|
||||
$('#destination_name_holder').hide();
|
||||
|
||||
// $('#destination_name_holder').hide(); // no longer used
|
||||
$('#withdrawal_destination_id_holder').show();
|
||||
|
||||
$('#destination_id_holder').show();
|
||||
$('#budget_id_holder').hide();
|
||||
$('#piggy_bank_id_holder').show();
|
||||
|
10
public/v1/js/ff/rules/create-edit.js
vendored
10
public/v1/js/ff/rules/create-edit.js
vendored
@ -307,7 +307,7 @@ function updateTriggerInput(selectList) {
|
||||
case 'to_account_is':
|
||||
case 'to_account_contains':
|
||||
console.log('Select list value is ' + selectList.val() + ', so input needs auto complete.');
|
||||
createAutoComplete(inputResult, 'json/all-accounts');
|
||||
createAutoComplete(inputResult, 'json/accounts');
|
||||
break;
|
||||
case 'tag_is':
|
||||
console.log('Select list value is ' + selectList.val() + ', so input needs auto complete.');
|
||||
@ -377,8 +377,8 @@ function createAutoComplete(input, URI) {
|
||||
prefetch: {
|
||||
url: URI + '?uid=' + uid,
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
return $.map(list, function (item) {
|
||||
return {name: item.name};
|
||||
});
|
||||
}
|
||||
},
|
||||
@ -386,8 +386,8 @@ function createAutoComplete(input, URI) {
|
||||
url: URI + '?search=%QUERY&uid=' + uid,
|
||||
wildcard: '%QUERY',
|
||||
filter: function (list) {
|
||||
return $.map(list, function (name) {
|
||||
return {name: name};
|
||||
return $.map(list, function (item) {
|
||||
return {name: item.name};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -189,4 +189,7 @@ return [
|
||||
'ob_source_need_data' => 'Need to get a valid source account ID and/or valid source account name to continue.',
|
||||
'ob_dest_need_data' => 'Need to get a valid destination account ID and/or valid destination account name to continue.',
|
||||
'ob_dest_bad_data' => 'Could not find a valid destination account when searching for ID ":id" or name ":name".',
|
||||
|
||||
'generic_invalid_source' => 'You can\'t use this account as the source account.',
|
||||
'generic_invalid_destination' => 'You can\'t use this account as the destination account.',
|
||||
];
|
||||
|
@ -5,9 +5,12 @@ TODO: hide and show columns
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
{{ groups.render|raw }}
|
||||
</th>
|
||||
<td colspan="7" class="no-margin-pagination">{{ groups.render|raw }}</td>
|
||||
<td colspan="1">
|
||||
<div class="pull-right">
|
||||
<input id="list_ALL" value="1" name="all" type="checkbox" class="mass-select-all form-check-inline"/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -16,7 +19,7 @@ TODO: hide and show columns
|
||||
<tr>
|
||||
<td colspan="2" style="border-top:1px #aaa solid;">
|
||||
<small><strong>
|
||||
<a href="{{ route('transactions.edit', [group.id]) }}" title="{{ group.title }}">{{ group.title }}</a>
|
||||
<a href="{{ route('transactions.show', [group.id]) }}" title="{{ group.title }}">{{ group.title }}</a>
|
||||
</strong></small>
|
||||
</td>
|
||||
<td colspan="2" style="border-top:1px #aaa solid;">
|
||||
@ -25,7 +28,7 @@ TODO: hide and show columns
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td colspan="2" style="border-top:1px #aaa solid;"> </td>
|
||||
<td style="border-top:1px #aaa solid;">
|
||||
<td style="border-top:1px #aaa solid;" colspan="2">
|
||||
<div class="btn-group btn-group-xs">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ 'actions'|_ }} <span class="caret"></span></button>
|
||||
@ -41,52 +44,54 @@ TODO: hide and show columns
|
||||
{% for index, transaction in group.transactions %}
|
||||
{% set style="" %}
|
||||
{% if group.transactions|length == loop.index and group.count > 1 %}
|
||||
{% set style="style='border-bottom:1px #aaa solid;'" %}
|
||||
{% set style="border-bottom:1px #aaa solid;" %}
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td {{ style|raw }}>
|
||||
{% if journal.transaction_type_type == 'Withdrawal' %}
|
||||
<td style=" {{ style|raw }}">
|
||||
{% if transaction.transaction_type_type == 'Withdrawal' %}
|
||||
<i class="fa fa-long-arrow-left fa-fw" title="{{ trans('firefly.Withdrawal') }}"></i>
|
||||
{% endif %}
|
||||
|
||||
{% if journal.transaction_type_type == 'Deposit' %}
|
||||
{% if transaction.transaction_type_type == 'Deposit' %}
|
||||
<i class="fa fa-long-arrow-right fa-fw" title="{{ trans('firefly.Deposit') }}"></i>
|
||||
{% endif %}
|
||||
|
||||
{% if journal.transaction_type_type == 'Transfer' %}
|
||||
{% if transaction.transaction_type_type == 'Transfer' %}
|
||||
<i class="fa fa-exchange fa-fw" title="{{ trans('firefly.Deposit') }}"></i>
|
||||
{% endif %}
|
||||
|
||||
{% if journal.transaction_type_type == 'Reconciliation' %}
|
||||
{% if transaction.transaction_type_type == 'Reconciliation' %}
|
||||
<i class="fa-fw fa fa-calculator" title="{{ trans('firefly.reconciliation_transaction') }}"></i>
|
||||
{% endif %}
|
||||
{% if journal.transaction_type_type == 'Opening balance' %}
|
||||
{% if transaction.transaction_type_type == 'Opening balance' %}
|
||||
<i class="fa-fw fa fa-star-o" title="{{ trans('firefly.Opening balance') }}"></i>
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
<td {{ style|raw }}>
|
||||
<td style=" {{ style|raw }}">
|
||||
{% if transaction.reconciled %}
|
||||
<i class="fa fa-check"></i>
|
||||
{% endif %}
|
||||
<a href="{{ route('transactions.show', [group.id]) }}" title="{{ transaction.description }}">{{ transaction.description }}</a>
|
||||
</td>
|
||||
<td {{ style|raw }}>
|
||||
<td style=" {{ style|raw }}">
|
||||
{{ formatAmountBySymbol(transaction.amount, transaction.currency_symbol, transaction.currency_symbol_decimal_places) }}
|
||||
{% if null != transaction.foreign_amount %}
|
||||
({{ formatAmountBySymbol(transaction.foreign_amount, transaction.foreign_currency_symbol, transaction.foreign_currency_symbol_decimal_places) }})
|
||||
{% endif %}
|
||||
</td>
|
||||
<td {{ style|raw }}>{{ transaction.date.formatLocalized(monthAndDayFormat) }}</td>
|
||||
<td {{ style|raw }}>
|
||||
<td style=" {{ style|raw }}">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
</td>
|
||||
<td style=" {{ style|raw }}">
|
||||
<a href="{{ route('accounts.show', [transaction.source_account_id]) }}"
|
||||
title="{{ transaction.source_account_iban|default(transaction.source_account_name) }}">{{ transaction.source_account_name }}</a>
|
||||
</td>
|
||||
<td {{ style|raw }}>
|
||||
<td style=" {{ style|raw }}">
|
||||
<a href="{{ route('accounts.show', [transaction.destination_account_id]) }}"
|
||||
title="{{ transaction.destination_account_iban|default(transaction.destination_account_name) }}">{{ transaction.destination_account_name }}</a>
|
||||
</td>
|
||||
<td {{ style|raw }}>
|
||||
<td style=" {{ style|raw }}">
|
||||
{% if group.count == 1 %}
|
||||
<div class="btn-group btn-group-xs">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
@ -99,10 +104,35 @@ TODO: hide and show columns
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="{{ style|raw }}">
|
||||
<div class="pull-right">
|
||||
<input id="list_{{ transaction.transaction_journal_id }}" value="1" name="journals[{{ transaction.transaction_journal_id }}]"
|
||||
type="checkbox" class="mass-select form-check-inline" data-value="{{ transaction.transaction_journal_id }}"/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="8">
|
||||
<div class="pull-right">
|
||||
<!-- Single button -->
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ 'actions'|_ }} <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Edit individually (x)</a></li>
|
||||
<li><a href="#">Bulk edit (x)</a></li>
|
||||
<li><a href="#">Delete (x)</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="#">Separated link</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
|
||||
|
10
resources/views/v1/list/journals-array-tiny.twig
Normal file
10
resources/views/v1/list/journals-array-tiny.twig
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="list-group">
|
||||
{% for journal in journals %}
|
||||
<a class="list-group-item" href="{{ route('transactions.show', [journal.transaction_group_id]) }}">
|
||||
{{ journal.description }}
|
||||
<span class="pull-right small">
|
||||
{{ journalArrayAmount(journal) }}
|
||||
</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
@ -91,13 +91,19 @@
|
||||
{{ ExpandedForm.longAccountList('source_id', array.transactions[0].source_id, {label: trans('form.asset_source_account')}) }}
|
||||
|
||||
{# source account name for deposits: #}
|
||||
{{ ExpandedForm.text('source_name', array.transactions[0].source_name, {label: trans('form.revenue_account')}) }}
|
||||
{#{{ ExpandedForm.text('source_name', array.transactions[0].source_name, {label: trans('form.revenue_account')}) }}#}
|
||||
|
||||
{# NEW for deposits, a drop down with revenue accounts, loan debt cash and mortgage #}
|
||||
{{ ExpandedForm.activeDepositDestinations('deposit_source_id', preFilled.deposit_source_id, {label: trans('form.deposit_source_id')}) }}
|
||||
|
||||
{# destination if deposit or transfer: #}
|
||||
{{ ExpandedForm.longAccountList('destination_id', array.transactions[0].destination_id, {label: trans('form.asset_destination_account')} ) }}
|
||||
|
||||
{# destination account name for withdrawals #}
|
||||
{{ ExpandedForm.text('destination_name', array.transactions[0].destination_name, {label: trans('form.expense_account')}) }}
|
||||
{# {{ ExpandedForm.text('destination_name', array.transactions[0].destination_name, {label: trans('form.expense_account')}) }}#}
|
||||
|
||||
{# NEW for withdrawals, also a drop down with expense accounts, loans, debts, mortgages or (cash). #}
|
||||
{{ ExpandedForm.activeWithdrawalDestinations('withdrawal_destination_id', preFilled.withdrawal_destination_id, {label: trans('form.withdrawal_destination_id')}) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -198,7 +198,7 @@
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% include 'list.transactions' with {showBudgets:true, showCategories:true} %}
|
||||
{% include 'list.groups' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -31,7 +31,7 @@
|
||||
{{ '0'|formatAmount }}
|
||||
{% else %}
|
||||
{% for income in entry.earned.per_currency %}
|
||||
{{ formatAmountBySymbol(income.sum, income.currency.symbol, income.currency.dp) }}<br/>
|
||||
{{ formatAmountBySymbol(income.sum * -1, income.currency.symbol, income.currency.dp) }}<br/>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</td>
|
||||
|
@ -23,7 +23,7 @@
|
||||
{{ '0'|formatAmount }}
|
||||
{% endif %}
|
||||
{% for income in amounts.earned.per_currency %}
|
||||
{{ formatAmountBySymbol(income.sum, income.currency.symbol, income.currency.dp) }}<br/>
|
||||
{{ formatAmountBySymbol(income.sum * -1, income.currency.symbol, income.currency.dp) }}<br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -10,15 +10,21 @@
|
||||
<tbody>
|
||||
{% for transaction in sorted %}
|
||||
<tr>
|
||||
<td data-value="{{ transaction.opposing_account_name }}">
|
||||
<a href="{{ route('accounts.show',transaction.opposing_account_id) }}">{{ transaction.opposing_account_name }}</a>
|
||||
<td data-value="{{ transaction.destination_account_name }}">
|
||||
<a href="{{ route('accounts.show',transaction.destination_account_id) }}">{{ transaction.destination_account_name }}</a>
|
||||
</td>
|
||||
<td data-value="{{ transaction.description }}">{{ transaction.description }}</td>
|
||||
<td data-value="{{ transaction.date.format('Y-m-d') }}">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
</td><!-- TODO i dont think transactionAmount will work -->
|
||||
<td style="text-align: right;" data-value="{{ transaction.transaction_amount }}"><span
|
||||
style="margin-right:5px;">{{ transaction|transactionAmount }}</span></td>
|
||||
<td style="text-align: right;" data-value="{{ transaction.amount}}"><span
|
||||
style="margin-right:5px;">
|
||||
|
||||
{{ formatAmountBySymbol(transaction.amount, transaction.currency_symbol, transaction.currency_symbol_decimal_places) }}
|
||||
{% if null != transaction.foreign_amount %}
|
||||
({{ formatAmountBySymbol(transaction.foreign_amount, transaction.foreign_currency_symbol, transaction.foreign_currency_symbol_decimal_places) }})
|
||||
{% endif %}
|
||||
</span></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -7,7 +7,7 @@
|
||||
{% block content %}
|
||||
|
||||
{# upper show-all instruction #}
|
||||
{% if periods.count > 0 %}
|
||||
{% if periods|length > 0 %}
|
||||
<div class="row">
|
||||
<div class="col-lg-offset-10 col-lg-2 col-md-offset-10 col-md-2 col-sm-12 col-xs-12">
|
||||
<p class="small text-center"><a href="{{ route('transactions.index.all',[transactionType]) }}">{{ 'showEverything'|_ }}</a></p>
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
{# list with journals #}
|
||||
<div class="row">
|
||||
<div class="{% if periods.count > 0 %}col-lg-10 col-md-10 col-sm-12{% else %}col-lg-12 col-md-12 col-sm-12{% endif %}">
|
||||
<div class="{% if periods|length > 0 %}col-lg-10 col-md-10 col-sm-12{% else %}col-lg-12 col-md-12 col-sm-12{% endif %}">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ subTitle }}</h3>
|
||||
@ -31,7 +31,7 @@
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
{# links for other views #}
|
||||
{% if periods.count > 0 %}
|
||||
{% if periods|length > 0 %}
|
||||
<p>
|
||||
<i class="fa fa-calendar"></i>
|
||||
<a href="{{ route('transactions.index.all', [transactionType]) }}">{{ 'show_all_no_filter'|_ }}</a>
|
||||
@ -47,7 +47,7 @@
|
||||
</div>
|
||||
|
||||
{# boxes with info #}
|
||||
{% if periods.count > 0 %}
|
||||
{% if periods|length > 0 %}
|
||||
<div class="col-lg-2 col-md-2 col-sm-12 col-xs-12">
|
||||
{% include 'list.periods' %}
|
||||
</div>
|
||||
@ -56,7 +56,7 @@
|
||||
</div>
|
||||
|
||||
{# lower show-all instruction #}
|
||||
{% if periods.count > 0 %}
|
||||
{% if periods|length > 0 %}
|
||||
<div class="row">
|
||||
<div class="col-lg-offset-10 col-lg-2 col-md-offset-10 col-md-2 col-sm-12 col-xs-12">
|
||||
<p class="small text-center"><a href="{{ route('transactions.index.all',[transactionType]) }}">{{ 'showEverything'|_ }}</a></p>
|
||||
|
@ -537,6 +537,8 @@ Route::group(
|
||||
Route::get('currencies', ['uses' => 'Json\AutoCompleteController@currencies', 'as' => 'autocomplete.currencies']);
|
||||
Route::get('piggy-banks', ['uses' => 'Json\AutoCompleteController@piggyBanks', 'as' => 'autocomplete.piggy-banks']);
|
||||
Route::get('tags', ['uses' => 'Json\AutoCompleteController@tags', 'as' => 'autocomplete.tags']);
|
||||
Route::get('transaction-journals/all', ['uses' => 'Json\AutoCompleteController@allJournals', 'as' => 'autocomplete.all-journals']);
|
||||
Route::get('currency-names', ['uses' => 'Json\AutoCompleteController@currencyNames', 'as' => 'autocomplete.currency-names']);
|
||||
|
||||
|
||||
|
||||
|
@ -133,6 +133,8 @@ class BudgetReportControllerTest extends TestCase
|
||||
$limit3->budget_id = $budget->id;
|
||||
$limit3->start_date = new Carbon('2012-01-01');
|
||||
$limit3->end_date = new Carbon('2012-01-31');
|
||||
$limit3->amount = '100';
|
||||
$limit3->save();
|
||||
|
||||
|
||||
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
|
@ -24,8 +24,9 @@ declare(strict_types=1);
|
||||
namespace Tests\Feature\Controllers\Recurring;
|
||||
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
@ -33,14 +34,18 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Validation\AccountValidator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Mockery;
|
||||
use Preferences;
|
||||
use Steam;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class CreateControllerTest
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
|
||||
*/
|
||||
class CreateControllerTest extends TestCase
|
||||
{
|
||||
@ -58,76 +63,100 @@ class CreateControllerTest extends TestCase
|
||||
*/
|
||||
public function testCreate(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
// mock repositories, even if not used.
|
||||
$this->mock(RecurringRepositoryInterface::class);
|
||||
$this->mock(CurrencyRepositoryInterface::class);
|
||||
$this->mock(PiggyBankRepositoryInterface::class);
|
||||
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
|
||||
$euro = $this->getEuro();
|
||||
$asset = $this->getRandomAsset();
|
||||
$cash = $this->getRandomAsset();
|
||||
$this->mockDefaultSession();
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
|
||||
$budgetRepos->shouldReceive('getActiveBudgets')->andReturn(new Collection)->once();
|
||||
\Amount::shouldReceive('getDefaultCurrency')->andReturn(TransactionCurrency::find(1));
|
||||
|
||||
|
||||
// for view:
|
||||
$accountRepos->shouldReceive('getActiveAccountsByType')->atLeast()->once()->andReturn(new Collection([$asset]));
|
||||
Steam::shouldReceive('balance')->andReturn('100')->atLeast()->once();
|
||||
$accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro);
|
||||
$accountRepos->shouldReceive('getMetaValue')->atLeast()->once()->andReturnNull();
|
||||
$accountRepos->shouldReceive('getCashAccount')->atLeast()->once()->andReturn($cash);
|
||||
//Amount::shouldReceive('getDefaultCurrency')->andReturn($euro)->atLeast()->once();
|
||||
Amount::shouldReceive('formatAnything')->atLeast()->once()->andReturn('100');
|
||||
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('recurring.create'));
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee('<ol class="breadcrumb">');
|
||||
$response->assertSee('source_id_holder');
|
||||
$response->assertSee('deposit_source_id');
|
||||
$response->assertSee('withdrawal_destination_id');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a withdrawal. From Asset account to Expense account
|
||||
*
|
||||
* @covers \FireflyIII\Http\Controllers\Recurring\CreateController
|
||||
* @covers \FireflyIII\Http\Requests\RecurrenceFormRequest
|
||||
*/
|
||||
public function testStore(): void
|
||||
public function testStoreWithdrawalExpense(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
// mock repositories, even if not used.
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$categoryRepos = $this->mock(CategoryRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$source = $this->getRandomAsset();
|
||||
$destination = $this->getRandomExpense();
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
$data = [
|
||||
'title' => 'hello' . $this->randomInt(),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'daily',
|
||||
'skip' => 0,
|
||||
'recurring_description' => 'Some descr' . $this->randomInt(),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['withdrawal'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
|
||||
|
||||
$data = [
|
||||
'title' => sprintf('hello %d', $this->randomInt()),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'daily',
|
||||
'skip' => 0,
|
||||
'recurring_description' => sprintf('Some descr %d', $this->randomInt()),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
|
||||
// mandatory for transaction:
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
|
||||
// mandatory account info:
|
||||
'source_id' => '1',
|
||||
'destination_name' => 'Some Expense',
|
||||
'source_id' => $source->id,
|
||||
'withdrawal_destination_id' => $destination->id,
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
];
|
||||
|
||||
$recurringRepos->shouldReceive('store')->andReturn($recurrence)->once();
|
||||
@ -139,23 +168,89 @@ class CreateControllerTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a withdrawal. But throw error.
|
||||
*
|
||||
* @covers \FireflyIII\Http\Controllers\Recurring\CreateController
|
||||
* @covers \FireflyIII\Http\Requests\RecurrenceFormRequest
|
||||
*/
|
||||
public function testStoreDeposit(): void
|
||||
public function testStoreError(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
// mock repositories, even if not used.
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$categoryRepos = $this->mock(CategoryRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$source = $this->getRandomAsset();
|
||||
$destination = $this->getRandomExpense();
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['withdrawal'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
|
||||
$data = [
|
||||
'title' => sprintf('hello %d', $this->randomInt()),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'daily',
|
||||
'skip' => 0,
|
||||
'recurring_description' => sprintf('Some descr %d', $this->randomInt()),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
|
||||
// mandatory for transaction:
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
|
||||
// mandatory account info:
|
||||
'source_id' => $source->id,
|
||||
'withdrawal_destination_id' => $destination->id,
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
];
|
||||
|
||||
$recurringRepos->shouldReceive('store')->andThrow(new FireflyException('Some exception'));
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->post(route('recurring.store'), $data);
|
||||
$response->assertStatus(302);
|
||||
$response->assertSessionHas('error', 'Some exception');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a deposit from Revenue to Asset.
|
||||
*
|
||||
* @covers \FireflyIII\Http\Controllers\Recurring\CreateController
|
||||
* @covers \FireflyIII\Http\Requests\RecurrenceFormRequest
|
||||
*/
|
||||
public function testStoreDepositRevenue(): void
|
||||
{
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$source = $this->getRandomRevenue();
|
||||
$destination = $this->getRandomAsset();
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['deposit'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
@ -177,10 +272,8 @@ class CreateControllerTest extends TestCase
|
||||
'amount' => '30',
|
||||
|
||||
// mandatory account info:
|
||||
'source_id' => '2',
|
||||
'source_name' => 'Some source',
|
||||
'destination_id' => '1',
|
||||
'destination_name' => 'Some Expense',
|
||||
'deposit_source_id' => $source->id,
|
||||
'destination_id' => $destination->id,
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
@ -200,53 +293,58 @@ class CreateControllerTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a withdrawal but it's monthly, not daily.
|
||||
*
|
||||
* @covers \FireflyIII\Http\Controllers\Recurring\CreateController
|
||||
* @covers \FireflyIII\Http\Requests\RecurrenceFormRequest
|
||||
*/
|
||||
public function testStoreMonthly(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$categoryRepos = $this->mock(CategoryRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$source = $this->getRandomAsset();
|
||||
$destination = $this->getRandomExpense();
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
$data = [
|
||||
'title' => 'hello' . $this->randomInt(),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'monthly,5',
|
||||
'skip' => 0,
|
||||
'recurring_description' => 'Some descr' . $this->randomInt(),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['withdrawal'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
|
||||
$data = [
|
||||
'title' => sprintf('hello %d', $this->randomInt()),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'monthly,5',
|
||||
'skip' => 0,
|
||||
'recurring_description' => sprintf('Some descr %d', $this->randomInt()),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
|
||||
// mandatory for transaction:
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
|
||||
// mandatory account info:
|
||||
'source_id' => '1',
|
||||
'destination_name' => 'Some Expense',
|
||||
'source_id' => $source->id,
|
||||
'withdrawal_destination_id' => $destination->id,
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
];
|
||||
|
||||
$recurringRepos->shouldReceive('store')->andReturn($recurrence)->once();
|
||||
@ -258,53 +356,58 @@ class CreateControllerTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a withdrawal but use ndom.
|
||||
*
|
||||
* @covers \FireflyIII\Http\Controllers\Recurring\CreateController
|
||||
* @covers \FireflyIII\Http\Requests\RecurrenceFormRequest
|
||||
*/
|
||||
public function testStoreNdom(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$categoryRepos = $this->mock(CategoryRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$source = $this->getRandomAsset();
|
||||
$destination = $this->getRandomExpense();
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
$data = [
|
||||
'title' => 'hello' . $this->randomInt(),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'ndom,3,5',
|
||||
'skip' => 0,
|
||||
'recurring_description' => 'Some descr' . $this->randomInt(),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['withdrawal'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
|
||||
$data = [
|
||||
'title' => sprintf('hello %d', $this->randomInt()),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'ndom,3,5',
|
||||
'skip' => 0,
|
||||
'recurring_description' => sprintf('Some descr %d', $this->randomInt()),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
|
||||
// mandatory for transaction:
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
|
||||
// mandatory account info:
|
||||
'source_id' => '1',
|
||||
'destination_name' => 'Some Expense',
|
||||
'source_id' => $source->id,
|
||||
'withdrawal_destination_id' => $destination->id,
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
];
|
||||
|
||||
$recurringRepos->shouldReceive('store')->andReturn($recurrence)->once();
|
||||
@ -321,17 +424,20 @@ class CreateControllerTest extends TestCase
|
||||
*/
|
||||
public function testStoreTransfer(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$categoryRepos = $this->mock(CategoryRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$source = $this->getRandomAsset();
|
||||
$destination = $this->getRandomAsset($source->id);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['transfer'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
|
||||
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
@ -354,10 +460,8 @@ class CreateControllerTest extends TestCase
|
||||
'amount' => '30',
|
||||
|
||||
// mandatory account info:
|
||||
'source_id' => '2',
|
||||
'source_name' => 'Some source',
|
||||
'destination_id' => '1',
|
||||
'destination_name' => 'Some Expense',
|
||||
'source_id' => $source->id,
|
||||
'destination_id' => $destination->id,
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
@ -382,49 +486,51 @@ class CreateControllerTest extends TestCase
|
||||
*/
|
||||
public function testStoreUntilDate(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$categoryRepos = $this->mock(CategoryRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$source = $this->getRandomAsset();
|
||||
$destination = $this->getRandomExpense();
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['withdrawal'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
$data = [
|
||||
'title' => 'hello' . $this->randomInt(),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'daily',
|
||||
'skip' => 0,
|
||||
'recurring_description' => 'Some descr' . $this->randomInt(),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
'title' => sprintf('hello %d', $this->randomInt()),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'daily',
|
||||
'skip' => 0,
|
||||
'recurring_description' => sprintf('Some descr %d', $this->randomInt()),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
|
||||
// mandatory for transaction:
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
|
||||
// mandatory account info:
|
||||
'source_id' => '1',
|
||||
'destination_name' => 'Some Expense',
|
||||
'source_id' => $source->id,
|
||||
'withdrawal_destination_id' => $destination->id,
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'until_date',
|
||||
'repeat_until' => $tomorrow->format('Y-m-d'),
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'until_date',
|
||||
'repeat_until' => $tomorrow->format('Y-m-d'),
|
||||
];
|
||||
|
||||
$recurringRepos->shouldReceive('store')->andReturn($recurrence)->once();
|
||||
@ -441,48 +547,51 @@ class CreateControllerTest extends TestCase
|
||||
*/
|
||||
public function testStoreYearly(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$categoryRepos = $this->mock(CategoryRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$source = $this->getRandomAsset();
|
||||
$destination = $this->getRandomExpense();
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
$data = [
|
||||
'title' => 'hello' . $this->randomInt(),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'yearly,2018-01-01',
|
||||
'skip' => 0,
|
||||
'recurring_description' => 'Some descr' . $this->randomInt(),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['withdrawal'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
|
||||
$data = [
|
||||
'title' => sprintf('hello %d', $this->randomInt()),
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'yearly,2018-01-01',
|
||||
'skip' => 0,
|
||||
'recurring_description' => sprintf('Some descr %d', $this->randomInt()),
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'foreign_amount' => '1',
|
||||
'foreign_currency_id' => '2',
|
||||
|
||||
// mandatory for transaction:
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
|
||||
// mandatory account info:
|
||||
'source_id' => '1',
|
||||
'destination_name' => 'Some Expense',
|
||||
'source_id' => $source->id,
|
||||
'withdrawal_destination_id' => $destination->id,
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
];
|
||||
|
||||
$recurringRepos->shouldReceive('store')->andReturn($recurrence)->once();
|
||||
|
@ -28,6 +28,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Mockery;
|
||||
use Preferences;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
@ -53,7 +54,9 @@ class DeleteControllerTest extends TestCase
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
|
||||
$recurringRepos->shouldReceive('getTransactions')->andReturn(new Collection())->once();
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$recurringRepos->shouldReceive('getTransactions')->andReturn(new Collection)->once();
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
|
||||
$this->be($this->user());
|
||||
@ -70,6 +73,9 @@ class DeleteControllerTest extends TestCase
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
$recurringRepos->shouldReceive('destroy')->once();
|
||||
|
||||
|
||||
|
@ -23,19 +23,21 @@ declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature\Controllers\Recurring;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Factory\CategoryFactory;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use FireflyIII\Transformers\RecurrenceTransformer;
|
||||
use FireflyIII\Validation\AccountValidator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Mockery;
|
||||
use Preferences;
|
||||
use Steam;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
@ -58,23 +60,44 @@ class EditControllerTest extends TestCase
|
||||
*/
|
||||
public function testEdit(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
$this->mock(CurrencyRepositoryInterface::class);
|
||||
$this->mock(PiggyBankRepositoryInterface::class);
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$categoryFactory = $this->mock(CategoryFactory::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$transformer = $this->mock(RecurrenceTransformer::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$transformer = $this->mock(RecurrenceTransformer::class);
|
||||
$asset = $this->getRandomAsset();
|
||||
$euro = $this->getEuro();
|
||||
$cash = $this->getRandomAsset();
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$transformed = [
|
||||
'transactions' => [
|
||||
[
|
||||
'source_id' => 1,
|
||||
'destination_id' => 1,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// for view:
|
||||
$accountRepos->shouldReceive('getActiveAccountsByType')->atLeast()->once()->andReturn(new Collection([$asset]));
|
||||
Steam::shouldReceive('balance')->andReturn('100')->atLeast()->once();
|
||||
$accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro);
|
||||
$accountRepos->shouldReceive('getMetaValue')->atLeast()->once()->andReturnNull();
|
||||
$accountRepos->shouldReceive('getCashAccount')->atLeast()->once()->andReturn($cash);
|
||||
//Amount::shouldReceive('getDefaultCurrency')->andReturn($euro)->atLeast()->once();
|
||||
Amount::shouldReceive('formatAnything')->atLeast()->once()->andReturn('100');
|
||||
|
||||
// transform recurrence.
|
||||
$transformer->shouldReceive('setParameters')->atLeast()->once();
|
||||
$transformer->shouldReceive('transform')->atLeast()->once();
|
||||
$transformer->shouldReceive('transform')->atLeast()->once()->andReturn($transformed);
|
||||
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
|
||||
// get stuff from recurrence.
|
||||
$recurringRepos->shouldReceive('setUser');
|
||||
$recurringRepos->shouldReceive('getNoteText')->andReturn('Note!');
|
||||
$recurringRepos->shouldReceive('repetitionDescription')->andReturn('dunno');
|
||||
@ -90,6 +113,8 @@ class EditControllerTest extends TestCase
|
||||
$response = $this->get(route('recurring.edit', [1]));
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee('<ol class="breadcrumb">');
|
||||
$response->assertSee('deposit_source_id');
|
||||
$response->assertSee('withdrawal_destination_id');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,51 +123,52 @@ class EditControllerTest extends TestCase
|
||||
*/
|
||||
public function testUpdate(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
$this->mock(BudgetRepositoryInterface::class);
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$validator = $this->mock(AccountValidator::class);
|
||||
$expense = $this->getRandomExpense();
|
||||
|
||||
return;
|
||||
$recurringRepos = $this->mock(RecurringRepositoryInterface::class);
|
||||
$budgetRepos = $this->mock(BudgetRepositoryInterface::class);
|
||||
$categoryRepos = $this->mock(CategoryRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$categoryFactory = $this->mock(CategoryFactory::class);
|
||||
$piggyRepos = $this->mock(PiggyBankRepositoryInterface::class);
|
||||
$transformer = $this->mock(RecurrenceTransformer::class);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$recurringRepos->shouldReceive('update')->once();
|
||||
|
||||
// validator:
|
||||
$validator->shouldReceive('setTransactionType')->withArgs(['withdrawal'])->atLeast()->once();
|
||||
$validator->shouldReceive('validateSource')->atLeast()->once()->andReturn(true);
|
||||
$validator->shouldReceive('validateDestination')->atLeast()->once()->andReturn(true);
|
||||
Preferences::shouldReceive('mark')->once();
|
||||
|
||||
$tomorrow = Carbon::now()->addDays(2);
|
||||
$recurrence = $this->user()->recurrences()->first();
|
||||
$data = [
|
||||
'id' => $recurrence->id,
|
||||
'title' => 'hello',
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'daily',
|
||||
'skip' => 0,
|
||||
'recurring_description' => 'Some descr',
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'return_to_edit' => '1',
|
||||
'id' => $recurrence->id,
|
||||
'title' => 'hello',
|
||||
'first_date' => $tomorrow->format('Y-m-d'),
|
||||
'repetition_type' => 'daily',
|
||||
'skip' => 0,
|
||||
'recurring_description' => 'Some descr',
|
||||
'active' => '1',
|
||||
'apply_rules' => '1',
|
||||
'return_to_edit' => '1',
|
||||
// mandatory for transaction:
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
'transaction_description' => 'Some descr',
|
||||
'transaction_type' => 'withdrawal',
|
||||
'transaction_currency_id' => '1',
|
||||
'amount' => '30',
|
||||
// mandatory account info:
|
||||
'source_id' => '1',
|
||||
'source_name' => '',
|
||||
'destination_id' => '',
|
||||
'destination_name' => 'Some Expense',
|
||||
'source_id' => '1',
|
||||
'source_name' => '',
|
||||
'withdrawal_destination_id' => $expense->id,
|
||||
'destination_id' => '',
|
||||
'destination_name' => 'Some Expense',
|
||||
|
||||
// optional fields:
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
'budget_id' => '1',
|
||||
'category' => 'CategoryA',
|
||||
'tags' => 'A,B,C',
|
||||
'create_another' => '1',
|
||||
'repetition_end' => 'times',
|
||||
'repetitions' => 3,
|
||||
];
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace Tests\Feature\Controllers\Recurring;
|
||||
|
||||
use FireflyIII\Factory\CategoryFactory;
|
||||
use FireflyIII\Models\Configuration;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
@ -32,6 +33,7 @@ use FireflyIII\Transformers\RecurrenceTransformer;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Mockery;
|
||||
use Preferences;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
@ -61,6 +63,13 @@ class IndexControllerTest extends TestCase
|
||||
$categoryFactory = $this->mock(CategoryFactory::class);
|
||||
$transformer = $this->mock(RecurrenceTransformer::class);
|
||||
|
||||
// mock calls
|
||||
$pref = new Preference;
|
||||
$pref->data = 50;
|
||||
Preferences::shouldReceive('get')->withArgs(['listPageSize', 50])->atLeast()->once()->andReturn($pref);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$transformer->shouldReceive('setParameters')->atLeast()->once();
|
||||
$transformer->shouldReceive('transform')->atLeast()->once()->andReturn(
|
||||
[
|
||||
@ -83,7 +92,6 @@ class IndexControllerTest extends TestCase
|
||||
|
||||
// mock cron job config:
|
||||
\FireflyConfig::shouldReceive('get')->withArgs(['last_rt_job', 0])->once()->andReturn($config);
|
||||
\FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->once()->andReturn($falseConfig);
|
||||
|
||||
$repository->shouldReceive('get')->andReturn($collection)->once();
|
||||
|
||||
@ -94,6 +102,9 @@ class IndexControllerTest extends TestCase
|
||||
$response->assertSee('<ol class="breadcrumb">');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \FireflyIII\Http\Controllers\Recurring\IndexController
|
||||
*/
|
||||
public function testShow(): void
|
||||
{
|
||||
$repository = $this->mock(RecurringRepositoryInterface::class);
|
||||
@ -102,6 +113,8 @@ class IndexControllerTest extends TestCase
|
||||
$categoryFactory = $this->mock(CategoryFactory::class);
|
||||
$transformer = $this->mock(RecurrenceTransformer::class);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$transformer->shouldReceive('setParameters')->atLeast()->once();
|
||||
$transformer->shouldReceive('transform')->atLeast()->once()->andReturn(
|
||||
[
|
||||
@ -109,7 +122,13 @@ class IndexControllerTest extends TestCase
|
||||
'first_date' => '2018-01-01',
|
||||
'repeat_until' => null,
|
||||
'latest_date' => null,
|
||||
'recurrence_repetitions' => [],
|
||||
'recurrence_repetitions' => [
|
||||
[
|
||||
'occurrences' => [
|
||||
'2019-01-01'
|
||||
]
|
||||
]
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -22,14 +22,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature\Controllers\Report;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
|
||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||
use FireflyIII\Helpers\Fiscal\FiscalHelperInterface;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Preferences;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
@ -56,46 +56,30 @@ class ExpenseControllerTest extends TestCase
|
||||
*/
|
||||
public function testBudget(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
|
||||
return;
|
||||
$expense = $this->user()->accounts()->where('account_type_id', 4)->first();
|
||||
$revenue = $this->user()->accounts()->where('account_type_id', 5)->first();
|
||||
$repository = $this->mock(AccountRepositoryInterface::class);
|
||||
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
|
||||
$collector = $this->mock(GroupCollectorInterface::class);
|
||||
$expense = $this->getRandomExpense();
|
||||
$revenue = $this->getRandomRevenue();
|
||||
$date = new Carbon;
|
||||
$transactions = [$this->getRandomWithdrawalAsArray()];
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('lastActivity')->atLeast()->once();
|
||||
|
||||
|
||||
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue);
|
||||
Amount::shouldReceive('formatAnything')->atLeast()->once()->andReturn('-100');
|
||||
|
||||
// fake collection:
|
||||
$transA = new Transaction;
|
||||
$transA->transaction_currency_id = 1;
|
||||
$transA->transaction_budget_name = 'Budget';
|
||||
$transA->transaction_budget_id = 1;
|
||||
$transA->transaction_currency_symbol = 'A';
|
||||
$transA->transaction_currency_dp = 2;
|
||||
$transA->transaction_amount = '100';
|
||||
$transB = new Transaction;
|
||||
$transB->transaction_currency_id = 2;
|
||||
$transB->transaction_budget_name = null;
|
||||
$transB->transaction_budget_id = 0;
|
||||
$transB->transaction_journal_budget_name = 'Budget2';
|
||||
$transB->transaction_journal_budget_id = 2;
|
||||
$transB->transaction_currency_symbol = 'A';
|
||||
$transB->transaction_currency_dp = 2;
|
||||
$transB->transaction_amount = '100';
|
||||
$collection = new Collection([$transA, $transB]);
|
||||
|
||||
// mock collector for spentByBudget (complex)
|
||||
$collector = $this->mock(TransactionCollectorInterface::class);
|
||||
// dont care about any calls, just return a default set of fake transactions:
|
||||
$collector->shouldReceive('setRange')->andReturnSelf();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('setOpposingAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('withBudgetInformation')->andReturnSelf();
|
||||
$collector->shouldReceive('getTransactions')->andReturn($collection);
|
||||
$collector->shouldReceive('setRange')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('withBudgetInformation')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('getExtractedJournals')->andReturn($transactions)->atLeast()->once();
|
||||
|
||||
|
||||
$this->be($this->user());
|
||||
@ -108,57 +92,37 @@ class ExpenseControllerTest extends TestCase
|
||||
*/
|
||||
public function testCategory(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
|
||||
return;
|
||||
$expense = $this->user()->accounts()->where('account_type_id', 4)->first();
|
||||
$revenue = $this->user()->accounts()->where('account_type_id', 5)->first();
|
||||
$repository = $this->mock(AccountRepositoryInterface::class);
|
||||
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
|
||||
$collector = $this->mock(GroupCollectorInterface::class);
|
||||
$expense = $this->getRandomExpense();
|
||||
$revenue = $this->getRandomRevenue();
|
||||
$date = new Carbon;
|
||||
$one = $this->getRandomWithdrawalAsArray();
|
||||
$two = $this->getRandomWithdrawalAsArray();
|
||||
|
||||
// two categories
|
||||
$oneCat = $this->getRandomCategory();
|
||||
$twoCat = $this->user()->categories()->where('id', '!=', $oneCat->id)->inRandomOrder()->first();
|
||||
|
||||
$one['category_id'] = $oneCat->id;
|
||||
$one['category_name'] = $oneCat->name;
|
||||
$two['category_id'] = $twoCat->id;
|
||||
$two['category_name'] = $twoCat->name;
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('lastActivity')->atLeast()->once();
|
||||
|
||||
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue);
|
||||
Amount::shouldReceive('formatAnything')->atLeast()->once()->andReturn('-100');
|
||||
|
||||
// fake collection:
|
||||
$transA = new Transaction;
|
||||
$transA->transaction_currency_id = 1;
|
||||
$transA->transaction_category_name = 'Category';
|
||||
$transA->transaction_category_id = 1;
|
||||
$transA->transaction_currency_symbol = 'A';
|
||||
$transA->transaction_currency_dp = 2;
|
||||
$transA->transaction_amount = '100';
|
||||
$transB = new Transaction;
|
||||
$transB->transaction_currency_id = 2;
|
||||
$transB->transaction_category_name = null;
|
||||
$transB->transaction_category_id = 0;
|
||||
$transB->transaction_journal_category_name = 'Category2';
|
||||
$transB->transaction_journal_category_id = 2;
|
||||
$transB->transaction_currency_symbol = 'A';
|
||||
$transB->transaction_currency_dp = 2;
|
||||
$transB->transaction_amount = '100';
|
||||
$collection = new Collection([$transA, $transB]);
|
||||
$transC = new Transaction;
|
||||
$transC->transaction_currency_id = 3;
|
||||
$transC->transaction_category_name = null;
|
||||
$transC->transaction_category_id = 0;
|
||||
$transC->transaction_journal_category_name = 'Category3';
|
||||
$transC->transaction_journal_category_id = 3;
|
||||
$transC->transaction_currency_symbol = 'A';
|
||||
$transC->transaction_currency_dp = 2;
|
||||
$transC->transaction_amount = '100';
|
||||
$secondCollection = new Collection([$transC]);
|
||||
|
||||
// mock collector for spentByCategory and earnedByCategory (complex)
|
||||
$collector = $this->mock(TransactionCollectorInterface::class);
|
||||
// dont care about any calls, just return a default set of fake transactions:
|
||||
$collector->shouldReceive('setRange')->andReturnSelf();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('setOpposingAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('withCategoryInformation')->andReturnSelf();
|
||||
$collector->shouldReceive('getTransactions')->andReturn($collection, $secondCollection);
|
||||
//$collector->shouldReceive('')->andReturnSelf();
|
||||
$collector->shouldReceive('setRange')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('withCategoryInformation')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('getExtractedJournals')->andReturn([$one], [$two])->atLeast()->once();
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('report-data.expense.category', ['1', $expense->id, '20170101', '20170131']));
|
||||
@ -170,45 +134,27 @@ class ExpenseControllerTest extends TestCase
|
||||
*/
|
||||
public function testSpent(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
|
||||
return;
|
||||
$expense = $this->user()->accounts()->where('account_type_id', 4)->first();
|
||||
$revenue = $this->user()->accounts()->where('account_type_id', 5)->first();
|
||||
$repository = $this->mock(AccountRepositoryInterface::class);
|
||||
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
|
||||
$collector = $this->mock(GroupCollectorInterface::class);
|
||||
|
||||
$expense = $this->getRandomExpense();
|
||||
$revenue = $this->getRandomRevenue();
|
||||
$date = new Carbon;
|
||||
$transactions = [$this->getRandomWithdrawalAsArray()];
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('lastActivity')->atLeast()->once();
|
||||
|
||||
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue);
|
||||
|
||||
// fake collection:
|
||||
$transA = new Transaction;
|
||||
$transA->transaction_currency_id = 1;
|
||||
$transA->transaction_category_name = 'Category';
|
||||
$transA->transaction_category_id = 1;
|
||||
$transA->transaction_currency_symbol = 'A';
|
||||
$transA->transaction_currency_dp = 2;
|
||||
$transA->transaction_amount = '100';
|
||||
$transB = new Transaction;
|
||||
$transB->transaction_currency_id = 2;
|
||||
$transB->transaction_category_name = null;
|
||||
$transB->transaction_category_id = 0;
|
||||
$transB->transaction_journal_budget_name = 'Category2';
|
||||
$transB->transaction_journal_budget_id = 2;
|
||||
$transB->transaction_currency_symbol = 'A';
|
||||
$transB->transaction_currency_dp = 2;
|
||||
$transB->transaction_amount = '100';
|
||||
$collection = new Collection([$transA, $transB]);
|
||||
|
||||
// mock collector for spentInPeriod and earnedInPeriod (complex)
|
||||
$collector = $this->mock(TransactionCollectorInterface::class);
|
||||
// dont care about any calls, just return a default set of fake transactions:
|
||||
$collector->shouldReceive('setRange')->andReturnSelf();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('setOpposingAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('getTransactions')->andReturn($collection);
|
||||
$collector->shouldReceive('setRange')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('getExtractedJournals')->andReturn($transactions)->atLeast()->once();
|
||||
Amount::shouldReceive('formatAnything')->atLeast()->once()->andReturn('-100');
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('report-data.expense.spent', ['1', $expense->id, '20170101', '20170131']));
|
||||
@ -220,47 +166,29 @@ class ExpenseControllerTest extends TestCase
|
||||
*/
|
||||
public function testTopExpense(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
|
||||
return;
|
||||
$expense = $this->user()->accounts()->where('account_type_id', 4)->first();
|
||||
$revenue = $this->user()->accounts()->where('account_type_id', 5)->first();
|
||||
Log::debug(sprintf('Now in test %s', __METHOD__));
|
||||
$repository = $this->mock(AccountRepositoryInterface::class);
|
||||
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
|
||||
$collector = $this->mock(GroupCollectorInterface::class);
|
||||
|
||||
$expense = $this->getRandomExpense();
|
||||
$revenue = $this->getRandomRevenue();
|
||||
$date = new Carbon;
|
||||
$transactions = [$this->getRandomWithdrawalAsArray()];
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('lastActivity')->atLeast()->once();
|
||||
|
||||
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue);
|
||||
|
||||
// fake collection:
|
||||
$transA = new Transaction;
|
||||
$transA->transaction_currency_id = 1;
|
||||
$transA->transaction_category_name = 'Category';
|
||||
$transA->transaction_category_id = 1;
|
||||
$transA->transaction_currency_symbol = 'A';
|
||||
$transA->transaction_currency_dp = 2;
|
||||
$transA->transaction_amount = '100';
|
||||
$transA->opposing_account_id = $expense->id;
|
||||
$transB = new Transaction;
|
||||
$transB->transaction_currency_id = 2;
|
||||
$transB->transaction_category_name = null;
|
||||
$transB->transaction_category_id = 0;
|
||||
$transB->transaction_journal_budget_name = 'Category2';
|
||||
$transB->transaction_journal_budget_id = 2;
|
||||
$transB->transaction_currency_symbol = 'A';
|
||||
$transB->transaction_currency_dp = 2;
|
||||
$transB->transaction_amount = '100';
|
||||
$transB->opposing_account_id = $expense->id;
|
||||
$collection = new Collection([$transA, $transB]);
|
||||
$collector->shouldReceive('setRange')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('withAccountInformation')->andReturnSelf()->atLeast()->once();
|
||||
|
||||
// mock collector for topExpense (complex)
|
||||
$collector = $this->mock(TransactionCollectorInterface::class);
|
||||
// dont care about any calls, just return a default set of fake transactions:
|
||||
$collector->shouldReceive('setRange')->andReturnSelf();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('setOpposingAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('getTransactions')->andReturn($collection);
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('getExtractedJournals')->andReturn($transactions)->atLeast()->once();
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('report-data.expense.expenses', ['1', $expense->id, '20170101', '20170131']));
|
||||
@ -272,46 +200,28 @@ class ExpenseControllerTest extends TestCase
|
||||
*/
|
||||
public function testTopIncome(): void
|
||||
{
|
||||
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
|
||||
|
||||
return;
|
||||
$expense = $this->user()->accounts()->where('account_type_id', 4)->first();
|
||||
$revenue = $this->user()->accounts()->where('account_type_id', 5)->first();
|
||||
Log::debug(sprintf('Now in test %s', __METHOD__));
|
||||
$repository = $this->mock(AccountRepositoryInterface::class);
|
||||
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
|
||||
$collector = $this->mock(GroupCollectorInterface::class);
|
||||
|
||||
$expense = $this->getRandomExpense();
|
||||
$revenue = $this->getRandomRevenue();
|
||||
$date = new Carbon;
|
||||
$transactions = [$this->getRandomWithdrawalAsArray()];
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('lastActivity')->atLeast()->once();
|
||||
|
||||
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
|
||||
$repository->shouldReceive('findByName')->once()->withArgs([$expense->name, [AccountType::REVENUE]])->andReturn($revenue);
|
||||
|
||||
// fake collection:
|
||||
$transA = new Transaction;
|
||||
$transA->transaction_currency_id = 1;
|
||||
$transA->transaction_category_name = 'Category';
|
||||
$transA->transaction_category_id = 1;
|
||||
$transA->transaction_currency_symbol = 'A';
|
||||
$transA->transaction_currency_dp = 2;
|
||||
$transA->transaction_amount = '100';
|
||||
$transA->opposing_account_id = $expense->id;
|
||||
$transB = new Transaction;
|
||||
$transB->transaction_currency_id = 2;
|
||||
$transB->transaction_category_name = null;
|
||||
$transB->transaction_category_id = 0;
|
||||
$transB->transaction_journal_budget_name = 'Category2';
|
||||
$transB->transaction_journal_budget_id = 2;
|
||||
$transB->transaction_currency_symbol = 'A';
|
||||
$transB->transaction_currency_dp = 2;
|
||||
$transB->transaction_amount = '100';
|
||||
$transB->opposing_account_id = $expense->id;
|
||||
$collection = new Collection([$transA, $transB]);
|
||||
|
||||
$collector = $this->mock(TransactionCollectorInterface::class);
|
||||
$collector->shouldReceive('setRange')->andReturnSelf();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('setOpposingAccounts')->andReturnSelf();
|
||||
$collector->shouldReceive('getTransactions')->andReturn($collection);
|
||||
//$collector->shouldReceive('')->andReturnSelf();
|
||||
$collector->shouldReceive('setRange')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setTypes')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('setAccounts')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('withAccountInformation')->andReturnSelf()->atLeast()->once();
|
||||
$collector->shouldReceive('getExtractedJournals')->andReturn($transactions)->atLeast()->once();
|
||||
|
||||
|
||||
$this->be($this->user());
|
||||
|
@ -33,6 +33,7 @@ use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Log;
|
||||
use Mockery;
|
||||
use Preferences;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
@ -56,12 +57,13 @@ class CreateControllerTest extends TestCase
|
||||
public function testCreate(): void
|
||||
{
|
||||
// mock stuff
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$billRepos = $this->mock(BillRepositoryInterface::class);
|
||||
$ruleRepos = $this->mock(RuleRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
$this->mockIntroPreference('shown_demo_rules_create');
|
||||
|
||||
$ruleGroupRepos->shouldReceive('count')->atLeast()->once()->andReturn(1);
|
||||
$ruleRepos->shouldReceive('count')->atLeast()->once()->andReturn(1);
|
||||
@ -80,17 +82,17 @@ class CreateControllerTest extends TestCase
|
||||
public function testCreateFromBill(): void
|
||||
{
|
||||
// mock stuff
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$billRepos = $this->mock(BillRepositoryInterface::class);
|
||||
$ruleRepos = $this->mock(RuleRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$ruleGroupRepos->shouldReceive('count')->atLeast()->once()->andReturn(1);
|
||||
$ruleRepos->shouldReceive('count')->atLeast()->once()->andReturn(1);
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('rules.create-from-bill', [1, 1]));
|
||||
@ -114,17 +116,17 @@ class CreateControllerTest extends TestCase
|
||||
$this->session(['_old_input' => $old]);
|
||||
|
||||
// mock stuff
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$ruleRepos = $this->mock(RuleRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
$this->mockIntroPreference('shown_demo_rules_create');
|
||||
|
||||
$ruleGroupRepos->shouldReceive('count')->atLeast()->once()->andReturn(1);
|
||||
$ruleRepos->shouldReceive('count')->atLeast()->once()->andReturn(1);
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('rules.create', [1]));
|
||||
$response->assertStatus(200);
|
||||
@ -139,12 +141,13 @@ class CreateControllerTest extends TestCase
|
||||
{
|
||||
// mock stuff
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
$repository->shouldReceive('store')->andReturn(new Rule);
|
||||
|
||||
$this->session(['rules.create.uri' => 'http://localhost']);
|
||||
|
@ -30,6 +30,7 @@ use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
|
||||
use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Log;
|
||||
use Mockery;
|
||||
use Preferences;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
@ -54,13 +55,14 @@ class DeleteControllerTest extends TestCase
|
||||
public function testDelete(): void
|
||||
{
|
||||
// mock stuff
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$ruleRepos = $this->mock(RuleRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('rules.delete', [1]));
|
||||
@ -75,10 +77,11 @@ class DeleteControllerTest extends TestCase
|
||||
{
|
||||
// mock stuff
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
$repository->shouldReceive('destroy');
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
$this->session(['rules.delete.uri' => 'http://localhost']);
|
||||
$this->be($this->user());
|
||||
$response = $this->post(route('rules.destroy', [1]));
|
||||
|
@ -33,6 +33,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Mockery;
|
||||
use Preferences;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
@ -57,12 +58,11 @@ class EditControllerTest extends TestCase
|
||||
// mock stuff
|
||||
$groupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
$repository->shouldReceive('getPrimaryTrigger')->andReturn(new Rule);
|
||||
$groupRepos->shouldReceive('get')->andReturn(new Collection);
|
||||
|
||||
@ -90,11 +90,11 @@ class EditControllerTest extends TestCase
|
||||
// mock stuff
|
||||
$groupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
$repository->shouldReceive('getPrimaryTrigger')->andReturn(new Rule);
|
||||
$groupRepos->shouldReceive('get')->andReturn(new Collection);
|
||||
|
||||
@ -112,11 +112,12 @@ class EditControllerTest extends TestCase
|
||||
{
|
||||
// mock stuff
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
|
||||
$rule = Rule::find(1);
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
|
||||
$this->mockDefaultSession();
|
||||
Preferences::shouldReceive('mark')->atLeast()->once();
|
||||
|
||||
$repository->shouldReceive('update');
|
||||
|
||||
$data = [
|
||||
|
@ -59,11 +59,11 @@ class IndexControllerTest extends TestCase
|
||||
{
|
||||
// mock stuff
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
|
||||
$repository->shouldReceive('moveDown');
|
||||
$this->mockDefaultSession();
|
||||
|
||||
|
||||
$this->be($this->user());
|
||||
@ -81,11 +81,12 @@ class IndexControllerTest extends TestCase
|
||||
// mock stuff
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$this->mockDefaultSession();
|
||||
$this->mockIntroPreference('shown_demo_rules_index');
|
||||
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
|
||||
$ruleGroupRepos->shouldReceive('count')->andReturn(0);
|
||||
$ruleGroupRepos->shouldReceive('store');
|
||||
$repository->shouldReceive('getFirstRuleGroup')->andReturn(new RuleGroup);
|
||||
@ -106,11 +107,10 @@ class IndexControllerTest extends TestCase
|
||||
{
|
||||
// mock stuff
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
|
||||
$data = ['actions' => [1, 2, 3]];
|
||||
$repository->shouldReceive('reorderRuleActions')->once();
|
||||
@ -127,11 +127,10 @@ class IndexControllerTest extends TestCase
|
||||
{
|
||||
// mock stuff
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
$data = ['triggers' => [1, 2, 3]];
|
||||
$repository->shouldReceive('reorderRuleTriggers')->once();
|
||||
|
||||
@ -148,12 +147,11 @@ class IndexControllerTest extends TestCase
|
||||
{
|
||||
// mock stuff
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$ruleGroupRepos = $this->mock(RuleGroupRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
$repository->shouldReceive('moveUp');
|
||||
|
||||
$this->be($this->user());
|
||||
|
@ -63,6 +63,7 @@ class SelectControllerTest extends TestCase
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$repository = $this->mock(RuleRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$this->session(['first' => new Carbon('2010-01-01')]);
|
||||
$accountRepos->shouldReceive('getAccountsById')->andReturn(new Collection([$account]));
|
||||
@ -81,7 +82,7 @@ class SelectControllerTest extends TestCase
|
||||
|
||||
Queue::assertPushed(
|
||||
ExecuteRuleOnExistingTransactions::class, function (Job $job) {
|
||||
return $job->getRule()->id === 1;
|
||||
return 1=== $job->getRule()->id;
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -93,6 +94,7 @@ class SelectControllerTest extends TestCase
|
||||
{
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->atLeast()->once()->andReturn(true);
|
||||
$accountRepos->shouldReceive('getAccountsByType')->andReturn(new Collection);
|
||||
@ -119,11 +121,9 @@ class SelectControllerTest extends TestCase
|
||||
|
||||
// mock stuff
|
||||
$matcher = $this->mock(TransactionMatcher::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$matcher->shouldReceive('setStrict')->once()->withArgs([false])->andReturnSelf();
|
||||
$matcher->shouldReceive('setTriggeredLimit')->withArgs([10])->andReturnSelf()->once();
|
||||
@ -144,11 +144,12 @@ class SelectControllerTest extends TestCase
|
||||
{
|
||||
$matcher = $this->mock(TransactionMatcher::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$matcher->shouldReceive('setTriggeredLimit')->withArgs([10])->andReturnSelf()->once();
|
||||
$matcher->shouldReceive('setSearchLimit')->withArgs([200])->andReturnSelf()->once();
|
||||
$matcher->shouldReceive('setRule')->andReturnSelf()->once();
|
||||
$matcher->shouldReceive('findTransactionsByRule')->andReturn(new Collection);
|
||||
$matcher->shouldReceive('findTransactionsByRule')->andReturn([]);
|
||||
|
||||
$this->be($this->user());
|
||||
$response = $this->get(route('rules.test-triggers-rule', [1]));
|
||||
@ -163,11 +164,9 @@ class SelectControllerTest extends TestCase
|
||||
*/
|
||||
public function testTestTriggersError(): void
|
||||
{
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$userRepos = $this->mock(UserRepositoryInterface::class);
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
|
||||
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
|
||||
$this->mockDefaultSession();
|
||||
|
||||
$this->be($this->user());
|
||||
$uri = route('rules.test-triggers');
|
||||
|
@ -30,7 +30,6 @@ use DB;
|
||||
use Exception;
|
||||
use FireflyConfig;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Budget;
|
||||
@ -167,7 +166,9 @@ abstract class TestCase extends BaseTestCase
|
||||
'currency_decimal_places' => $euro->decimal_places,
|
||||
'amount' => '-30',
|
||||
'budget_id' => $budget->id,
|
||||
'budget_name' => $budget->name,
|
||||
'category_id' => $category->id,
|
||||
'category_name' => $category->name,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -491,25 +491,35 @@ class TransferCurrenciesCorrectionsTest extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic test. Source transaction has bad currency.
|
||||
* Basic test. Source transaction has bad currency, and this must be fixed.
|
||||
*
|
||||
* TODO something in this test is too random, and it fails. Not sure why.
|
||||
*
|
||||
* @covers \FireflyIII\Console\Commands\Upgrade\TransferCurrenciesCorrections
|
||||
*/
|
||||
public function testHandleTransferBadDestCurrency(): void
|
||||
{
|
||||
|
||||
Log::warning(sprintf('Now in test %s.', __METHOD__));
|
||||
$accountRepos = $this->mock(AccountRepositoryInterface::class);
|
||||
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
|
||||
$journalRepos = $this->mock(JournalRepositoryInterface::class);
|
||||
$transfer = $this->getRandomTransfer();
|
||||
$euro = $this->getEuro();
|
||||
|
||||
$dollar = $this->getDollar();
|
||||
// get destination transaction and remove currency:
|
||||
$transfer->transaction_currency_id = $euro->id;
|
||||
$transfer->save();
|
||||
|
||||
Log::debug(sprintf('Gave transfer #%d currency EUR', $transfer->id));
|
||||
|
||||
|
||||
/** @var Transaction $destination */
|
||||
$destination = $transfer->transactions()->where('amount', '>', 0)->first();
|
||||
$destination->transaction_currency_id = 2;
|
||||
$destination->transaction_currency_id = $dollar->id;
|
||||
$destination->save();
|
||||
|
||||
Log::debug(sprintf('Gave transaction #%d currency USD', $destination->id));
|
||||
|
||||
// mock calls:
|
||||
$journalRepos->shouldReceive('getAllJournals')
|
||||
->withArgs([[TransactionType::TRANSFER]])
|
||||
@ -518,12 +528,10 @@ class TransferCurrenciesCorrectionsTest extends TestCase
|
||||
// account repos
|
||||
$accountRepos->shouldReceive('getMetaValue')
|
||||
->atLeast()->once()
|
||||
->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
|
||||
->withArgs([Mockery::any(), 'currency_id'])->andReturn((string)$euro->id);
|
||||
|
||||
// currency repos
|
||||
$currencyRepos->shouldReceive('findNull')
|
||||
->atLeast()->once()
|
||||
->withArgs([1])->andReturn($euro);
|
||||
$currencyRepos->shouldReceive('findNull')->atLeast()->once()->withArgs([$euro->id])->andReturn($euro);
|
||||
|
||||
// configuration
|
||||
$false = new Configuration;
|
||||
@ -536,7 +544,7 @@ class TransferCurrenciesCorrectionsTest extends TestCase
|
||||
->assertExitCode(0);
|
||||
|
||||
// assume problem is fixed:
|
||||
$this->assertCount(1, Transaction::where('id', $destination->id)->where('transaction_currency_id', 1)->get());
|
||||
$this->assertCount(1, Transaction::where('id', $destination->id)->where('transaction_currency_id', $euro->id)->get());
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,7 @@ namespace Tests\Unit\Factory;
|
||||
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Factory\AccountFactory;
|
||||
use FireflyIII\Factory\BudgetFactory;
|
||||
use FireflyIII\Factory\CategoryFactory;
|
||||
@ -831,8 +832,13 @@ class RecurrenceFactoryTest extends TestCase
|
||||
/** @var RecurrenceFactory $factory */
|
||||
$factory = app(RecurrenceFactory::class);
|
||||
$factory->setUser($this->user());
|
||||
|
||||
$result = $factory->create($data);
|
||||
$result = null;
|
||||
try {
|
||||
$result = $factory->create($data);
|
||||
} catch (FireflyException $e) {
|
||||
$this->assertEquals('Cannot make a recurring transaction of type "bad type"', $e->getMessage());
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user