Finalise account tests

This commit is contained in:
James Cole 2019-06-23 05:53:01 +02:00
parent 311659ba0d
commit 9f50c5db3d
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
25 changed files with 470 additions and 841 deletions

View File

@ -61,6 +61,7 @@ class RenameAccountMeta extends Command
$array = [
'accountRole' => 'account_role',
'ccType' => 'cc_type',
'accountNumber' => 'account_number',
'ccMonthlyPaymentDate' => 'cc_monthly_payment_date',
];
$count = 0;
@ -71,6 +72,9 @@ class RenameAccountMeta extends Command
*/
foreach ($array as $old => $new) {
$count += AccountMeta::where('name', $old)->update(['name' => $new]);
// delete empty entries while we're at it.
AccountMeta::where('name', $new)->where('data','""')->delete();
}
$this->markAsExecuted();

View File

@ -55,6 +55,7 @@ class UpgradeDatabase extends Command
$commands = [
// there are 12 upgrade commands.
'firefly-iii:transaction-identifiers',
'firefly-iii:migrate-to-groups',
'firefly-iii:account-currencies',
'firefly-iii:transfer-currencies',
'firefly-iii:other-currencies',
@ -63,7 +64,6 @@ class UpgradeDatabase extends Command
'firefly-iii:bills-to-rules',
'firefly-iii:bl-currency',
'firefly-iii:cc-liabilities',
'firefly-iii:migrate-to-groups',
'firefly-iii:back-to-journals',
'firefly-iii:rename-account-meta'
];

View File

@ -100,17 +100,12 @@ class EditController extends Controller
$openingBalanceAmount = (string)$repository->getOpeningBalanceAmount($account);
$openingBalanceDate = $repository->getOpeningBalanceDate($account);
$default = app('amount')->getDefaultCurrency();
$currency = $this->currencyRepos->findNull((int)$repository->getMetaValue($account, 'currency_id'));
$currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
// include this account in net-worth charts?
$includeNetWorth = $repository->getMetaValue($account, 'include_net_worth');
$includeNetWorth = null === $includeNetWorth ? true : '1' === $includeNetWorth;
if (null === $currency) {
$currency = $default;
}
// code to handle active-checkboxes
$hasOldInput = null !== $request->old('_token');
$preFilled = [

View File

@ -25,15 +25,18 @@ namespace FireflyIII\Http\Controllers\Account;
use Carbon\Carbon;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\TransactionGroupFactory;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\ReconciliationStoreRequest;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Controllers\UserNavigation;
use FireflyIII\User;
use Log;
/**
@ -83,13 +86,12 @@ class ReconcileController extends Controller
*/
public function reconcile(Account $account, Carbon $start = null, Carbon $end = null)
{
if (AccountType::INITIAL_BALANCE === $account->accountType->type) {
return $this->redirectToOriginalAccount($account);
}
if (AccountType::ASSET !== $account->accountType->type) {
// @codeCoverageIgnoreStart
session()->flash('error', (string)trans('firefly.must_be_asset_account'));
return redirect(route('accounts.index', [config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type))]));
// @codeCoverageIgnoreEnd
}
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
@ -97,16 +99,20 @@ class ReconcileController extends Controller
$range = app('preferences')->get('viewRange', '1M')->data;
// get start and end
// @codeCoverageIgnoreStart
if (null === $start && null === $end) {
/** @var Carbon $start */
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
/** @var Carbon $end */
$end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range));
}
if (null === $end) {
/** @var Carbon $end */
$end = app('navigation')->endOfPeriod($start, $range);
}
// @codeCoverageIgnoreEnd
$startDate = clone $start;
$startDate->subDay();
@ -142,70 +148,78 @@ class ReconcileController extends Controller
Log::debug('In ReconcileController::submit()');
$data = $request->getAll();
/** @var Transaction $transaction */
foreach ($data['transactions'] as $transactionId) {
$this->repository->reconcileById((int)$transactionId);
/** @var string $journalId */
foreach ($data['journals'] as $journalId) {
$this->repository->reconcileById((int)$journalId);
}
Log::debug('Reconciled all transactions.');
// create reconciliation transaction (if necessary):
$result = '';
if ('create' === $data['reconcile']) {
// get "opposing" account.
$reconciliation = $this->accountRepos->getReconciliation($account);
$difference = $data['difference'];
$source = $reconciliation;
$destination = $account;
if (1 === bccomp($difference, '0')) {
// amount is positive. Add it to reconciliation?
$source = $account;
$destination = $reconciliation;
}
// data for journal
$description = trans(
'firefly.reconcilliation_transaction_title',
['from' => $start->formatLocalized($this->monthAndDayFormat), 'to' => $end->formatLocalized($this->monthAndDayFormat)]
);
$journalData = [
'type' => 'Reconciliation',
'description' => $description,
'user' => auth()->user()->id,
'date' => $data['end'],
'bill_id' => null,
'bill_name' => null,
'piggy_bank_id' => null,
'piggy_bank_name' => null,
'tags' => null,
'interest_date' => null,
'transactions' => [[
'currency_id' => (int)$this->accountRepos->getMetaValue($account, 'currency_id'),
'currency_code' => null,
'description' => null,
'amount' => app('steam')->positive($difference),
'source_id' => $source->id,
'source_name' => null,
'destination_id' => $destination->id,
'destination_name' => null,
'reconciled' => true,
'identifier' => 0,
'foreign_currency_id' => null,
'foreign_currency_code' => null,
'foreign_amount' => null,
'budget_id' => null,
'budget_name' => null,
'category_id' => null,
'category_name' => null,
],
],
'notes' => implode(', ', $data['transactions']),
];
$this->repository->store($journalData);
$result = $this->createReconciliation($account, $start, $end, $data['difference']);
}
Log::debug('End of routine.');
app('preferences')->mark();
session()->flash('success', (string)trans('firefly.reconciliation_stored'));
if ('' === $result) {
session()->flash('success', (string)trans('firefly.reconciliation_stored'));
}
if ('' !== $result) {
session()->flash('error', (string)trans('firefly.reconciliation_error', ['error' => $result]));
}
return redirect(route('accounts.show', [$account->id]));
}
/**
* Creates a reconciliation group.
* @return string
*/
private function createReconciliation(Account $account, Carbon $start, Carbon $end, string $difference): string
{
$reconciliation = $this->accountRepos->getReconciliation($account);
$currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
$source = $reconciliation;
$destination = $account;
if (1 === bccomp($difference, '0')) {
$source = $account;
$destination = $reconciliation;
}
// title:
$description = trans('firefly.reconciliation_transaction_title',
['from' => $start->formatLocalized($this->monthAndDayFormat), 'to' => $end->formatLocalized($this->monthAndDayFormat)]);
$submission = [
'user' => auth()->user()->id,
'group_title' => null,
'transactions' => [
[
'user' => auth()->user()->id,
'type' => strtolower(TransactionType::RECONCILIATION),
'date' => $end,
'order' => 0,
'currency_id' => $currency->id,
'foreign_currency_id' => null,
'amount' => $difference,
'foreign_amount' => null,
'description' => $description,
'source_id' => $source->id,
'destination_id' => $destination->id,
'reconciled' => true,
],
],
];
/** @var TransactionGroupFactory $factory */
$factory = app(TransactionGroupFactory::class);
/** @var User $user */
$user = auth()->user();
$factory->setUser($user);
try {
$factory->create($submission);
} catch (FireflyException $e) {
return $e->getMessage();
}
return '';
}
}

