mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-01-05 21:53:08 -06:00
Merge branch 'release/3.4.0.6'
This commit is contained in:
commit
aaa186be5e
12
README.md
12
README.md
@ -1,5 +1,5 @@
|
||||
# Firefly III
|
||||
#### v3.4.0.5
|
||||
#### v3.4.0.6
|
||||
|
||||
[![Build Status](https://travis-ci.org/JC5/firefly-iii.svg?branch=develop)](https://travis-ci.org/JC5/firefly-iii)
|
||||
[![Project Status](http://stillmaintained.com/JC5/firefly-iii.png?a=b)](http://stillmaintained.com/JC5/firefly-iii)
|
||||
@ -13,11 +13,13 @@
|
||||
"Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared
|
||||
household accounts and savings accounts! It's pretty fancy. You should use it to save and organise money.
|
||||
|
||||
Firefly is a system you'll have install yourself on webhosting of your choosing.
|
||||
_Firefly is a system you'll have install yourself on webhosting of your choosing._
|
||||
|
||||
Personal financial management is pretty difficult, and everybody has their own approach to it. Some people
|
||||
make budgets, other people limit their cashflow by throwing away their credit cards, others get a better job.
|
||||
There are tons of ways to save and earn money.
|
||||
make budgets, other people limit their cashflow by throwing away their credit cards, others try to increase
|
||||
their current cashflow. There are tons of ways to save and earn money.
|
||||
|
||||
Firefly works on the principle that if you know where you're money is going, you can stop it from going there.
|
||||
|
||||
|
||||
To get to know Firefly, and to see if it fits you, check out these resources:
|
||||
@ -28,7 +30,7 @@ To get to know Firefly, and to see if it fits you, check out these resources:
|
||||
and the philosophy behind it.
|
||||
|
||||
|
||||
### About the name (if you care)
|
||||
#### About the name (if you care)
|
||||
|
||||
It's III, or 3, because [version 2](https://github.com/JC5/Firefly) and version 1 (not online) preceded it. It has been growing steadily ever since.
|
||||
|
||||
|
@ -30,7 +30,7 @@ class ConnectJournalToPiggyBank
|
||||
*
|
||||
* @param JournalCreated $event
|
||||
*
|
||||
* @return void
|
||||
* @return boolean
|
||||
*/
|
||||
public function handle(JournalCreated $event)
|
||||
{
|
||||
@ -38,7 +38,7 @@ class ConnectJournalToPiggyBank
|
||||
$journal = $event->journal;
|
||||
$piggyBankId = $event->piggyBankId;
|
||||
if (intval($piggyBankId) < 1) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
Log::debug('JournalCreated event: ' . $journal->id . ', ' . $piggyBankId);
|
||||
@ -47,20 +47,20 @@ class ConnectJournalToPiggyBank
|
||||
$piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
|
||||
|
||||
if (is_null($piggyBank) || $journal->transactionType->type != 'Transfer') {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
Log::debug('Found a piggy bank');
|
||||
$amount = $journal->amount;
|
||||
Log::debug('Amount: ' . $amount);
|
||||
if ($amount == 0) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// update piggy bank rep for date of transaction journal.
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
if (is_null($repetition)) {
|
||||
Log::debug('Found no repetition for piggy bank for date ' . $journal->date->format('Y M d'));
|
||||
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
Log::debug('Found rep! ' . $repetition->id);
|
||||
@ -91,6 +91,7 @@ class ConnectJournalToPiggyBank
|
||||
'amount' => $amount
|
||||
]
|
||||
);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ use Log;
|
||||
/**
|
||||
* Class RescanJournal
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class RescanJournal
|
||||
|
@ -6,6 +6,7 @@ use FireflyIII\Models\PiggyBankEvent;
|
||||
/**
|
||||
* Class UpdateJournalConnection
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UpdateJournalConnection
|
||||
|
@ -17,6 +17,7 @@ class Help implements HelpInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param $key
|
||||
*
|
||||
* @return string
|
||||
@ -27,6 +28,7 @@ class Help implements HelpInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param $route
|
||||
*
|
||||
* @return array
|
||||
@ -54,6 +56,7 @@ class Help implements HelpInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param $route
|
||||
*
|
||||
* @return bool
|
||||
@ -64,6 +67,7 @@ class Help implements HelpInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param $route
|
||||
* @param array $content
|
||||
*
|
||||
@ -76,6 +80,7 @@ class Help implements HelpInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param $route
|
||||
*
|
||||
* @return bool
|
||||
|
@ -33,7 +33,7 @@ class ReminderHelper implements ReminderHelperInterface
|
||||
$ranges = $this->getReminderRanges($piggyBank, $start);
|
||||
$currentRep = $piggyBank->currentRelevantRep();
|
||||
$left = $piggyBank->targetamount - $currentRep->currentamount;
|
||||
$perReminder = $left / count($ranges);
|
||||
$perReminder = count($ranges) == 0 ? $left : $left / count($ranges);
|
||||
} else {
|
||||
$perReminder = null;
|
||||
$ranges = [];
|
||||
@ -46,8 +46,6 @@ class ReminderHelper implements ReminderHelperInterface
|
||||
'leftToSave' => $left,
|
||||
];
|
||||
|
||||
|
||||
// create one:
|
||||
$reminder = new Reminder;
|
||||
$reminder->user()->associate(Auth::user());
|
||||
$reminder->startdate = $start;
|
||||
|
@ -18,25 +18,6 @@ use Steam;
|
||||
class ReportHelper implements ReportHelperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* This methods fails to take in account transfers FROM shared accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function expensesGroupedByAccount(Carbon $start, Carbon $end, $limit = 15)
|
||||
{
|
||||
$result = $this->_queries->journalsByExpenseAccount($start, $end);
|
||||
$array = $this->_helper->makeArray($result);
|
||||
$limited = $this->_helper->limitArray($array, $limit);
|
||||
|
||||
return $limited;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets some kind of list for a monthly overview.
|
||||
*
|
||||
|
@ -13,18 +13,6 @@ use Illuminate\Support\Collection;
|
||||
interface ReportHelperInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* This methods fails to take in account transfers FROM shared accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function expensesGroupedByAccount(Carbon $start, Carbon $end, $limit = 15);
|
||||
|
||||
/**
|
||||
* This method gets some kind of list for a monthly overview.
|
||||
*
|
||||
|
@ -46,7 +46,7 @@ class PiggyBanks
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest() && App::environment() != 'testing') {
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest()) {
|
||||
// get piggy banks without a repetition:
|
||||
/** @var Collection $set */
|
||||
$set = $this->auth->user()->piggybanks()
|
||||
|
@ -48,7 +48,7 @@ class Range
|
||||
*/
|
||||
public function handle(Request $request, Closure $theNext)
|
||||
{
|
||||
if ($this->auth->check() && App::environment() != 'testing') {
|
||||
if ($this->auth->check()) {
|
||||
|
||||
// ignore preference. set the range to be the current month:
|
||||
if (!Session::has('start') && !Session::has('end')) {
|
||||
|
@ -46,7 +46,7 @@ class Reminders
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest() && App::environment() != 'testing') {
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest()) {
|
||||
// do reminders stuff.
|
||||
$piggyBanks = $this->auth->user()->piggyBanks()->where('remind_me', 1)->get();
|
||||
$today = new Carbon;
|
||||
|
@ -246,13 +246,12 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
->whereNotNull('budget_transaction_journal.budget_id');
|
||||
}
|
||||
)
|
||||
->before($end)
|
||||
->after($start)
|
||||
->before($end)
|
||||
->lessThan(0)
|
||||
->transactionTypes(['Withdrawal'])
|
||||
->get();
|
||||
|
||||
return floatval($noBudgetSet->sum('amount')) * -1;
|
||||
->sum('transactions.amount');
|
||||
return floatval($noBudgetSet) * -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,7 +60,7 @@
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header">
|
||||
{% if mainTitleIcon %}
|
||||
<i class="fa {{ mainTitleIcon }}"></i>
|
||||
<i class="hidden-xs fa {{ mainTitleIcon }}"></i>
|
||||
{% endif %}
|
||||
|
||||
{{ title }}
|
||||
@ -68,12 +68,12 @@
|
||||
{% if subTitle %}
|
||||
<small>
|
||||
{% if subTitleIcon %}
|
||||
<i class="fa {{ subTitleIcon }}"></i>
|
||||
<i class="hidden-xs fa {{ subTitleIcon }}"></i>
|
||||
{% endif %}
|
||||
{{ subTitle }}
|
||||
</small>
|
||||
{% endif %}
|
||||
<small class="pull-right"><a href="#" id="help" data-route="{{ Route.getCurrentRoute.getName }}"><i
|
||||
<small class="pull-right hidden-xs"><a href="#" id="help" data-route="{{ Route.getCurrentRoute.getName }}"><i
|
||||
data-route="{{ Route.getCurrentRoute.getName }}" class="fa fa-question-circle"></i></a></small>
|
||||
</h1>
|
||||
|
||||
|
@ -2,25 +2,25 @@
|
||||
|
||||
<table class="table table-striped table-bordered sortable-table">
|
||||
<tr class="ignore">
|
||||
<th colspan="2"> </th>
|
||||
<th class="hidden-xs" colspan="2"> </th>
|
||||
<th>Description</th>
|
||||
<th>Amount</th>
|
||||
<th>Date</th>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th class="hidden-xs">From</th>
|
||||
<th class="hidden-xs">To</th>
|
||||
<!-- Hide budgets? -->
|
||||
{% if not hideBudgets %}
|
||||
<th><i class="fa fa-tasks fa-fw" title="Budget"></i></th>
|
||||
<th class="hidden-xs"><i class="fa fa-tasks fa-fw" title="Budget"></i></th>
|
||||
{% endif %}
|
||||
|
||||
<!-- Hide categories? -->
|
||||
{% if not hideCategories %}
|
||||
<th><i class="fa fa-bar-chart fa-fw" title="Category"></i></th>
|
||||
<th class="hidden-xs"><i class="fa fa-bar-chart fa-fw" title="Category"></i></th>
|
||||
{% endif %}
|
||||
|
||||
<!-- Hide bills? -->
|
||||
{% if not hideBills %}
|
||||
<th><i class="fa fa-fw fa-rotate-right" title="Bill"></i></th>
|
||||
<th class="hidden-xs"><i class="fa fa-fw fa-rotate-right" title="Bill"></i></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% for journal in journals %}
|
||||
@ -37,7 +37,7 @@
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr class="drag" data-date="{{journal.date.format('Y-m-d')}}" data-id="{{journal.id}}">
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
<div class="btn-group btn-group-xs">
|
||||
{% if sorting %}
|
||||
<a href="#" class="handle btn btn-default btn-xs"><i class="fa fa-fw fa-arrows-v"></i></a>
|
||||
@ -47,7 +47,7 @@
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
{{ journal|typeIcon }}
|
||||
</td>
|
||||
<td>
|
||||
@ -63,14 +63,14 @@
|
||||
<td>
|
||||
{{journal.date.format('j F Y')}}
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
{% if journal.transactions[0].account.accountType.type == 'Cash account' %}
|
||||
<span class="text-success">(cash)</span>
|
||||
{% else %}
|
||||
<a href="{{route('accounts.show',journal.transactions[0].account_id)}}">{{journal.transactions[0].account.name}}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
{% if journal.transactions[1].account.accountType.type == 'Cash account' %}
|
||||
<span class="text-success">(cash)</span>
|
||||
{% else %}
|
||||
@ -80,7 +80,7 @@
|
||||
|
||||
<!-- Do NOT hide the budget? -->
|
||||
{% if not hideBudgets %}
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
{% if journal.budgets[0] %}
|
||||
<a href="{{route('budgets.show',journal.budgets[0].id)}}">{{journal.budgets[0].name}}</a>
|
||||
{% endif %}
|
||||
@ -89,7 +89,7 @@
|
||||
|
||||
<!-- Do NOT hide the category? -->
|
||||
{% if not hideCategories %}
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
{% if journal.categories[0] %}
|
||||
<a href="{{route('categories.show',journal.categories[0].id)}}">{{journal.categories[0].name}}</a>
|
||||
{% endif %}
|
||||
@ -98,7 +98,7 @@
|
||||
|
||||
<!-- Do NOT hide the bill? -->
|
||||
{% if not hideBills %}
|
||||
<td>
|
||||
<td class="hidden-xs">
|
||||
{% if journal.bill %}
|
||||
<a href="{{ route('bills.show',journal.bill_id) }}">{{journal.bill.name}}</a>
|
||||
{% endif %}
|
||||
|
@ -13,7 +13,7 @@
|
||||
<!-- /.navbar-header -->
|
||||
|
||||
|
||||
<ul class="nav navbar-top-links navbar-right">
|
||||
<ul class="nav navbar-top-links navbar-right hidden-xs">
|
||||
|
||||
<!-- reminders -->
|
||||
{% if reminders|length > 0 %}
|
||||
@ -68,16 +68,15 @@
|
||||
|
||||
<!-- /.dropdown -->
|
||||
|
||||
|
||||
</ul>
|
||||
<p class="navbar-text navbar-right" id="daterange"><span> </span> <b class="caret"></b></p>
|
||||
<p class="navbar-text navbar-right hidden-xs" id="daterange"><span> </span> <b class="caret"></b></p>
|
||||
|
||||
|
||||
<!-- /.navbar-top-links -->
|
||||
<div class="navbar-default sidebar" role="navigation">
|
||||
<div class="sidebar-nav navbar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
<li class="sidebar-search">
|
||||
<li class="sidebar-search hidden-xs">
|
||||
<form action="{{ route('search') }}" method="GET" class="form-inline">
|
||||
<div class="input-group custom-search-form">
|
||||
<input type="text" name="q" class="form-control" value="{% if Input.get('q') %}{{ Input.get('q') }}{% endif %}"
|
||||
@ -174,6 +173,8 @@
|
||||
</ul>
|
||||
<!-- /.nav-second-level -->
|
||||
</li>
|
||||
<!-- profile, again-->
|
||||
<!-- reminders, again-->
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /.sidebar-collapse -->
|
||||
|
269
tests/helpers/ConnectJournalToPiggyBankTest.php
Normal file
269
tests/helpers/ConnectJournalToPiggyBankTest.php
Normal file
@ -0,0 +1,269 @@
|
||||
<?php
|
||||
use FireflyIII\Events\JournalCreated;
|
||||
use FireflyIII\Handlers\Events\ConnectJournalToPiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use League\FactoryMuffin\Facade as FactoryMuffin;
|
||||
|
||||
/**
|
||||
* Class ConnectJournalToPiggyBankTest
|
||||
*/
|
||||
class ConnectJournalToPiggyBankTest extends TestCase
|
||||
{
|
||||
//event(new JournalCreated($journal, intval($request->get('piggy_bank_id'))));
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the fixture, for example, closes a network connection.
|
||||
* This method is called after a test is executed.
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
|
||||
public function testEmptyPiggyBankId()
|
||||
{
|
||||
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
|
||||
$event = new JournalCreated($journal, 0);
|
||||
$class = new ConnectJournalToPiggyBank();
|
||||
$result = $class->handle($event);
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testNoRepetition()
|
||||
{
|
||||
FactoryMuffin::create('FireflyIII\Models\TransactionType');
|
||||
FactoryMuffin::create('FireflyIII\Models\TransactionType');
|
||||
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$this->be($user);
|
||||
|
||||
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
|
||||
/** @var \FireflyIII\Models\PiggyBank $piggyBank */
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$account1 = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account2 = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account1->user_id = $user->id;
|
||||
$account2->user_id = $user->id;
|
||||
$piggyBank->account_id = $account1->id;
|
||||
$account1->save();
|
||||
$account2->save();
|
||||
$piggyBank->save();
|
||||
|
||||
// because the event handler responds to this piggy bank, we must remove
|
||||
// the piggy bank repetition:
|
||||
/** @var \FireflyIII\Models\PiggyBankRepetition $rep */
|
||||
foreach($piggyBank->piggyBankRepetitions()->get() as $rep) {
|
||||
$rep->forceDelete();
|
||||
}
|
||||
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $account1->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => 100
|
||||
]
|
||||
);
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $account2->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => -100
|
||||
]
|
||||
);
|
||||
|
||||
// two transactions:
|
||||
|
||||
|
||||
$event = new JournalCreated($journal, $piggyBank->id);
|
||||
$class = new ConnectJournalToPiggyBank();
|
||||
$result = $class->handle($event);
|
||||
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testNoSuchPiggy()
|
||||
{
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$this->be($user);
|
||||
|
||||
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
|
||||
$event = new JournalCreated($journal, 1);
|
||||
$class = new ConnectJournalToPiggyBank();
|
||||
$result = $class->handle($event);
|
||||
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testWithRepetition()
|
||||
{
|
||||
FactoryMuffin::create('FireflyIII\Models\TransactionType');
|
||||
FactoryMuffin::create('FireflyIII\Models\TransactionType');
|
||||
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$this->be($user);
|
||||
|
||||
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$account1 = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account2 = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account1->user_id = $user->id;
|
||||
$account2->user_id = $user->id;
|
||||
$piggyBank->account_id = $account1->id;
|
||||
$account1->save();
|
||||
$account2->save();
|
||||
$piggyBank->save();
|
||||
|
||||
$start = clone $journal->date;
|
||||
$end = clone $journal->date;
|
||||
$start->subDay();
|
||||
$end->addDay();
|
||||
|
||||
PiggyBankRepetition::create(
|
||||
[
|
||||
'piggy_bank_id' => $piggyBank->id,
|
||||
'startdate' => $start->format('Y-m-d'),
|
||||
'targetdate' => $end->format('Y-m-d'),
|
||||
'currentamount' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $account1->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => 100
|
||||
]
|
||||
);
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $account2->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => -100
|
||||
]
|
||||
);
|
||||
|
||||
$event = new JournalCreated($journal, $piggyBank->id);
|
||||
$class = new ConnectJournalToPiggyBank();
|
||||
$result = $class->handle($event);
|
||||
|
||||
|
||||
$this->assertTrue($result);
|
||||
$this->assertCount(1, $piggyBank->piggyBankEvents()->get());
|
||||
}
|
||||
|
||||
public function testWithRepetitionReversed()
|
||||
{
|
||||
FactoryMuffin::create('FireflyIII\Models\TransactionType');
|
||||
FactoryMuffin::create('FireflyIII\Models\TransactionType');
|
||||
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$this->be($user);
|
||||
|
||||
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$account1 = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account2 = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account1->user_id = $user->id;
|
||||
$account2->user_id = $user->id;
|
||||
$piggyBank->account_id = $account1->id;
|
||||
$account1->save();
|
||||
$account2->save();
|
||||
$piggyBank->save();
|
||||
|
||||
$start = clone $journal->date;
|
||||
$end = clone $journal->date;
|
||||
$start->subDay();
|
||||
$end->addDay();
|
||||
|
||||
PiggyBankRepetition::create(
|
||||
[
|
||||
'piggy_bank_id' => $piggyBank->id,
|
||||
'startdate' => $start->format('Y-m-d'),
|
||||
'targetdate' => $end->format('Y-m-d'),
|
||||
'currentamount' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $account1->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => -100
|
||||
]
|
||||
);
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $account2->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => 100
|
||||
]
|
||||
);
|
||||
|
||||
$event = new JournalCreated($journal, $piggyBank->id);
|
||||
$class = new ConnectJournalToPiggyBank();
|
||||
$result = $class->handle($event);
|
||||
|
||||
|
||||
$this->assertTrue($result);
|
||||
$this->assertCount(1, $piggyBank->piggyBankEvents()->get());
|
||||
}
|
||||
|
||||
public function testZeroAmount()
|
||||
{
|
||||
FactoryMuffin::create('FireflyIII\Models\TransactionType');
|
||||
FactoryMuffin::create('FireflyIII\Models\TransactionType');
|
||||
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$this->be($user);
|
||||
|
||||
$journal = FactoryMuffin::create('FireflyIII\Models\TransactionJournal');
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$account1 = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account2 = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account1->user_id = $user->id;
|
||||
$account2->user_id = $user->id;
|
||||
$piggyBank->account_id = $account1->id;
|
||||
$account1->save();
|
||||
$account2->save();
|
||||
$piggyBank->save();
|
||||
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $account1->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => 0
|
||||
]
|
||||
);
|
||||
Transaction::create(
|
||||
[
|
||||
'account_id' => $account2->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => 0
|
||||
]
|
||||
);
|
||||
|
||||
// two transactions:
|
||||
|
||||
|
||||
$event = new JournalCreated($journal, $piggyBank->id);
|
||||
$class = new ConnectJournalToPiggyBank();
|
||||
$result = $class->handle($event);
|
||||
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
}
|
167
tests/helpers/ReminderHelperTest.php
Normal file
167
tests/helpers/ReminderHelperTest.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Reminders\ReminderHelper;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use League\FactoryMuffin\Facade as FactoryMuffin;
|
||||
|
||||
/**
|
||||
* Class ReminderHelperTest
|
||||
*/
|
||||
class ReminderHelperTest extends TestCase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @var ReminderHelper
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
FactoryMuffin::create('FireflyIII\User');
|
||||
$this->object = new ReminderHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the fixture, for example, closes a network connection.
|
||||
* This method is called after a test is executed.
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testCreateReminder()
|
||||
{
|
||||
$account = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$piggyBank->account_id = $account->id;
|
||||
$start = Carbon::now()->startOfMonth();
|
||||
$end = Carbon::now()->endOfMonth()->startOfDay();
|
||||
$piggyBank->save();
|
||||
$this->be($account->user);
|
||||
|
||||
$result = $this->object->createReminder($piggyBank, $start, $end);
|
||||
$this->assertEquals($piggyBank->targetamount, $result->metadata->leftToSave);
|
||||
}
|
||||
|
||||
public function testCreateReminderHaveAlready()
|
||||
{
|
||||
$account = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$reminder = FactoryMuffin::create('FireflyIII\Models\Reminder');
|
||||
$piggyBank->account_id = $account->id;
|
||||
$start = Carbon::now()->startOfMonth();
|
||||
$end = Carbon::now()->endOfMonth()->startOfDay();
|
||||
$reminder->remindersable_id = $piggyBank->id;
|
||||
$reminder->startdate = $start;
|
||||
$reminder->enddate = $end;
|
||||
$reminder->user_id = $account->user_id;
|
||||
$reminder->save();
|
||||
$piggyBank->save();
|
||||
$this->be($account->user);
|
||||
|
||||
$result = $this->object->createReminder($piggyBank, $start, $end);
|
||||
$this->assertEquals($reminder->id, $result->id);
|
||||
}
|
||||
|
||||
public function testCreateReminderNoTarget()
|
||||
{
|
||||
$account = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$piggyBank->targetdate = null;
|
||||
$piggyBank->account_id = $account->id;
|
||||
$start = Carbon::now()->startOfMonth();
|
||||
$end = Carbon::now()->endOfMonth()->startOfDay();
|
||||
$piggyBank->save();
|
||||
$this->be($account->user);
|
||||
|
||||
$result = $this->object->createReminder($piggyBank, $start, $end);
|
||||
$this->assertEquals(0, $result->metadata->leftToSave);
|
||||
}
|
||||
|
||||
public function testGetReminderRangesNull()
|
||||
{
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$result = $this->object->getReminderRanges($piggyBank);
|
||||
$this->assertEquals([], $result);
|
||||
}
|
||||
|
||||
public function testGetReminderRangesWithTargetDate()
|
||||
{
|
||||
/** @var \FireflyIII\Models\PiggyBank $piggyBank */
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$piggyBank->startdate = new Carbon('2015-01-01');
|
||||
$piggyBank->targetdate = new Carbon('2015-12-31');
|
||||
$piggyBank->reminder = 'monthly';
|
||||
$piggyBank->remind_me = true;
|
||||
$piggyBank->save();
|
||||
|
||||
$result = $this->object->getReminderRanges($piggyBank, new Carbon('2015-04-01'));
|
||||
// date is ignored, result should be 12:
|
||||
$this->assertCount(12, $result);
|
||||
|
||||
}
|
||||
|
||||
public function testGetReminderRangesWithoutTargetDate()
|
||||
{
|
||||
/** @var \FireflyIII\Models\PiggyBank $piggyBank */
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$piggyBank->startdate = new Carbon('2015-01-01');
|
||||
$piggyBank->targetdate = null;
|
||||
$piggyBank->reminder = 'monthly';
|
||||
$piggyBank->remind_me = true;
|
||||
$piggyBank->save();
|
||||
$result = $this->object->getReminderRanges($piggyBank, new Carbon('2015-12-31'));
|
||||
// date is a year later, result should be 12:
|
||||
$this->assertCount(12, $result);
|
||||
|
||||
}
|
||||
|
||||
public function testGetReminderTextDate()
|
||||
{
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$reminder = FactoryMuffin::create('FireflyIII\Models\Reminder');
|
||||
$piggyBank->targetdate = new Carbon;
|
||||
$reminder->remindersable_id = $piggyBank->id;
|
||||
|
||||
Amount::shouldReceive('format')->andReturn('xx');
|
||||
|
||||
$result = $this->object->getReminderText($reminder);
|
||||
$strpos = strpos($result, 'to fill this piggy bank on ');
|
||||
$this->assertTrue(!($strpos === false));
|
||||
|
||||
}
|
||||
|
||||
public function testGetReminderTextNoPiggy()
|
||||
{
|
||||
$reminder = FactoryMuffin::create('FireflyIII\Models\Reminder');
|
||||
$reminder->remindersable_id = 2;
|
||||
$this->assertEquals('Piggy bank no longer exists.', $this->object->getReminderText($reminder));
|
||||
|
||||
}
|
||||
|
||||
public function testGetReminderTextNullDate()
|
||||
{
|
||||
$piggyBank = FactoryMuffin::create('FireflyIII\Models\PiggyBank');
|
||||
$reminder = FactoryMuffin::create('FireflyIII\Models\Reminder');
|
||||
$piggyBank->targetdate = null;
|
||||
$piggyBank->save();
|
||||
$reminder->remindersable_id = $piggyBank->id;
|
||||
$reminder->save();
|
||||
|
||||
Amount::shouldReceive('format')->andReturn('xx');
|
||||
|
||||
$result = $this->object->getReminderText($reminder);
|
||||
$strpos = strpos($result, 'Add money to this piggy bank to reach your target of');
|
||||
$this->assertTrue(!($strpos === false));
|
||||
|
||||
}
|
||||
}
|
234
tests/helpers/ReportHelperTest.php
Normal file
234
tests/helpers/ReportHelperTest.php
Normal file
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Report\ReportHelper;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use League\FactoryMuffin\Facade as FactoryMuffin;
|
||||
|
||||
/**
|
||||
* Class ReportHelperTest
|
||||
*/
|
||||
class ReportHelperTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var ReportHelper
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
FactoryMuffin::create('FireflyIII\User');
|
||||
$this->object = new ReportHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the fixture, for example, closes a network connection.
|
||||
* This method is called after a test is executed.
|
||||
*/
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers FireflyIII\Helpers\Report\ReportHelper::getBudgetsForMonth
|
||||
* @covers FireflyIII\Helpers\Report\ReportQuery::journalsByBudget
|
||||
* @covers FireflyIII\Helpers\Report\ReportQuery::sharedExpenses
|
||||
*/
|
||||
public function testGetBudgetsForMonthWithShared()
|
||||
{
|
||||
$date = new Carbon('2015-01-01');
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$budgets = [];
|
||||
|
||||
// three budget limits starting on the $date:
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
|
||||
$budgetLimit = FactoryMuffin::create('FireflyIII\Models\BudgetLimit');
|
||||
$budgetLimit->startdate = $date;
|
||||
$budget->user_id = $user->id;
|
||||
$budget->save();
|
||||
$budgetLimit->save();
|
||||
$budgets[] = $budget;
|
||||
}
|
||||
|
||||
$this->be($user);
|
||||
|
||||
$result = $this->object->getBudgetsForMonth($date, true);
|
||||
|
||||
// assert each budget is in the array:
|
||||
foreach ($budgets as $budget) {
|
||||
$id = $budget->id;
|
||||
$this->assertEquals($budget->name, $result[$id]['name']);
|
||||
}
|
||||
$this->assertEquals(0, $result[0]['queryAmount']);
|
||||
$this->assertEquals('No budget', $result[0]['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers FireflyIII\Helpers\Report\ReportHelper::getBudgetsForMonth
|
||||
* @covers FireflyIII\Helpers\Report\ReportQuery::journalsByBudget
|
||||
*/
|
||||
public function testGetBudgetsForMonthWithoutShared()
|
||||
{
|
||||
$date = new Carbon('2015-01-01');
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$budgets = [];
|
||||
|
||||
// three budget limits starting on the $date:
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$budget = FactoryMuffin::create('FireflyIII\Models\Budget');
|
||||
$budgetLimit = FactoryMuffin::create('FireflyIII\Models\BudgetLimit');
|
||||
$budgetLimit->startdate = $date;
|
||||
$budget->user_id = $user->id;
|
||||
$budget->save();
|
||||
$budgetLimit->save();
|
||||
$budgets[] = $budget;
|
||||
}
|
||||
|
||||
$this->be($user);
|
||||
|
||||
$result = $this->object->getBudgetsForMonth($date, false);
|
||||
|
||||
// assert each budget is in the array:
|
||||
foreach ($budgets as $budget) {
|
||||
$id = $budget->id;
|
||||
$this->assertEquals($budget->name, $result[$id]['name']);
|
||||
}
|
||||
$this->assertEquals(0, $result[0]['queryAmount']);
|
||||
$this->assertEquals('No budget', $result[0]['name']);
|
||||
}
|
||||
|
||||
public function testListOfMonths()
|
||||
{
|
||||
// start of year up until now
|
||||
$date = new Carbon('2015-01-01');
|
||||
$now = new Carbon;
|
||||
$diff = $now->diffInMonths($date) + 1; // the month itself.
|
||||
$result = $this->object->listOfMonths($date);
|
||||
|
||||
$this->assertCount($diff, $result[2015]);
|
||||
|
||||
}
|
||||
|
||||
public function testListOfYears()
|
||||
{
|
||||
|
||||
$date = new Carbon('2015-01-01');
|
||||
$now = new Carbon;
|
||||
$diff = $now->diffInYears($date) + 1; // the year itself.
|
||||
$result = $this->object->listOfYears($date);
|
||||
$this->assertCount($diff, $result);
|
||||
}
|
||||
|
||||
public function testYearBalanceReport()
|
||||
{
|
||||
$date = new Carbon('2015-01-01');
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$setShared = [];
|
||||
$setNormal = [];
|
||||
|
||||
FactoryMuffin::create('FireflyIII\Models\AccountType');
|
||||
FactoryMuffin::create('FireflyIII\Models\AccountType');
|
||||
$assetType = FactoryMuffin::create('FireflyIII\Models\AccountType');
|
||||
|
||||
// need some shared accounts:
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$shared = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$shared->user_id = $user->id;
|
||||
$shared->account_type_id = $assetType->id;
|
||||
$shared->save();
|
||||
// meta for shared:
|
||||
AccountMeta::create(
|
||||
[
|
||||
'account_id' => $shared->id,
|
||||
'name' => 'accountRole',
|
||||
'data' => 'sharedAsset',
|
||||
]
|
||||
);
|
||||
$setShared[] = $shared;
|
||||
}
|
||||
|
||||
// need some normal accounts:
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$account = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account->user_id = $user->id;
|
||||
$account->account_type_id = $assetType->id;
|
||||
$account->save();
|
||||
$setNormal[] = $account;
|
||||
}
|
||||
|
||||
// mock stuff:
|
||||
Steam::shouldReceive('balance')->withAnyArgs()->andReturn(0);
|
||||
|
||||
$this->be($user);
|
||||
|
||||
$result = $this->object->yearBalanceReport($date, false);
|
||||
foreach($result as $entry) {
|
||||
// everything is hidden:
|
||||
$this->assertTrue($entry['hide']);
|
||||
// nothing is shared:
|
||||
$this->assertFalse($entry['shared']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function testYearBalanceReportWithShared()
|
||||
{
|
||||
$date = new Carbon('2015-01-01');
|
||||
$user = FactoryMuffin::create('FireflyIII\User');
|
||||
$setShared = [];
|
||||
$setNormal = [];
|
||||
|
||||
FactoryMuffin::create('FireflyIII\Models\AccountType');
|
||||
FactoryMuffin::create('FireflyIII\Models\AccountType');
|
||||
$assetType = FactoryMuffin::create('FireflyIII\Models\AccountType');
|
||||
|
||||
// need some shared accounts:
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$shared = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$shared->user_id = $user->id;
|
||||
$shared->account_type_id = $assetType->id;
|
||||
$shared->save();
|
||||
// meta for shared:
|
||||
AccountMeta::create(
|
||||
[
|
||||
'account_id' => $shared->id,
|
||||
'name' => 'accountRole',
|
||||
'data' => 'sharedAsset',
|
||||
]
|
||||
);
|
||||
$setShared[] = $shared;
|
||||
}
|
||||
|
||||
// need some normal accounts:
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$account = FactoryMuffin::create('FireflyIII\Models\Account');
|
||||
$account->user_id = $user->id;
|
||||
$account->account_type_id = $assetType->id;
|
||||
$account->save();
|
||||
$setNormal[] = $account;
|
||||
}
|
||||
|
||||
// mock stuff:
|
||||
Steam::shouldReceive('balance')->withAnyArgs()->andReturn(0);
|
||||
|
||||
$this->be($user);
|
||||
|
||||
$result = $this->object->yearBalanceReport($date, true);
|
||||
foreach($result as $entry) {
|
||||
// everything is hidden:
|
||||
$this->assertTrue($entry['hide']);
|
||||
// nothing is shared:
|
||||
$this->assertFalse($entry['shared']);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user