View File

@ -36,6 +36,7 @@ use FireflyIII\Support\Http\Controllers\UserNavigation;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use View;
use Exception;
/**
* Class ShowController
@ -53,6 +54,7 @@ class ShowController extends Controller
/**
* ShowController constructor.
* @codeCoverageIgnore
*/
public function __construct()
{
@ -82,43 +84,34 @@ class ShowController extends Controller
* @param Carbon|null $end
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
*
* @throws FireflyException
*
* @throws Exception
*/
public function show(Request $request, Account $account, Carbon $start = null, Carbon $end = null)
{
if (AccountType::INITIAL_BALANCE === $account->accountType->type) {
return $this->redirectToOriginalAccount($account);
}
// a basic thing to determin if this account is a liability:
if ($this->repository->isLiability($account)) {
return redirect(route('accounts.show.all', [$account->id]));
if (in_array($account->accountType->type, [AccountType::INITIAL_BALANCE, AccountType::RECONCILIATION], true)) {
return $this->redirectToOriginalAccount($account); // @codeCoverageIgnore
}
/** @var Carbon $start */
$start = $start ?? session('start');
/** @var Carbon $end */
$end = $end ?? session('end');
if ($end < $start) {
throw new FireflyException('End is after start!'); // @codeCoverageIgnore
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
}
$what = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type)); // used for menu
$objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
$today = new Carbon;
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
$currencyId = (int)$this->repository->getMetaValue($account, 'currency_id');
$currency = $this->currencyRepos->findNull($currencyId);
if (0 === $currencyId) {
$currency = app('amount')->getDefaultCurrency(); // @codeCoverageIgnore
}
$fStart = $start->formatLocalized($this->monthAndDayFormat);
$fEnd = $end->formatLocalized($this->monthAndDayFormat);
$subTitle = (string)trans('firefly.journals_in_period_for_account', ['name' => $account->name, 'start' => $fStart, 'end' => $fEnd]);
$chartUri = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
$periods = $this->getAccountPeriodOverview($account, $end);
$currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
$fStart = $start->formatLocalized($this->monthAndDayFormat);
$fEnd = $end->formatLocalized($this->monthAndDayFormat);
$subTitle = (string)trans('firefly.journals_in_period_for_account', ['name' => $account->name, 'start' => $fStart, 'end' => $fEnd]);
$chartUri = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
$periods = $this->getAccountPeriodOverview($account, $end);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
@ -134,7 +127,7 @@ class ShowController extends Controller
return view(
'accounts.show',
compact(
'account', 'showAll', 'what', 'currency', 'today', 'periods', 'subTitleIcon', 'groups', 'subTitle', 'start', 'end',
'account', 'showAll', 'objectType', 'currency', 'today', 'periods', 'subTitleIcon', 'groups', 'subTitle', 'start', 'end',
'chartUri'
)
);
@ -145,7 +138,7 @@ class ShowController extends Controller
*
* @param Request $request
* @param Account $account
*
* @throws Exception
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
*
*
@ -156,19 +149,16 @@ class ShowController extends Controller
return $this->redirectToOriginalAccount($account); // @codeCoverageIgnore
}
$isLiability = $this->repository->isLiability($account);
$objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
$end = new Carbon;
$today = new Carbon;
$start = $this->repository->oldestJournalDate($account) ?? Carbon::now()->startOfMonth();
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type);
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
$currencyId = (int)$this->repository->getMetaValue($account, 'currency_id');
$currency = $this->currencyRepos->findNull($currencyId);
if (0 === $currencyId) {
$currency = app('amount')->getDefaultCurrency(); // @codeCoverageIgnore
}
$subTitle = (string)trans('firefly.all_journals_for_account', ['name' => $account->name]);
$periods = new Collection;
$currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
$subTitle = (string)trans('firefly.all_journals_for_account', ['name' => $account->name]);
$periods = new Collection;
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page)->withAccountInformation();
@ -179,7 +169,8 @@ class ShowController extends Controller
return view(
'accounts.show',
compact('account', 'showAll', 'isLiability', 'currency', 'today', 'chartUri', 'periods', 'subTitleIcon', 'groups', 'subTitle', 'start', 'end')
compact('account', 'showAll', 'objectType', 'isLiability', 'currency', 'today',
'chartUri', 'periods', 'subTitleIcon', 'groups', 'subTitle', 'start', 'end')
);
}

View File

@ -139,7 +139,7 @@ class ReconcileController extends Controller
'accounts.reconcile.overview', compact(
'account', 'start', 'diffCompare', 'difference', 'end', 'clearedAmount',
'startBalance', 'endBalance', 'amount',
'route', 'countCleared', 'reconSum'
'route', 'countCleared', 'reconSum', 'selectedIds'
)
)->render();
// @codeCoverageIgnoreStart

View File

@ -65,29 +65,6 @@ class TransactionController extends Controller
);
}
/**
* Do a reconciliation.
*
* @param Request $request
*
* @return JsonResponse
*/
public function reconcile(Request $request): JsonResponse
{
$transactionIds = $request->get('transactions');
foreach ($transactionIds as $transactionId) {
$transactionId = (int)$transactionId;
$transaction = $this->repository->findTransaction($transactionId);
if (null !== $transaction) {
Log::debug(sprintf('Transaction ID is %d', $transaction->id));
$this->repository->reconcile($transaction);
}
}
return response()->json(['ok' => 'reconciled']);
}
/**
* Reorder transactions.
*

View File

@ -23,7 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Rules\ValidTransactions;
use FireflyIII\Rules\ValidJournals;
use Log;
/**
@ -59,7 +59,7 @@ class ReconciliationStoreRequest extends Request
'start_balance' => $this->string('startBalance'),
'end_balance' => $this->string('endBalance'),
'difference' => $this->string('difference'),
'journals' => $transactions,
'journals' => $transactions,
'reconcile' => $this->string('reconcile'),
];
Log::debug('In ReconciliationStoreRequest::getAll(). Will now return data.');
@ -80,7 +80,7 @@ class ReconciliationStoreRequest extends Request
'startBalance' => 'numeric',
'endBalance' => 'numeric',
'difference' => 'required|numeric',
'journals' => [new ValidJournals],
'journals' => [new ValidJournals],
'reconcile' => 'required|in:create,nothing',
];
}

View File

@ -230,6 +230,7 @@ class AccountRepository implements AccountRepositoryInterface
if (count($accountIds) > 0) {
$query->whereIn('accounts.id', $accountIds);
}
$query->orderBy('accounts.active', 'DESC');
$query->orderBy('accounts.name', 'ASC');
$result = $query->get(['accounts.*']);
@ -249,6 +250,7 @@ class AccountRepository implements AccountRepositoryInterface
if (count($types) > 0) {
$query->accountTypeIn($types);
}
$query->orderBy('accounts.active', 'DESC');
$query->orderBy('accounts.name', 'ASC');
$result = $query->get(['accounts.*']);

View File

@ -688,18 +688,14 @@ class JournalRepository implements JournalRepositoryInterface
/**
* @param int $transactionId
*
* @return bool
*/
public function reconcileById(int $transactionId): bool
public function reconcileById(int $journalId): void
{
/** @var Transaction $transaction */
$transaction = $this->user->transactions()->find($transactionId);
if (null !== $transaction) {
return $this->reconcile($transaction);
/** @var TransactionJournal $journal */
$journal = $this->user->transactionJournals()->find($journalId);
if (null !== $journal) {
$journal->transactions()->update(['reconciled' => true]);
}
return false;
}
/**

View File

@ -309,11 +309,9 @@ interface JournalRepositoryInterface
public function reconcile(Transaction $transaction): bool;
/**
* @param int $transactionId
*
* @return bool
* @param int $journalId
*/
public function reconcileById(int $transactionId): bool;
public function reconcileById(int $journalId): void;
/**
* @param TransactionJournal $journal

View File

@ -87,7 +87,7 @@ class AmountFormat extends Twig_Extension
static function (AccountModel $account, string $amount, bool $coloured = null): string {
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
Log::warning('AmountFormat::formatAmountByAccount should NOT be called in the TEST environment!');
}
$coloured = $coloured ?? true;

View File

@ -153,10 +153,6 @@ class General extends Twig_Extension
/** @var Carbon $date */
$date = session('end', Carbon::now()->endOfMonth());
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
}
return app('steam')->balance($account, $date);
}
);
@ -213,7 +209,7 @@ class General extends Twig_Extension
'accountGetMetaField',
static function (Account $account, string $field): string {
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
Log::warning('Twig General::getMetaField should NOT be called in the TEST environment!');
}
/** @var AccountRepositoryInterface $repository */
@ -238,9 +234,6 @@ class General extends Twig_Extension
return new Twig_SimpleFunction(
'hasRole',
static function (string $role): bool {
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
}
$repository = app(UserRepositoryInterface::class);
if ($repository->hasRole(auth()->user(), $role)) {
return true;
@ -258,7 +251,7 @@ class General extends Twig_Extension
{
return new Twig_SimpleFilter(
'markdown',
function (string $text): string {
static function (string $text): string {
$converter = new CommonMarkConverter;
return $converter->convertToHtml($text);
@ -275,7 +268,7 @@ class General extends Twig_Extension
{
return new Twig_SimpleFilter(
'mimeIcon',
function (string $string): string {
static function (string $string): string {
switch ($string) {
default:
return 'fa-file-o';
@ -354,7 +347,7 @@ class General extends Twig_Extension
{
return new Twig_SimpleFunction(
'phpdate',
function (string $str): string {
static function (string $str): string {
return date($str);
}
);

View File

@ -96,7 +96,7 @@ class TransactionGroupTwig extends Twig_Extension
'journalGetMetaDate',
static function (int $journalId, string $metaField) {
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
Log::warning('Twig TransactionGroup::journalGetMetaDate should NOT be called in the TEST environment!');
}
$entry = DB::table('journal_meta')
->where('name', $metaField)
@ -121,7 +121,7 @@ class TransactionGroupTwig extends Twig_Extension
'journalGetMetaField',
static function (int $journalId, string $metaField) {
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
Log::warning('Twig TransactionGroup::journalGetMetaField should NOT be called in the TEST environment!');
}
$entry = DB::table('journal_meta')
->where('name', $metaField)
@ -146,7 +146,7 @@ class TransactionGroupTwig extends Twig_Extension
'journalHasMeta',
static function (int $journalId, string $metaField) {
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should NOT be called in the TEST environment!', __METHOD__));
Log::warning('Twig TransactionGroup::journalHasMeta should NOT be called in the TEST environment!');
}
$count = DB::table('journal_meta')
->where('name', $metaField)

View File

@ -124,6 +124,9 @@ class AccountValidator
case TransactionType::OPENING_BALANCE:
$result = $this->validateOBDestination($destinationId, $destinationName);
break;
case TransactionType::RECONCILIATION:
$result = $this->validateReconciliationDestination($destinationId);
break;
//case TransactionType::OPENING_BALANCE:
//case TransactionType::RECONCILIATION:
// die(sprintf('Cannot handle type "%s"', $this->transactionType));
@ -159,6 +162,9 @@ class AccountValidator
case TransactionType::OPENING_BALANCE:
$result = $this->validateOBSource($accountId, $accountName);
break;
case TransactionType::RECONCILIATION:
$result = $this->validateReconciliationSource($accountId);
break;
//case TransactionType::OPENING_BALANCE:
//case TransactionType::RECONCILIATION:
// die(sprintf('Cannot handle type "%s"', $this->transactionType));
@ -582,5 +588,51 @@ class AccountValidator
return true;
}
/**
* @param int|null $accountId
* @return bool
*/
private function validateReconciliationSource(?int $accountId): bool
{
if (null === $accountId) {
return false;
}
$result = $this->accountRepository->findNull($accountId);
$types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE, AccountType::RECONCILIATION];
if (null === $result) {
return false;
}
if (in_array($result->accountType->type, $types, true)) {
$this->source = $result;
return true;
}
return false;
}
/**
* @param int|null $accountId
* @return bool
*/
private function validateReconciliationDestination(?int $accountId): bool
{
if (null === $accountId) {
return false;
}
$result = $this->accountRepository->findNull($accountId);
$types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE, AccountType::RECONCILIATION];
if (null === $result) {
return false;
}
if (in_array($result->accountType->type, $types, true)) {
$this->destination = $result;
return true;
}
return false;
}
}

View File

@ -780,7 +780,9 @@ return [
'reconcile_go_back' => 'You can always edit or delete a correction later.',
'must_be_asset_account' => 'You can only reconcile asset accounts',
'reconciliation_stored' => 'Reconciliation stored',
'reconcilliation_transaction_title' => 'Reconciliation (:from to :to)',
'reconciliation_error' => 'Due to an error the transactions were marked as reconciled but the correction has not been stored: :error.',
'reconciliation_transaction_title' => 'Reconciliation (:from to :to)',
'sum_of_reconciliation' => 'Sum of reconciliation',
'reconcile_this_account' => 'Reconcile this account',
'confirm_reconciliation' => 'Confirm reconciliation',
'submitted_start_balance' => 'Submitted start balance',
@ -1381,13 +1383,13 @@ return [
'recurrence_deleted' => 'Recurring transaction ":title" deleted',
// new lines for summary controller.
'box_balance_in_currency' => 'Balance (:currency)',
'box_spent_in_currency' => 'Spent (:currency)',
'box_earned_in_currency' => 'Earned (:currency)',
'box_bill_paid_in_currency' => 'Bills paid (:currency)',
'box_bill_unpaid_in_currency' => 'Bills unpaid (:currency)',
'box_left_to_spend_in_currency' => 'Left to spend (:currency)',
'box_net_worth_in_currency' => 'Net worth (:currency)',
'box_spend_per_day' => 'Left to spend per day: :amount',
'box_balance_in_currency' => 'Balance (:currency)',
'box_spent_in_currency' => 'Spent (:currency)',
'box_earned_in_currency' => 'Earned (:currency)',
'box_bill_paid_in_currency' => 'Bills paid (:currency)',
'box_bill_unpaid_in_currency' => 'Bills unpaid (:currency)',
'box_left_to_spend_in_currency' => 'Left to spend (:currency)',
'box_net_worth_in_currency' => 'Net worth (:currency)',
'box_spend_per_day' => 'Left to spend per day: :amount',
];

View File

@ -15,8 +15,8 @@
<input type="hidden" name="end" value="{{ end.format('Y-m-d') }}"/>
<input type="hidden" name="startBalance" value="{{ startBalance }}"/>
<input type="hidden" name="endBalance" value="{{ endBalance }}"/>
{% for id in transactionIds %}
<input type="hidden" name="transactions[]" value="{{ id }}"/>
{% for id in selectedIds %}
<input type="hidden" name="journals[]" value="{{ id }}"/>
{% endfor %}
<table class="table table-striped table-bordered">
@ -25,7 +25,7 @@
<td>{{ formatAmountByAccount(account, startBalance) }}</td>
</tr>
<tr>
<td>{{ trans('firefly.selected_transactions', {count: transactionIds|length}) }}</td>
<td>{{ trans('firefly.selected_transactions', {count: selectedIds|length}) }}</td>
<td>{{ formatAmountByAccount(account, amount) }}</td>
</tr>
<tr>

View File

@ -102,7 +102,6 @@
</td>
<td>
{% if journal.date >= start and journal.date <= end %}
{% if journal.reconciled %}
<i class="fa fa-check" aria-hidden="true"></i>

View File

@ -13,76 +13,19 @@ TODO: hide and show columns
<tbody>
{% for group in groups %}
{% if group.count > 1 %}
<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>
</strong></small>
</td>
<td colspan="2" style="border-top:1px #aaa solid;">
{% for sum in group.sums %}
{{ formatAmountBySymbol(sum.amount, sum.currency_symbol, sum.currency_symbol_decimal_places) }}{% if loop.index != group.sums|length %},{% endif %}
{% endfor %}
</td>
<td colspan="2" style="border-top:1px #aaa solid;">&nbsp;</td>
<td style="border-top:1px #aaa solid;">
<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>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li><a href="{{ route('transactions.edit', [group.id]) }}"><i class="fa fa-fw fa-pencil"></i> {{ 'edit'|_ }}</a></li>
<li><a href="{{ route('transactions.delete', [group.id]) }}"><i class="fa fa-fw fa-trash"></i> {{ 'delete'|_ }}</a></li>
<li><a href="{{ route('transactions.clone', [group.id]) }}"><i class="fa fa-copy fa-fw"></i> {{ 'clone'|_ }}</a></li>
</ul>
</div>
</td>
</tr>
{% endif %}
{% 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;'" %}
{% endif %}
<tr>
<td {{ style|raw }}>
{% if journal.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' %}
<i class="fa fa-long-arrow-right fa-fw" title="{{ trans('firefly.Deposit') }}"></i>
{% endif %}
{% if journal.transaction_type_type == 'Transfer' %}
<i class="fa fa-exchange fa-fw" title="{{ trans('firefly.Deposit') }}"></i>
{% endif %}
{% if journal.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' %}
<i class="fa-fw fa fa-star-o" title="{{ trans('firefly.Opening balance') }}"></i>
{% endif %}
</td>
<td {{ style|raw }}>
<a href="{{ route('transactions.show', [group.id]) }}" title="{{ transaction.description }}">{{ transaction.description }}</a>
</td>
<td {{ 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 }}>
<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 }}>
<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 }}>
{% if group.count == 1 %}
<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>
</strong></small>
</td>
<td colspan="2" style="border-top:1px #aaa solid;">
{% for sum in group.sums %}
{{ formatAmountBySymbol(sum.amount, sum.currency_symbol, sum.currency_symbol_decimal_places) }}{% if loop.index != group.sums|length %},{% endif %}
{% endfor %}
</td>
<td colspan="2" style="border-top:1px #aaa solid;">&nbsp;</td>
<td style="border-top:1px #aaa solid;">
<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>
@ -92,10 +35,72 @@ TODO: hide and show columns
<li><a href="{{ route('transactions.clone', [group.id]) }}"><i class="fa fa-copy fa-fw"></i> {{ 'clone'|_ }}</a></li>
</ul>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
</td>
</tr>
{% endif %}
{% 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;'" %}
{% endif %}
<tr>
<td {{ style|raw }}>
{% if journal.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' %}
<i class="fa fa-long-arrow-right fa-fw" title="{{ trans('firefly.Deposit') }}"></i>
{% endif %}
{% if journal.transaction_type_type == 'Transfer' %}
<i class="fa fa-exchange fa-fw" title="{{ trans('firefly.Deposit') }}"></i>
{% endif %}
{% if journal.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' %}
<i class="fa-fw fa fa-star-o" title="{{ trans('firefly.Opening balance') }}"></i>
{% endif %}
</td>
<td {{ 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 }}>
{{ 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 }}>
<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 }}>
<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 }}>
{% 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">
{{ 'actions'|_ }} <span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li><a href="{{ route('transactions.edit', [group.id]) }}"><i class="fa fa-fw fa-pencil"></i> {{ 'edit'|_ }}</a></li>
<li><a href="{{ route('transactions.delete', [group.id]) }}"><i class="fa fa-fw fa-trash"></i> {{ 'delete'|_ }}</a></li>
<li><a href="{{ route('transactions.clone', [group.id]) }}"><i class="fa fa-copy fa-fw"></i> {{ 'clone'|_ }}</a></li>
</ul>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>

View File

@ -74,17 +74,18 @@ class EditControllerTest extends TestCase
// mock preferences:
$this->mockDefaultPreferences();
$repository->shouldReceive('findNull')->withArgs([1])->andReturn($euro)->atLeast()->once();
//$repository->shouldReceive('findNull')->withArgs([1])->andReturn($euro)->atLeast()->once();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$repository->shouldReceive('get')->andReturn(new Collection)->atLeast()->once();
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$accountRepos->shouldReceive('getAccountCurrency')->andReturn($euro)->once();
$accountRepos->shouldReceive('getNoteText')->andReturn('Some text')->once();
$accountRepos->shouldReceive('getOpeningBalanceAmount')->andReturnNull()->atLeast()->once();
$accountRepos->shouldReceive('getOpeningBalanceDate')->andReturnNull()->atLeast()->once();
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->atLeast()->once();
//$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->atLeast()->once();
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_number'])->andReturn('123')->atLeast()->once();
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_role'])->andReturn('defaultAsset')->atLeast()->once();
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'cc_type'])->andReturn('')->atLeast()->once();
@ -128,13 +129,13 @@ class EditControllerTest extends TestCase
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$repository->shouldReceive('findNull')->once()->andReturn($euro);
//$repository->shouldReceive('findNull')->once()->andReturn($euro);
$repository->shouldReceive('get')->andReturn(new Collection);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$accountRepos->shouldReceive('getNoteText')->andReturn('Some text')->once();
$accountRepos->shouldReceive('getOpeningBalanceAmount')->andReturnNull();
$accountRepos->shouldReceive('getOpeningBalanceDate')->andReturnNull();
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
//$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_number'])->andReturn('123');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_role'])->andReturn('defaultAsset');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'cc_type'])->andReturn('');
@ -143,6 +144,7 @@ class EditControllerTest extends TestCase
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly');
$accountRepos->shouldReceive('getAccountCurrency')->andReturn($euro)->once();
// get all types:
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
@ -179,12 +181,12 @@ class EditControllerTest extends TestCase
$repository = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
$euro = $this->getEuro();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
Amount::shouldReceive('getDefaultCurrency')->andReturn(TransactionCurrency::find(2));
$repository->shouldReceive('findNull')->once()->andReturn(null);
//$repository->shouldReceive('findNull')->once()->andReturn(null);
$repository->shouldReceive('get')->andReturn(new Collection);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$accountRepos->shouldReceive('getNoteText')->andReturn('Some text')->once();
@ -199,6 +201,7 @@ class EditControllerTest extends TestCase
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly');
$accountRepos->shouldReceive('getAccountCurrency')->andReturn($euro)->once();
// mock calls to Preferences:
$this->mockDefaultPreferences();

View File

@ -23,20 +23,21 @@ declare(strict_types=1);
namespace Tests\Feature\Controllers\Account;
use Amount;
use Carbon\Carbon;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\FiscalHelperInterface;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\TransactionGroupFactory;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Fiscal\FiscalHelperInterface;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Support\Collection;
use Log;
use Mockery;
use Preferences;
use Steam;
use Tests\TestCase;
/**
@ -53,64 +54,6 @@ class ReconcileControllerTest extends TestCase
Log::info(sprintf('Now in %s.', get_class($this)));
}
/**
* Test editing a reconciliation.
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testEdit(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$repository = $this->mock(JournalRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$journal = $this->user()->transactionJournals()->where('transaction_type_id', 5)->first();
$transaction = $journal->transactions()->where('amount', '>', 0)->first();
$repository->shouldReceive('firstNull')->andReturn($journal);
$repository->shouldReceive('getFirstPosTransaction')->andReturn($transaction);
$repository->shouldReceive('getJournalDate')->andReturn('2018-01-01');
$repository->shouldReceive('getJournalCategoryName')->andReturn('');
$repository->shouldReceive('getJournalBudgetid')->andReturn(0);
$this->be($this->user());
$response = $this->get(route('accounts.reconcile.edit', [$journal->id]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('<ol class="breadcrumb">');
}
/**
* Test the redirect if journal is not a reconciliation.
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testEditRedirect(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$journal = $this->user()->transactionJournals()->where('transaction_type_id', '!=', 5)->first();
$this->be($this->user());
$response = $this->get(route('accounts.reconcile.edit', [$journal->id]));
$response->assertStatus(302);
$response->assertRedirect(route('transactions.edit', [$journal->id]));
}
/**
* Test showing the reconciliation.
@ -119,241 +62,37 @@ class ReconcileControllerTest extends TestCase
*/
public function testReconcile(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$userRepos = $this->mock(UserRepositoryInterface::class);
$repository = $this->mock(CurrencyRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
$this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$this->mock(GroupCollectorInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$euro = $this->getEuro();
$asset = $this->getRandomAsset();
$date = new Carbon;
// used for session range.
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$userRepos->shouldReceive('hasRole')->atLeast()->once()->withArgs([Mockery::any(), 'owner'])->andReturnTrue();
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
$this->mockDefaultConfiguration();
$this->mockDefaultPreferences();
Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
Steam::shouldReceive('balance')->atLeast()->once()->andReturn('100');
$accountRepos->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro);
$accountRepos->shouldReceive('getMetaValue')
->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->atLeast()->once();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$repository->shouldReceive('findNull')->once()->andReturn(TransactionCurrency::find(1));
$this->be($this->user());
$response = $this->get(route('accounts.reconcile', [1, '20170101', '20170131']));
$response = $this->get(route('accounts.reconcile', [$asset->id, '20170101', '20170131']));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('<ol class="breadcrumb">');
}
/**
* Test showing the reconciliation (its a initial balance).
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testReconcileInitialBalance(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$userRepos = $this->mock(UserRepositoryInterface::class);
$repository = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$date = new Carbon;
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
$transaction = Transaction::leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
->where('accounts.user_id', $this->user()->id)->where('accounts.account_type_id', 6)->first(['account_id']);
$this->be($this->user());
$response = $this->get(route('accounts.reconcile', [$transaction->account_id, '20170101', '20170131']));
$response->assertStatus(302);
}
/**
* Test reconcile view (without date info).
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testReconcileNoDates(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$userRepos = $this->mock(UserRepositoryInterface::class);
$repository = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$accountRepos->shouldReceive('getMetaValue')
->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->atLeast()->once();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$repository->shouldReceive('findNull')->once()->andReturn(TransactionCurrency::find(1));
$this->be($this->user());
$response = $this->get(route('accounts.reconcile', [1]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('<ol class="breadcrumb">');
}
/**
* Test reconcile view (without end date).
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testReconcileNoEndDate(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$userRepos = $this->mock(UserRepositoryInterface::class);
$repository = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$date = new Carbon;
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
$accountRepos->shouldReceive('getMetaValue')
->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->atLeast()->once();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$repository->shouldReceive('findNull')->once()->andReturn(TransactionCurrency::find(1));
$this->be($this->user());
$response = $this->get(route('accounts.reconcile', [1, '20170101']));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('<ol class="breadcrumb">');
}
/**
* Test reconcile view when account is not an asset.
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testReconcileNotAsset(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$date = new Carbon;
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
$account = $this->user()->accounts()->where('account_type_id', '!=', 6)->where('account_type_id', '!=', 3)->first();
$this->be($this->user());
$response = $this->get(route('accounts.reconcile', [$account->id, '20170101', '20170131']));
$response->assertStatus(302);
}
/**
* Test show for actual reconciliation.
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testShow(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$userRepos = $this->mock(UserRepositoryInterface::class);
$repository = $this->mock(JournalRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$accountRepos->shouldReceive('getMetaValue')
->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->atLeast()->once();
$currencyRepos->shouldReceive('findNull')->atLeast()->once()->withArgs([1])->andReturn(TransactionCurrency::find(1));
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$journal = $this->user()->transactionJournals()->where('transaction_type_id', 5)->first();
$repository->shouldReceive('firstNull')->andReturn(new TransactionJournal);
$repository->shouldReceive('getAssetTransaction')->once()->andReturn($journal->transactions()->first());
$this->be($this->user());
$response = $this->get(route('accounts.reconcile.show', [$journal->id]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('<ol class="breadcrumb">');
}
/**
* Test show for actual reconciliation.
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testShowError(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$repository = $this->mock(JournalRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$journal = $this->user()->transactionJournals()->where('transaction_type_id', 5)->first();
$repository->shouldReceive('firstNull')->andReturn(new TransactionJournal);
$repository->shouldReceive('getAssetTransaction')->once()->andReturnNull();
$this->be($this->user());
$response = $this->get(route('accounts.reconcile.show', [$journal->id]));
$response->assertStatus(500);
// has bread crumb
$response->assertSee('The transaction data is incomplete. This is probably a bug. Apologies.');
}
/**
* Test show for actual reconciliation, but its not a reconciliation.
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
*/
public function testShowSomethingElse(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$journal = $this->user()->transactionJournals()->where('transaction_type_id', '!=', 5)->first();
$this->be($this->user());
$response = $this->get(route('accounts.reconcile.show', [$journal->id]));
$response->assertStatus(302);
$response->assertRedirect(route('transactions.show', [$journal->id]));
}
/**
* Submit reconciliation.
*
@ -362,115 +101,97 @@ class ReconcileControllerTest extends TestCase
*/
public function testSubmit(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
$repository = $this->mock(AccountRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$asset = $this->getRandomAsset();
$euro = $this->getEuro();
$date = new Carbon;
$factory = $this->mock(TransactionGroupFactory::class);
$group = $this->getRandomWithdrawalGroup();
$this->mock(CurrencyRepositoryInterface::class);
$this->mock(GroupCollectorInterface::class);
// used for session range.
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
$this->mockDefaultPreferences();
$this->mockDefaultConfiguration();
Preferences::shouldReceive('mark')->atLeast()->once();
return;
$repository = $this->mock(AccountRepositoryInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$date = new Carbon;
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
$journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal);
$journalRepos->shouldReceive('reconcileById')->andReturn(true);
$journalRepos->shouldReceive('store')->andReturn(new TransactionJournal);
$repository->shouldReceive('getReconciliation')->andReturn(new Account);
$repository->shouldReceive('findNull')->andReturn(new Account);
$repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
$journalRepos->shouldReceive('reconcileById')->times(3);
$repository->shouldReceive('getReconciliation')->atLeast()->once()->andReturn($asset);
$repository->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro);
$factory->shouldReceive('setUser')->atLeast()->once();
$factory->shouldReceive('create')->andReturn($group);
$data = [
'transactions' => [1, 2, 3],
'reconcile' => 'create',
'difference' => '5',
'start' => '20170101',
'end' => '20170131',
'journals' => [1, 2, 3],
'reconcile' => 'create',
'difference' => '5',
'start' => '20170101',
'end' => '20170131',
];
$this->be($this->user());
$response = $this->post(route('accounts.reconcile.submit', [1, '20170101', '20170131']), $data);
$response = $this->post(route('accounts.reconcile.submit', [$asset->id, '20170101', '20170131']), $data);
$response->assertStatus(302);
$response->assertSessionHas('success');
}
/**
* Submit reconciliation, but throw an error.
*
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
* @covers \FireflyIII\Http\Requests\ReconciliationUpdateRequest
* @covers \FireflyIII\Http\Requests\ReconciliationStoreRequest
*/
public function testUpdate(): void
public function testSubmitError(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
$repository = $this->mock(AccountRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$asset = $this->getRandomAsset();
$euro = $this->getEuro();
$date = new Carbon;
$factory = $this->mock(TransactionGroupFactory::class);
$group = $this->getRandomWithdrawalGroup();
$this->mock(CurrencyRepositoryInterface::class);
$this->mock(GroupCollectorInterface::class);
return;
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$journalRepos->shouldReceive('firstNull')->andReturn(new TransactionJournal);
$journalRepos->shouldReceive('getJournalSourceAccounts')->andReturn(new Collection([new Account]));
$journalRepos->shouldReceive('getJournalDestinationAccounts')->andReturn(new Collection([new Account]));
$journalRepos->shouldReceive('getNoteText')->andReturn('');
$journalRepos->shouldReceive('update')->once();
// used for session range.
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
$journal = $this->user()->transactionJournals()->where('transaction_type_id', 5)->first();
$data = [
'amount' => '5',
$this->mockDefaultPreferences();
$this->mockDefaultConfiguration();
Preferences::shouldReceive('mark')->atLeast()->once();
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
$journalRepos->shouldReceive('reconcileById')->times(3);
$repository->shouldReceive('getReconciliation')->atLeast()->once()->andReturn($asset);
$repository->shouldReceive('getAccountCurrency')->atLeast()->once()->andReturn($euro);
$factory->shouldReceive('setUser')->atLeast()->once();
$factory->shouldReceive('create')->andThrow(new FireflyException('Some error'));
$data = [
'journals' => [1, 2, 3],
'reconcile' => 'create',
'difference' => '5',
'start' => '20170101',
'end' => '20170131',
];
$this->be($this->user());
$response = $this->post(route('accounts.reconcile.update', [$journal->id]), $data);
$response->assertStatus(302);
}
$response = $this->post(route('accounts.reconcile.submit', [$asset->id, '20170101', '20170131']), $data);
/**
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
* @covers \FireflyIII\Http\Requests\ReconciliationUpdateRequest
*/
public function testUpdateNotReconcile(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$journal = $this->user()->transactionJournals()->where('transaction_type_id', '!=', 5)->first();
$data = ['amount' => '5',];
$this->be($this->user());
$response = $this->post(route('accounts.reconcile.update', [$journal->id]), $data);
$response->assertStatus(302);
$response->assertRedirect(route('transactions.show', [$journal->id]));
}
/**
* @covers \FireflyIII\Http\Controllers\Account\ReconcileController
* @covers \FireflyIII\Http\Requests\ReconciliationUpdateRequest
*/
public function testUpdateZero(): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$collector = $this->mock(TransactionCollectorInterface::class);
$journal = $this->user()->transactionJournals()->where('transaction_type_id', 5)->first();
$data = ['amount' => '0',];
$this->be($this->user());
$response = $this->post(route('accounts.reconcile.update', [$journal->id]), $data);
$response->assertStatus(302);
$response->assertSessionHas('error');
}
}

View File

@ -23,11 +23,10 @@ declare(strict_types=1);
namespace Tests\Feature\Controllers\Account;
use Amount;
use Carbon\Carbon;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\FiscalHelperInterface;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Account\AccountTaskerInterface;
@ -35,9 +34,9 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Log;
use Mockery;
use Preferences;
use Tests\TestCase;
/**
@ -64,9 +63,6 @@ class ShowControllerTest extends TestCase
*/
public function testShow(string $range): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
Log::info(sprintf('testShow(%s)', $range));
$date = new Carbon;
$this->session(['start' => $date, 'end' => clone $date]);
@ -78,36 +74,48 @@ class ShowControllerTest extends TestCase
$userRepos = $this->mock(UserRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$collector = $this->mock(GroupCollectorInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
$journal = $this->getRandomWithdrawalAsArray();
$group = $this->getRandomWithdrawalGroup();
$asset = $this->getRandomAsset();
$euro = $this->getEuro();
// mock stuff
$this->mockDefaultConfiguration();
$this->mockDefaultPreferences();
// amount mocks:
Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
Amount::shouldReceive('formatAnything')->atLeast()->once()->andReturn('-100');
$repository->shouldReceive('getAccountCurrency')->andReturn($euro)->atLeast()->once();
$repository->shouldReceive('oldestJournalDate')->andReturn(clone $date)->once();
// used for session range.
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
// list size
$pref = new Preference;
$pref->data = 50;
Preferences::shouldReceive('get')->withArgs(['listPageSize', 50])->atLeast()->once()->andReturn($pref);
Preferences::shouldReceive('lastActivity')->atLeast()->once();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1));
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$tasker->shouldReceive('amountOutInPeriod')->withAnyArgs()->andReturn('-1');
$tasker->shouldReceive('amountInInPeriod')->withAnyArgs()->andReturn('1');
$repository = $this->mock(AccountRepositoryInterface::class);
$repository->shouldReceive('oldestJournalDate')->andReturn(clone $date)->once();
$repository->shouldReceive('getMetaValue')->andReturn('');
$repository->shouldReceive('isLiability')->andReturn(false);
$transaction = factory(Transaction::class)->make();
$collector = $this->mock(TransactionCollectorInterface::class);
$collector->shouldReceive('setAccounts')->andReturnSelf();
$collector->shouldReceive('setRange')->andReturnSelf();
$collector->shouldReceive('setLimit')->andReturnSelf();
$collector->shouldReceive('withOpposingAccount')->andReturnSelf();
$collector->shouldReceive('setAccounts')->andReturnSelf()->atLeast()->once();
$collector->shouldReceive('setRange')->andReturnSelf()->atLeast()->once();
$collector->shouldReceive('setLimit')->andReturnSelf()->atLeast()->once();
$collector->shouldReceive('setPage')->andReturnSelf();
$collector->shouldReceive('setTypes')->andReturnSelf();
$collector->shouldReceive('getTransactions')->andReturn(new Collection([$transaction]));
$collector->shouldReceive('getPaginatedTransactions')->andReturn(new LengthAwarePaginator([$transaction], 0, 10));
$collector->shouldReceive('setTypes')->andReturnSelf()->atLeast()->once();
$collector->shouldReceive('getExtractedJournals')->andReturn([$journal]);
$collector->shouldReceive('withAccountInformation')->andReturnSelf();
$collector->shouldReceive('getPaginatedGroups')->andReturn(new LengthAwarePaginator([$group], 0, 10));
$this->be($this->user());
$this->changeDateRange($this->user(), $range);
$response = $this->get(route('accounts.show', [1]));
$response = $this->get(route('accounts.show', [$asset->id]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('<ol class="breadcrumb">');
@ -121,212 +129,57 @@ class ShowControllerTest extends TestCase
*/
public function testShowAll(string $range): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
Log::info(sprintf('testShowAll(%s)', $range));
$date = new Carbon;
$this->session(['start' => $date, 'end' => clone $date]);
// mock stuff:
$tasker = $this->mock(AccountTaskerInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$tasker = $this->mock(AccountTaskerInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
$collector = $this->mock(GroupCollectorInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
$journal = $this->getRandomWithdrawalAsArray();
$group = $this->getRandomWithdrawalGroup();
$euro = $this->getEuro();
$asset = $this->getRandomAsset();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
// mock stuff
$this->mockDefaultConfiguration();
$this->mockDefaultPreferences();
$currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1));
// amount mocks:
Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
// Amount::shouldReceive('formatAnything')->atLeast()->once()->andReturn('-100');
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$tasker->shouldReceive('amountOutInPeriod')->withAnyArgs()->andReturn('-1');
$tasker->shouldReceive('amountInInPeriod')->withAnyArgs()->andReturn('1');
$repository = $this->mock(AccountRepositoryInterface::class);
$repository->shouldReceive('isLiability')->andReturn(false)->atLeast()->once();
$repository->shouldReceive('getAccountCurrency')->andReturn($euro)->atLeast()->once();
$repository->shouldReceive('oldestJournalDate')->andReturn(clone $date)->once();
$repository->shouldReceive('getMetaValue')->andReturn('');
$repository->shouldReceive('isLiability')->andReturn(false);
$transaction = factory(Transaction::class)->make();
$collector = $this->mock(TransactionCollectorInterface::class);
$collector->shouldReceive('setAccounts')->andReturnSelf();
$collector->shouldReceive('setRange')->andReturnSelf();
$collector->shouldReceive('setLimit')->andReturnSelf();
$collector->shouldReceive('withOpposingAccount')->andReturnSelf();
$collector->shouldReceive('setPage')->andReturnSelf();
$collector->shouldReceive('setTypes')->andReturnSelf();
$collector->shouldReceive('getTransactions')->andReturn(new Collection([$transaction]));
$collector->shouldReceive('getPaginatedTransactions')->andReturn(new LengthAwarePaginator([$transaction], 0, 10));
$this->be($this->user());
$this->changeDateRange($this->user(), $range);
$response = $this->get(route('accounts.show.all', [1]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('<ol class="breadcrumb">');
}
/**
* @covers \FireflyIII\Http\Controllers\Account\ShowController
*/
public function testShowBrokenBadDates(): void
{
Log::info(sprintf('testShowBrokenBadDates(%s)', ''));
// mock
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$date = new Carbon;
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
$accountRepos->shouldReceive('isLiability')->atLeast()->once()->andReturn(false);
// used for session range.
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$this->session(['start' => '2018-01-01', 'end' => '2017-12-01']);
$this->be($this->user());
$account = $this->user()->accounts()->where('account_type_id', 3)->orderBy('id', 'ASC')->whereNull('deleted_at')->first();
$response = $this->get(route('accounts.show', [$account->id, '2018-01-01', '2017-12-01']));
$response->assertStatus(500);
$response->assertSee('End is after start!');
}
/**
* @covers \FireflyIII\Http\Controllers\Account\ShowController
*/
public function testShowBrokenInitial(): void
{
Log::info(sprintf('testShowBrokenInitial(%s)', ''));
// mock
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$date = new Carbon;
$this->session(['start' => $date, 'end' => clone $date]);
$this->be($this->user());
$account = $this->user()->accounts()->where('account_type_id', 6)->orderBy('id', 'ASC')->whereNull('deleted_at')->first();
$response = $this->get(route('accounts.show', [$account->id]));
$response->assertStatus(302);
$response->assertRedirect(route('index'));
$response->assertSessionHas('error');
}
/**
* @covers \FireflyIII\Http\Controllers\Account\ShowController
* @dataProvider dateRangeProvider
*
* @param string $range
*/
public function testShowByDateEmpty(string $range): void
{
$this->markTestIncomplete('Needs to be rewritten for v4.8.0');
return;
Log::info(sprintf('testShowByDateEmpty(%s)', $range));
// mock stuff
$collector = $this->mock(TransactionCollectorInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
$fiscalHelper = $this->mock(FiscalHelperInterface::class);
$date = new Carbon;
$fiscalHelper->shouldReceive('endOfFiscalYear')->atLeast()->once()->andReturn($date);
$fiscalHelper->shouldReceive('startOfFiscalYear')->atLeast()->once()->andReturn($date);
// list size
$pref = new Preference;
$pref->data = 50;
Preferences::shouldReceive('get')->withArgs(['listPageSize', 50])->atLeast()->once()->andReturn($pref);
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$collector->shouldReceive('setAccounts')->andReturnSelf();
$collector->shouldReceive('setRange')->andReturnSelf();
$collector->shouldReceive('setLimit')->andReturnSelf();
$collector->shouldReceive('setAccounts')->andReturnSelf()->atLeast()->once();
$collector->shouldReceive('setLimit')->andReturnSelf()->atLeast()->once();
$collector->shouldReceive('setPage')->andReturnSelf();
$collector->shouldReceive('getPaginatedTransactions')->andReturn(new LengthAwarePaginator([], 0, 10));
$repository->shouldReceive('oldestJournalDate')->andReturn(new Carbon);
$repository->shouldReceive('getMetaValue')->andReturn('');
$repository->shouldReceive('isLiability')->andReturn(false);
$collector->shouldReceive('setTypes')->andReturnSelf();
$collector->shouldReceive('withOpposingAccount')->andReturnSelf();
$collector->shouldReceive('getTransactions')->andReturn(new Collection);
$currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1));
$collector->shouldReceive('getExtractedJournals')->andReturn([$journal]);
$collector->shouldReceive('withAccountInformation')->andReturnSelf();
$collector->shouldReceive('getPaginatedGroups')->andReturn(new LengthAwarePaginator([$group], 0, 10));
$this->be($this->user());
$this->changeDateRange($this->user(), $range);
$response = $this->get(route('accounts.show', [1, '2016-01-01']));
$response = $this->get(route('accounts.show.all', [$asset->id]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('<ol class="breadcrumb">');
}
/**
* @covers \FireflyIII\Http\Controllers\Account\ShowController
*/
public function testShowInitial(): void
{
Log::info(sprintf('testShowInitial(%s)', ''));
// mock stuff
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$date = new Carbon;
$this->session(['start' => $date, 'end' => clone $date]);
$this->be($this->user());
$account = $this->user()->accounts()->where('account_type_id', 6)->orderBy('id', 'DESC')->whereNull('deleted_at')->first();
$response = $this->get(route('accounts.show', [$account->id]));
$response->assertStatus(302);
}
/**
* @covers \FireflyIII\Http\Controllers\Account\ShowController
* @dataProvider dateRangeProvider
*
* @param string $range
*/
public function testShowLiability(string $range): void
{
Log::info(sprintf('testShowLiability(%s)', $range));
$date = new Carbon;
$this->session(['start' => $date, 'end' => clone $date]);
$account = $this->user()->accounts()->where('account_type_id', 12)->whereNull('deleted_at')->first();
// mock stuff:
$tasker = $this->mock(AccountTaskerInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
$currencyRepos->shouldReceive('findNull')->andReturn(TransactionCurrency::find(1));
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$tasker->shouldReceive('amountOutInPeriod')->withAnyArgs()->andReturn('-1');
$tasker->shouldReceive('amountInInPeriod')->withAnyArgs()->andReturn('1');
$repository->shouldReceive('getMetaValue')->andReturn('');
$repository->shouldReceive('isLiability')->andReturn(true);
$this->be($this->user());
$this->changeDateRange($this->user(), $range);
$response = $this->get(route('accounts.show', [$account->id]));
$response->assertStatus(302);
$response->assertRedirect(route('accounts.show.all', [$account->id]));
}
}

View File

@ -83,6 +83,24 @@ abstract class TestCase extends BaseTestCase
FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->once()->andReturn($falseConfig);
}
/**
* @return array
*/
public function getRandomWithdrawalAsArray(): array
{
$withdrawal = $this->getRandomWithdrawal();
$euro = $this->getEuro();
return [
'transaction_journal_id' => $withdrawal->id,
'currency_id' => $euro->id,
'currency_name' => $euro->name,
'currency_symbol' => $euro->symbol,
'currency_decimal_places' => $euro->decimal_places,
'amount' => '-30',
];
}
/**
* Mock default preferences.
*/
@ -388,7 +406,10 @@ abstract class TestCase extends BaseTestCase
->where('transaction_type_id', $transactionType->id)->inRandomOrder()->first();
/** @var TransactionGroup $group */
$group = $journal->transactionGroup;
$count = $group->transactionJournals()->count();
$count = 0;
if (null !== $group) {
$count = $group->transactionJournals()->count();
}
Log::debug(sprintf('Count is %d', $count));
} while (1 !== $count);

View File

@ -172,15 +172,17 @@ class AccountCurrenciesTest extends TestCase
*/
public function testHandleDifferent(): void
{
$false = new Configuration;
$false->data = false;
$pref = new Preference;
$pref->data = 'USD';
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
$journal = $this->getRandomWithdrawal();
$account = $this->getRandomAsset();
$euro = TransactionCurrency::where('code', 'EUR')->first();
$false = new Configuration;
$false->data = false;
$pref = new Preference;
$pref->data = 'USD';
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
$journal = $this->getRandomWithdrawal();
$account = $this->getRandomAsset();
$euro = $this->getEuro();
$journal->transaction_currency_id = $euro->id;
$journal->save();
// delete meta data of account just in case:
AccountMeta::where('account_id', $account->id)->where('name', 'currency_id')->forceDelete();

View File

@ -251,7 +251,8 @@ class UserEventHandlerTest extends TestCase
Mail::fake();
$user = $this->emptyUser();
$event = new RegisteredUser($user, '127.0.0.1');
//config('firefly.send_registration_mail', true);
\Config::set('firefly.send_registration_mail', true);
$listener = new UserEventHandler;
$listener->sendRegistrationMail($event);