All code for issue #38.

This commit is contained in:
James Cole
2014-12-29 20:28:17 +01:00
parent 40892ccfa7
commit 75f86462e2
32 changed files with 573 additions and 498 deletions

View File

@@ -195,37 +195,37 @@ Breadcrumbs::register(
}
);
// recurring transactions
// bills
Breadcrumbs::register(
'recurring.index', function (Generator $breadcrumbs) {
'bills.index', function (Generator $breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push('Recurring transactions', route('recurring.index'));
$breadcrumbs->push('Bills', route('bills.index'));
}
);
Breadcrumbs::register(
'recurring.create', function (Generator $breadcrumbs) {
$breadcrumbs->parent('recurring.index');
$breadcrumbs->push('Create new recurring transaction', route('recurring.create'));
'bills.create', function (Generator $breadcrumbs) {
$breadcrumbs->parent('bills.index');
$breadcrumbs->push('Create new bill', route('bills.create'));
}
);
Breadcrumbs::register(
'recurring.edit', function (Generator $breadcrumbs, RecurringTransaction $recurring) {
$breadcrumbs->parent('recurring.show', $recurring);
$breadcrumbs->push('Edit ' . $recurring->name, route('recurring.edit', $recurring->id));
'bills.edit', function (Generator $breadcrumbs, Bill $bill) {
$breadcrumbs->parent('bills.show', $bill);
$breadcrumbs->push('Edit ' . $bill->name, route('bills.edit', $bill->id));
}
);
Breadcrumbs::register(
'recurring.delete', function (Generator $breadcrumbs, RecurringTransaction $recurring) {
$breadcrumbs->parent('recurring.show', $recurring);
$breadcrumbs->push('Delete ' . $recurring->name, route('recurring.delete', $recurring->id));
'bills.delete', function (Generator $breadcrumbs, Bill $bill) {
$breadcrumbs->parent('bills.show', $bill);
$breadcrumbs->push('Delete ' . $bill->name, route('bills.delete', $bill->id));
}
);
Breadcrumbs::register(
'recurring.show', function (Generator $breadcrumbs, RecurringTransaction $recurring) {
$breadcrumbs->parent('recurring.index');
$breadcrumbs->push($recurring->name, route('recurring.show', $recurring->id));
'bills.show', function (Generator $breadcrumbs, Bill $bill) {
$breadcrumbs->parent('bills.index');
$breadcrumbs->push($bill->name, route('bills.show', $bill->id));
}
);

View File

@@ -0,0 +1,205 @@
<?php
use FireflyIII\Database\Bill\Bill as Repository;
use FireflyIII\Exception\FireflyException;
/**
*
* @SuppressWarnings("CamelCase") // I'm fine with this.
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
* @SuppressWarnings("NPathComplexity")
* Class BillController
*
*/
class BillController extends BaseController
{
/** @var Repository */
protected $_repository;
/**
* @param Repository $repository
*/
public function __construct(Repository $repository)
{
$this->_repository = $repository;
View::share('title', 'Bills');
View::share('mainTitleIcon', 'fa-rotate-right');
}
/**
* @return $this
*/
public function create()
{
$periods = \Config::get('firefly.periods_to_text');
return View::make('bills.create')->with('periods', $periods)->with('subTitle', 'Create new');
}
/**
* @param Bill $bill
*
* @return $this
*/
public function delete(Bill $bill)
{
return View::make('bills.delete')->with('bill', $bill)->with(
'subTitle', 'Delete "' . $bill->name . '"'
);
}
/**
* @param Bill $bill
*
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(Bill $bill)
{
$this->_repository->destroy($bill);
Session::flash('success', 'The bill was deleted.');
return Redirect::route('bills.index');
}
/**
* @param Bill $bill
*
* @return $this
*/
public function edit(Bill $bill)
{
$periods = \Config::get('firefly.periods_to_text');
return View::make('bills.edit')->with('periods', $periods)->with('bill', $bill)->with(
'subTitle', 'Edit "' . $bill->name . '"'
);
}
/**
* @return $this
*/
public function index()
{
$bills = $this->_repository->get();
return View::make('bills.index', compact('bills'));
}
/**
* @param Bill $bill
*
* @return mixed
*/
public function rescan(Bill $bill)
{
if (intval($bill->active) == 0) {
Session::flash('warning', 'Inactive bills cannot be scanned.');
return Redirect::intended('/');
}
$this->_repository->scanEverything($bill);
Session::flash('success', 'Rescanned everything.');
return Redirect::intended('/');
}
/**
* @param Bill $bill
*
* @return mixed
*/
public function show(Bill $bill)
{
$journals = $bill->transactionjournals()->withRelevantData()->orderBy('date', 'DESC')->get();
$hideBill = true;
return View::make('bills.show', compact('journals', 'hideBills'))->with('bill', $bill)->with(
'subTitle', $bill->name
);
}
/**
* @return $this
* @throws FireflyException
*/
public function store()
{
$data = Input::all();
$data['user_id'] = Auth::user()->id;
// always validate:
$messages = $this->_repository->validate($data);
// flash messages:
Session::flash('warnings', $messages['warnings']);
Session::flash('successes', $messages['successes']);
Session::flash('errors', $messages['errors']);
if ($messages['errors']->count() > 0) {
Session::flash('error', 'Could not store bill: ' . $messages['errors']->first());
}
// return to create screen:
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
return Redirect::route('bills.create')->withInput();
}
// store:
$this->_repository->store($data);
Session::flash('success', 'Bill "' . e($data['name']) . '" stored.');
if ($data['post_submit_action'] == 'store') {
return Redirect::route('bills.index');
}
return Redirect::route('bills.create')->withInput();
}
/**
* @param Bill $bill
*
* @return $this
* @throws FireflyException
*/
public function update(Bill $bill)
{
$data = Input::except('_token');
$data['active'] = isset($data['active']) ? 1 : 0;
$data['automatch'] = isset($data['automatch']) ? 1 : 0;
$data['user_id'] = Auth::user()->id;
// always validate:
$messages = $this->_repository->validate($data);
// flash messages:
Session::flash('warnings', $messages['warnings']);
Session::flash('successes', $messages['successes']);
Session::flash('errors', $messages['errors']);
if ($messages['errors']->count() > 0) {
Session::flash('error', 'Could not update bill: ' . $messages['errors']->first());
}
// return to update screen:
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
return Redirect::route('bills.edit', $bill->id)->withInput();
}
// update
$this->_repository->update($bill, $data);
Session::flash('success', 'Bill "' . e($data['name']) . '" updated.');
// go back to list
if ($data['post_submit_action'] == 'update') {
return Redirect::route('bills.index');
}
// go back to update screen.
return Redirect::route('bills.edit', $bill->id)->withInput(['post_submit_action' => 'return_to_edit']);
}
}

View File

@@ -334,11 +334,11 @@ class GoogleChartController extends BaseController
}
/**
* @param RecurringTransaction $recurring
* @param Bill $bill
*
* @return \Illuminate\Http\JsonResponse
*/
public function recurringOverview(RecurringTransaction $recurring)
public function billOverview(Bill $bill)
{
$this->_chart->addColumn('Date', 'date');
@@ -347,7 +347,7 @@ class GoogleChartController extends BaseController
$this->_chart->addColumn('Current entry', 'number');
// get first transaction or today for start:
$first = $recurring->transactionjournals()->orderBy('date', 'ASC')->first();
$first = $bill->transactionjournals()->orderBy('date', 'ASC')->first();
if ($first) {
$start = $first->date;
} else {
@@ -355,15 +355,15 @@ class GoogleChartController extends BaseController
}
$end = new Carbon;
while ($start <= $end) {
$result = $recurring->transactionjournals()->before($end)->after($start)->first();
$result = $bill->transactionjournals()->before($end)->after($start)->first();
if ($result) {
$amount = $result->getAmount();
} else {
$amount = 0;
}
unset($result);
$this->_chart->addRow(clone $start, $recurring->amount_max, $recurring->amount_min, $amount);
$start = DateKit::addPeriod($start, $recurring->repeat_freq, 0);
$this->_chart->addRow(clone $start, $bill->amount_max, $bill->amount_min, $amount);
$start = DateKit::addPeriod($start, $bill->repeat_freq, 0);
}
$this->_chart->generate();
@@ -378,14 +378,14 @@ class GoogleChartController extends BaseController
* @return \Illuminate\Http\JsonResponse
* @throws \FireflyIII\Exception\FireflyException
*/
public function recurringTransactionsOverview()
public function billsOverview()
{
$paid = ['items' => [], 'amount' => 0];
$unpaid = ['items' => [], 'amount' => 0];
$this->_chart->addColumn('Name', 'string');
$this->_chart->addColumn('Amount', 'number');
$set = $this->_repository->getRecurringSummary($this->_start, $this->_end);
$set = $this->_repository->getBillsSummary($this->_start, $this->_end);
foreach ($set as $entry) {
if (intval($entry->journalId) == 0) {

View File

@@ -1,205 +0,0 @@
<?php
use FireflyIII\Database\RecurringTransaction\RecurringTransaction as Repository;
use FireflyIII\Exception\FireflyException;
/**
*
* @SuppressWarnings("CamelCase") // I'm fine with this.
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
* @SuppressWarnings("NPathComplexity")
* Class RecurringController
*
*/
class RecurringController extends BaseController
{
/** @var Repository */
protected $_repository;
/**
* @param Repository $repository
*/
public function __construct(Repository $repository)
{
$this->_repository = $repository;
View::share('title', 'Recurring transactions');
View::share('mainTitleIcon', 'fa-rotate-right');
}
/**
* @return $this
*/
public function create()
{
$periods = \Config::get('firefly.periods_to_text');
return View::make('recurring.create')->with('periods', $periods)->with('subTitle', 'Create new');
}
/**
* @param RecurringTransaction $recurringTransaction
*
* @return $this
*/
public function delete(RecurringTransaction $recurringTransaction)
{
return View::make('recurring.delete')->with('recurringTransaction', $recurringTransaction)->with(
'subTitle', 'Delete "' . $recurringTransaction->name . '"'
);
}
/**
* @param RecurringTransaction $recurringTransaction
*
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(RecurringTransaction $recurringTransaction)
{
$this->_repository->destroy($recurringTransaction);
Session::flash('success', 'The recurring transaction was deleted.');
return Redirect::route('recurring.index');
}
/**
* @param RecurringTransaction $recurringTransaction
*
* @return $this
*/
public function edit(RecurringTransaction $recurringTransaction)
{
$periods = \Config::get('firefly.periods_to_text');
return View::make('recurring.edit')->with('periods', $periods)->with('recurringTransaction', $recurringTransaction)->with(
'subTitle', 'Edit "' . $recurringTransaction->name . '"'
);
}
/**
* @return $this
*/
public function index()
{
$recurring = $this->_repository->get();
return View::make('recurring.index', compact('recurring'));
}
/**
* @param RecurringTransaction $recurringTransaction
*
* @return mixed
*/
public function rescan(RecurringTransaction $recurringTransaction)
{
if (intval($recurringTransaction->active) == 0) {
Session::flash('warning', 'Inactive recurring transactions cannot be scanned.');
return Redirect::intended('/');
}
$this->_repository->scanEverything($recurringTransaction);
Session::flash('success', 'Rescanned everything.');
return Redirect::intended('/');
}
/**
* @param RecurringTransaction $recurringTransaction
*
* @return mixed
*/
public function show(RecurringTransaction $recurringTransaction)
{
$journals = $recurringTransaction->transactionjournals()->withRelevantData()->orderBy('date', 'DESC')->get();
$hideRecurring = true;
return View::make('recurring.show', compact('journals', 'hideRecurring'))->with('recurring', $recurringTransaction)->with(
'subTitle', $recurringTransaction->name
);
}
/**
* @return $this
* @throws FireflyException
*/
public function store()
{
$data = Input::all();
$data['user_id'] = Auth::user()->id;
// always validate:
$messages = $this->_repository->validate($data);
// flash messages:
Session::flash('warnings', $messages['warnings']);
Session::flash('successes', $messages['successes']);
Session::flash('errors', $messages['errors']);
if ($messages['errors']->count() > 0) {
Session::flash('error', 'Could not store recurring transaction: ' . $messages['errors']->first());
}
// return to create screen:
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
return Redirect::route('recurring.create')->withInput();
}
// store:
$this->_repository->store($data);
Session::flash('success', 'Recurring transaction "' . e($data['name']) . '" stored.');
if ($data['post_submit_action'] == 'store') {
return Redirect::route('recurring.index');
}
return Redirect::route('recurring.create')->withInput();
}
/**
* @param RecurringTransaction $recurringTransaction
*
* @return $this
* @throws FireflyException
*/
public function update(RecurringTransaction $recurringTransaction)
{
$data = Input::except('_token');
$data['active'] = isset($data['active']) ? 1 : 0;
$data['automatch'] = isset($data['automatch']) ? 1 : 0;
$data['user_id'] = Auth::user()->id;
// always validate:
$messages = $this->_repository->validate($data);
// flash messages:
Session::flash('warnings', $messages['warnings']);
Session::flash('successes', $messages['successes']);
Session::flash('errors', $messages['errors']);
if ($messages['errors']->count() > 0) {
Session::flash('error', 'Could not update recurring transaction: ' . $messages['errors']->first());
}
// return to update screen:
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
return Redirect::route('recurring.edit', $recurringTransaction->id)->withInput();
}
// update
$this->_repository->update($recurringTransaction, $data);
Session::flash('success', 'Recurring transaction "' . e($data['name']) . '" updated.');
// go back to list
if ($data['post_submit_action'] == 'update') {
return Redirect::route('recurring.index');
}
// go back to update screen.
return Redirect::route('recurring.edit', $recurringTransaction->id)->withInput(['post_submit_action' => 'return_to_edit']);
}
}

View File

@@ -1,7 +1,6 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\QueryException;
use Illuminate\Database\Schema\Blueprint;
/**
@@ -37,6 +36,51 @@ class ChangesForV322 extends Migration
$table->dropSoftDeletes();
}
);
// drop keys from bills (foreign bills_uid_for and unique uid_name_unique)
Schema::table(
'bills', function (Blueprint $table) {
$table->dropForeign('bills_uid_for');
$table->dropUnique('uid_name_unique');
}
);
// drop foreign key from transaction_journals (bill_id_foreign)
Schema::table(
'transaction_journals', function (Blueprint $table) {
$table->dropForeign('bill_id_foreign');
}
);
// drop foreign key from budget_limits:
Schema::table(
'budget_limits', function (Blueprint $table) {
$table->dropForeign('bid_foreign');
$table->dropUnique('unique_bl_combi');
}
);
// rename bills to recurring_transactions
Schema::rename('bills', 'recurring_transactions');
// recreate foreign key recurring_transactions_user_id_foreign in recurring_transactions
// recreate unique recurring_transactions_user_id_name_unique in recurring_transactions
Schema::table(
'recurring_transactions', function (Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unique(['user_id', 'name']);
}
);
// rename bill_id to recurring_transaction_id
// recreate foreign transaction_journals_recurring_transaction_id_foreign in transaction_journals
Schema::table(
'transaction_journals', function (Blueprint $table) {
$table->renameColumn('bill_id', 'recurring_transaction_id');
$table->foreign('recurring_transaction_id')->references('id')->on('recurring_transactions')->onDelete('set null');
}
);
}
@@ -55,13 +99,13 @@ class ChangesForV322 extends Migration
Schema::table(
'budget_limits', function (Blueprint $table) {
// try {
//$table->dropUnique('limits_component_id_startdate_repeat_freq_unique');
// } catch (QueryException $e) {
//$table->dropUnique('unique_ci_combi');
// } catch (PDOException $e) {
// $table->dropUnique('unique_ci_combi');
// }
// try {
//$table->dropUnique('limits_component_id_startdate_repeat_freq_unique');
// } catch (QueryException $e) {
//$table->dropUnique('unique_ci_combi');
// } catch (PDOException $e) {
// $table->dropUnique('unique_ci_combi');
// }
}
);
@@ -91,6 +135,48 @@ class ChangesForV322 extends Migration
$table->softDeletes();
}
);
// rename everything related to recurring transactions, aka bills:
Schema::table(
'transaction_journals', function (Blueprint $table) {
// drop relation
$table->dropForeign('transaction_journals_recurring_transaction_id_foreign');
// rename column
$table->renameColumn('recurring_transaction_id', 'bill_id');
}
);
Schema::table(
'recurring_transactions', function (Blueprint $table) {
$table->dropForeign('recurring_transactions_user_id_foreign');
$table->dropUnique('recurring_transactions_user_id_name_unique');
}
);
// rename table:
Schema::rename('recurring_transactions', 'bills');
// recreate foreign relation:
Schema::table(
'transaction_journals', function (Blueprint $table) {
$table->foreign('bill_id', 'bill_id_foreign')->references('id')->on('bills')->onDelete('set null');
}
);
// recreate more foreign relations.
Schema::table(
'bills', function (Blueprint $table) {
// connect user id to users
$table->foreign('user_id', 'bills_uid_for')->references('id')->on('users')->onDelete('cascade');
// for a user, the name must be unique
$table->unique(['user_id', 'name'], 'uid_name_unique');
}
);
}
}

View File

@@ -36,19 +36,19 @@ class TestContentSeeder extends Seeder
$deleteBudget = Budget::create(['user_id' => $user->id, 'name' => 'Delete me']);
// some limits:
$startDate = Carbon::now()->startOfMonth();
$endDate = Carbon::now()->endOfMonth();
$startDate = Carbon::now()->startOfMonth();
$endDate = Carbon::now()->endOfMonth();
$secondStart = Carbon::now()->subMonth()->startOfMonth();
$secondEnd = Carbon::now()->subMonth()->endOfMonth();
$limitOne = BudgetLimit::create(
$secondEnd = Carbon::now()->subMonth()->endOfMonth();
$limitOne = BudgetLimit::create(
['startdate' => $startDate->format('Y-m-d'), 'amount' => 201, 'repeats' => 0, 'repeat_freq' => 'monthly',
'budget_id' => $groceriesBudget->id]
);
$limitTwo = BudgetLimit::create(
$limitTwo = BudgetLimit::create(
['startdate' => $secondStart->format('Y-m-d'), 'amount' => 202, 'repeats' => 0, 'repeat_freq' => 'monthly',
'budget_id' => $billsBudget->id]
);
$limitThree = BudgetLimit::create(
$limitThree = BudgetLimit::create(
['startdate' => '2014-01-01', 'amount' => 203, 'repeats' => 0, 'repeat_freq' => 'monthly',
'budget_id' => $deleteBudget->id]
);
@@ -58,7 +58,8 @@ class TestContentSeeder extends Seeder
['budget_limit_id' => $limitOne->id, 'startdate' => $startDate->format('Y-m-d'), 'enddate' => $endDate->format('Y-m-d'), 'amount' => 201]
);
$repTwo = LimitRepetition::create(
['budget_limit_id' => $limitTwo->id, 'startdate' => $secondStart->format('Y-m-d'), 'enddate' => $secondEnd->format('Y-m-d'), 'amount' => 202]
['budget_limit_id' => $limitTwo->id, 'startdate' => $secondStart->format('Y-m-d'), 'enddate' => $secondEnd->format('Y-m-d'),
'amount' => 202]
);
$repThree = LimitRepetition::create(
['budget_limit_id' => $limitThree->id, 'startdate' => '2014-01-01', 'enddate' => '2014-01-31', 'amount' => 203]
@@ -79,7 +80,7 @@ class TestContentSeeder extends Seeder
Component::create(['user_id' => $user->id, 'name' => 'Some Component 7', 'class' => 'Category']);
// piggy bank
$piggy = PiggyBank::create(
$piggy = PiggyBank::create(
[
'account_id' => $savings->id,
'name' => 'New camera',
@@ -99,7 +100,7 @@ class TestContentSeeder extends Seeder
PiggyBankEvent::create(['piggy_bank_id' => 1, 'date' => $startDate->format('Y-m-d'), 'amount' => 100]);
PiggyBankRepetition::create(
[
'piggy_bank_id' => $piggy->id,
'piggy_bank_id' => $piggy->id,
'startdate' => Carbon::now()->format('Y-m-d'),
'targetdate' => null,
'currentamount' => 0
@@ -107,7 +108,7 @@ class TestContentSeeder extends Seeder
);
// piggy bank
$piggyTargeted = PiggyBank::create(
$piggyTargeted = PiggyBank::create(
[
'account_id' => $savings->id,
'name' => 'New clothes',
@@ -128,15 +129,15 @@ class TestContentSeeder extends Seeder
PiggyBankEvent::create(['piggy_bank_id' => $piggyTargeted->id, 'date' => $startDate->format('Y-m-d'), 'amount' => 100]);
PiggyBankRepetition::create(
[
'piggy_bank_id' => $piggyTargeted->id,
'piggy_bank_id' => $piggyTargeted->id,
'startdate' => Carbon::now()->format('Y-m-d'),
'targetdate' => Carbon::now()->addMonths(4)->format('Y-m-d'),
'currentamount' => 0
]
);
// recurring transaction
$recurring = \RecurringTransaction::create(
// bill
$firstBill = \Bill::create(
[
'user_id' => $user->id,
'name' => 'Huur',
@@ -151,8 +152,8 @@ class TestContentSeeder extends Seeder
]
);
// recurring transaction
$secondRecurring = \RecurringTransaction::create(
// bill
$secondBill = \Bill::create(
[
'user_id' => $user->id,
'name' => 'Gas licht',
@@ -198,7 +199,7 @@ class TestContentSeeder extends Seeder
while ($start <= $end) {
$this->createTransaction(
$checking, $portaal, 500, $withdrawal, 'Huur Portaal for ' . $start->format('F Y'), $start->format('Y-m-') . '01', $billsBudget, $house,
$recurring
$firstBill
);
$this->createTransaction(
$checking, $vitens, 12, $withdrawal, 'Water for ' . $start->format('F Y'), $start->format('Y-m-') . '02', $billsBudget, $house
@@ -261,28 +262,27 @@ class TestContentSeeder extends Seeder
*
* @param Budget $budget
* @param Category $category
* @param RecurringTransaction $recurring
* @param Bill $bill
*
* @return TransactionJournal
*/
public function createTransaction(
Account $from, Account $to, $amount, TransactionType $type, $description, $date, Budget $budget = null, Category $category = null,
$recurring = null
Account $from, Account $to, $amount, TransactionType $type, $description, $date, Budget $budget = null, Category $category = null, Bill $bill = null
) {
$user = User::whereEmail('thegrumpydictator@gmail.com')->first();
$euro = TransactionCurrency::whereCode('EUR')->first();
$recurringID = is_null($recurring) ? null : $recurring->id;
$user = User::whereEmail('thegrumpydictator@gmail.com')->first();
$euro = TransactionCurrency::whereCode('EUR')->first();
$billID = is_null($bill) ? null : $bill->id;
/** @var TransactionJournal $journal */
$journal = TransactionJournal::create(
[
'user_id' => $user->id,
'transaction_type_id' => $type->id,
'transaction_currency_id' => $euro->id,
'recurring_transaction_id' => $recurringID,
'description' => $description,
'completed' => 1,
'date' => $date
'user_id' => $user->id,
'transaction_type_id' => $type->id,
'transaction_currency_id' => $euro->id,
'bill_id' => $billID,
'description' => $description,
'completed' => 1,
'date' => $date
]
);

View File

@@ -48,12 +48,12 @@ class Chart implements ChartInterface
*
* @return Collection
*/
public function getRecurringSummary(Carbon $start, Carbon $end)
public function getBillsSummary(Carbon $start, Carbon $end)
{
return \RecurringTransaction::
return \Bill::
leftJoin(
'transaction_journals', function (JoinClause $join) use ($start, $end) {
$join->on('recurring_transactions.id', '=', 'transaction_journals.recurring_transaction_id')
$join->on('bills.id', '=', 'transaction_journals.bill_id')
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'));
}
@@ -64,11 +64,11 @@ class Chart implements ChartInterface
}
)
->where('active', 1)
->groupBy('recurring_transactions.id')
->groupBy('bills.id')
->get(
['recurring_transactions.id', 'recurring_transactions.name', 'transaction_journals.description',
['bills.id', 'bills.name', 'transaction_journals.description',
'transaction_journals.id as journalId',
\DB::Raw('SUM(`recurring_transactions`.`amount_min` + `recurring_transactions`.`amount_max`) / 2 as `averageAmount`'),
\DB::Raw('SUM(`bills`.`amount_min` + `bills`.`amount_max`) / 2 as `averageAmount`'),
'transactions.amount AS actualAmount']
);
}

View File

@@ -26,6 +26,6 @@ interface ChartInterface
*
* @return Collection
*/
public function getRecurringSummary(Carbon $start, Carbon $end);
public function getBillsSummary(Carbon $start, Carbon $end);
}

View File

@@ -1,6 +1,6 @@
<?php
namespace FireflyIII\Database\RecurringTransaction;
namespace FireflyIII\Database\Bill;
use Carbon\Carbon;
@@ -13,11 +13,11 @@ use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag;
/**
* Class Recurring
* Class Bill
*
* @package FireflyIII\Database
*/
class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransactionInterface
class Bill implements CUD, CommonDatabaseCalls, BillInterface
{
use SwitchUser;
@@ -48,30 +48,30 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
*/
public function store(array $data)
{
$recurring = new \RecurringTransaction;
$recurring->user()->associate($this->getUser());
$recurring->name = $data['name'];
$recurring->match = $data['match'];
$recurring->amount_max = floatval($data['amount_max']);
$recurring->amount_min = floatval($data['amount_min']);
$bill = new \Bill;
$bill->user()->associate($this->getUser());
$bill->name = $data['name'];
$bill->match = $data['match'];
$bill->amount_max = floatval($data['amount_max']);
$bill->amount_min = floatval($data['amount_min']);
$date = new Carbon($data['date']);
$recurring->active = intval($data['active']);
$recurring->automatch = intval($data['automatch']);
$recurring->repeat_freq = $data['repeat_freq'];
$bill->active = intval($data['active']);
$bill->automatch = intval($data['automatch']);
$bill->repeat_freq = $data['repeat_freq'];
/*
* Jump to the start of the period.
*/
$date = \DateKit::startOfPeriod($date, $data['repeat_freq']);
$recurring->date = $date;
$recurring->skip = intval($data['skip']);
$bill->date = $date;
$bill->skip = intval($data['skip']);
$recurring->save();
$bill->save();
return $recurring;
return $bill;
}
/**
@@ -118,7 +118,7 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
$errors->add('amount_max', 'Maximum amount can not be less than minimum amount.');
$errors->add('amount_min', 'Minimum amount can not be more than maximum amount.');
}
$object = new \RecurringTransaction($model);
$object = new \Bill($model);
$object->isValid();
$errors->merge($object->getErrors());
@@ -167,7 +167,7 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
*/
public function get()
{
return $this->getUser()->recurringtransactions()->get();
return $this->getUser()->bills()->get();
}
/**
@@ -189,35 +189,35 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
*/
public function getActive()
{
return $this->getUser()->recurringtransactions()->where('active', 1)->get();
return $this->getUser()->bills()->where('active', 1)->get();
}
/**
* @param \RecurringTransaction $recurring
* @param \Bill $bill
* @param Carbon $start
* @param Carbon $end
*
* @return \TransactionJournal|null
*/
public function getJournalForRecurringInRange(\RecurringTransaction $recurring, Carbon $start, Carbon $end)
public function getJournalForBillInRange(\Bill $bill, Carbon $start, Carbon $end)
{
return $this->getUser()->transactionjournals()->where('recurring_transaction_id', $recurring->id)->after($start)->before($end)->first();
return $this->getUser()->transactionjournals()->where('bill_id', $bill->id)->after($start)->before($end)->first();
}
/**
* @param \RecurringTransaction $recurring
* @param \Bill $bill
* @param \TransactionJournal $journal
*
* @return bool
*/
public function scan(\RecurringTransaction $recurring, \TransactionJournal $journal)
public function scan(\Bill $bill, \TransactionJournal $journal)
{
/*
* Match words.
*/
$wordMatch = false;
$matches = explode(',', $recurring->match);
$matches = explode(',', $bill->match);
$description = strtolower($journal->description);
/*
@@ -261,8 +261,8 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
if (count($transactions) > 1) {
$amount = max(floatval($transactions[0]->amount), floatval($transactions[1]->amount));
$min = floatval($recurring->amount_min);
$max = floatval($recurring->amount_max);
$min = floatval($bill->amount_min);
$max = floatval($bill->amount_max);
if ($amount >= $min && $amount <= $max) {
$amountMatch = true;
\Log::debug('Amount match is true!');
@@ -273,17 +273,17 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
* If both, update!
*/
if ($wordMatch && $amountMatch) {
$journal->recurringTransaction()->associate($recurring);
$journal->bill()->associate($bill);
$journal->save();
}
}
/**
* @param \RecurringTransaction $recurring
* @param \Bill $bill
*
* @return bool
*/
public function scanEverything(\RecurringTransaction $recurring)
public function scanEverything(\Bill $bill)
{
// get all journals that (may) be relevant.
// this is usually almost all of them.
@@ -291,7 +291,7 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $journalRepository */
$journalRepository = \App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
$set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $recurring->amount_min)->where('amount', '<=', $recurring->amount_max)
$set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)
->get(['transaction_journal_id']);
$ids = [];
@@ -303,7 +303,7 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
$journals = $journalRepository->getByIds($ids);
/** @var \TransactionJournal $journal */
foreach ($journals as $journal) {
$this->scan($recurring, $journal);
$this->scan($bill, $journal);
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace FireflyIII\Database\Bill;
use Carbon\Carbon;
/**
* Interface BillInterface
*
* @package FireflyIII\Database
*/
interface BillInterface
{
/**
* @param \Bill $bill
* @param Carbon $start
* @param Carbon $end
*
* @return null|\TransactionJournal
* @internal param Carbon $current
* @internal param Carbon $currentEnd
*
*/
public function getJournalForBillInRange(\Bill $bill, Carbon $start, Carbon $end);
/**
* @param \Bill $bill
* @param \TransactionJournal $journal
*
* @return bool
*/
public function scan(\Bill $bill, \TransactionJournal $journal);
/**
* @param \Bill $bill
*
* @return bool
*/
public function scanEverything(\Bill $bill);
}

View File

@@ -1,41 +0,0 @@
<?php
namespace FireflyIII\Database\RecurringTransaction;
use Carbon\Carbon;
/**
* Interface RecurringInterface
*
* @package FireflyIII\Database
*/
interface RecurringTransactionInterface
{
/**
* @param \RecurringTransaction $recurring
* @param Carbon $start
* @param Carbon $end
*
* @return null|\TransactionJournal
* @internal param Carbon $current
* @internal param Carbon $currentEnd
*
*/
public function getJournalForRecurringInRange(\RecurringTransaction $recurring, Carbon $start, Carbon $end);
/**
* @param \RecurringTransaction $recurring
* @param \TransactionJournal $journal
*
* @return bool
*/
public function scan(\RecurringTransaction $recurring, \TransactionJournal $journal);
/**
* @param \RecurringTransaction $recurring
*
* @return bool
*/
public function scanEverything(\RecurringTransaction $recurring);
}

View File

@@ -153,8 +153,8 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
if (!isset($model['what'])) {
$errors->add('description', 'Internal error: need to know type of transaction!');
}
if (isset($model['recurring_transaction_id']) && intval($model['recurring_transaction_id']) < 0) {
$errors->add('recurring_transaction_id', 'Recurring transaction is invalid.');
if (isset($model['bill_id']) && intval($model['bill_id']) < 0) {
$errors->add('bill_id', 'Bill is invalid.');
}
if (!isset($model['description'])) {
$errors->add('description', 'This field is mandatory.');

View File

@@ -17,12 +17,12 @@ class TransactionJournal
*/
public function store(\TransactionJournal $journal)
{
/** @var \FireflyIII\Database\RecurringTransaction\RecurringTransaction $repository */
$repository = \App::make('FireflyIII\Database\RecurringTransaction\RecurringTransaction');
/** @var \FireflyIII\Database\Bill\Bill $repository */
$repository = \App::make('FireflyIII\Database\Bill\Bill');
$set = $repository->get();
/** @var \RecurringTransaction $entry */
/** @var \Bill $entry */
foreach ($set as $entry) {
$repository->scan($entry, $journal);
}
@@ -43,13 +43,13 @@ class TransactionJournal
*/
public function update(\TransactionJournal $journal)
{
/** @var \FireflyIII\Database\RecurringTransaction\RecurringTransaction $repository */
$repository = \App::make('FireflyIII\Database\RecurringTransaction\RecurringTransaction');
/** @var \FireflyIII\Database\Bill\Bill $repository */
$repository = \App::make('FireflyIII\Database\Bill\Bill');
$set = $repository->get();
$journal->recurring_transaction_id = null;
$journal->bill_id = null;
$journal->save();
/** @var \RecurringTransaction $entry */
/** @var \Bill $entry */
foreach ($set as $entry) {
$repository->scan($entry, $journal);
}

View File

@@ -3,9 +3,9 @@ use Carbon\Carbon;
use Watson\Validating\ValidatingTrait;
use \Illuminate\Database\Eloquent\Model as Eloquent;
/**
* Class RecurringTransaction
* Class Bill
*/
class RecurringTransaction extends Eloquent
class Bill extends Eloquent
{
use ValidatingTrait;
@@ -57,8 +57,7 @@ class RecurringTransaction extends Eloquent
/**
* TODO remove this method in favour of something in the FireflyIII libraries.
*
* Find the next expected match based on the set journals and the date stuff from the recurring
* transaction.
* Find the next expected match based on the set journals and the date stuff from the bill.
*/
public function nextExpectedMatch()
{
@@ -78,18 +77,15 @@ class RecurringTransaction extends Eloquent
$today = DateKit::addPeriod(new Carbon, $this->repeat_freq, 0);
/*
* FF3 loops from the $start of the recurring transaction, and to make sure
* FF3 loops from the $start of the bill, and to make sure
* $skip works, it adds one (for modulo).
*/
$skip = $this->skip + 1;
$start = DateKit::startOfPeriod(new Carbon, $this->repeat_freq);
/*
* go back exactly one month/week/etc because FF3 does not care about 'next'
* recurring transactions if they're too far into the past.
* bills if they're too far into the past.
*/
// echo 'Repeat freq is: ' . $recurringTransaction->repeat_freq . '<br />';
// echo 'Start: ' . $start . ' <br />';
$counter = 0;
while ($start <= $today) {

View File

@@ -85,9 +85,9 @@ class TransactionJournal extends Eloquent
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function recurringTransaction()
public function bill()
{
return $this->belongsTo('RecurringTransaction');
return $this->belongsTo('Bill');
}
/**
@@ -202,7 +202,7 @@ class TransactionJournal extends Eloquent
$query->with(
['transactions' => function ($q) {
$q->orderBy('amount', 'ASC');
}, 'transactiontype', 'budgets','categories', 'transactions.account.accounttype', 'recurringTransaction', 'budgets', 'categories']
}, 'transactiontype', 'budgets','categories', 'transactions.account.accounttype', 'bill', 'budgets', 'categories']
);
}

View File

@@ -69,9 +69,9 @@ class User extends Eloquent implements UserInterface, RemindableInterface
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function recurringtransactions()
public function bills()
{
return $this->hasMany('RecurringTransaction');
return $this->hasMany('Bill');
}
/**

View File

@@ -34,9 +34,9 @@ Route::bind(
Route::bind(
'recurring', function ($value, $route) {
'bill', function ($value, $route) {
if (Auth::check()) {
return RecurringTransaction::
return Bill::
where('id', $value)->where('user_id', Auth::user()->id)->first();
}
@@ -192,11 +192,11 @@ Route::group(
Route::get('/chart/home/account', ['uses' => 'GoogleChartController@allAccountsBalanceChart']);
Route::get('/chart/home/budgets', ['uses' => 'GoogleChartController@allBudgetsHomeChart']);
Route::get('/chart/home/categories', ['uses' => 'GoogleChartController@allCategoriesHomeChart']);
Route::get('/chart/home/recurring', ['uses' => 'GoogleChartController@recurringTransactionsOverview']);
Route::get('/chart/home/bills', ['uses' => 'GoogleChartController@billsOverview']);
Route::get('/chart/account/{account}/{view?}', ['uses' => 'GoogleChartController@accountBalanceChart']);
Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']);
Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']);
Route::get('/chart/recurring/{recurring}', ['uses' => 'GoogleChartController@recurringOverview']);
Route::get('/chart/bills/{bill}', ['uses' => 'GoogleChartController@billOverview']);
Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']);
Route::get('/chart/piggy_history/{piggy_bank}', ['uses' => 'GoogleChartController@piggyBankHistory']);
@@ -234,13 +234,13 @@ Route::group(
Route::get('/profile', ['uses' => 'ProfileController@index', 'as' => 'profile']);
Route::get('/profile/change-password', ['uses' => 'ProfileController@changePassword', 'as' => 'change-password']);
// recurring transactions controller
Route::get('/recurring', ['uses' => 'RecurringController@index', 'as' => 'recurring.index']);
Route::get('/recurring/rescan/{recurring}', ['uses' => 'RecurringController@rescan', 'as' => 'recurring.rescan']); # rescan for matching.
Route::get('/recurring/create', ['uses' => 'RecurringController@create', 'as' => 'recurring.create']);
Route::get('/recurring/edit/{recurring}', ['uses' => 'RecurringController@edit', 'as' => 'recurring.edit']);
Route::get('/recurring/delete/{recurring}', ['uses' => 'RecurringController@delete', 'as' => 'recurring.delete']);
Route::get('/recurring/show/{recurring}', ['uses' => 'RecurringController@show', 'as' => 'recurring.show']);
// bills controller
Route::get('/bills', ['uses' => 'BillController@index', 'as' => 'bills.index']);
Route::get('/bills/rescan/{bill}', ['uses' => 'BillController@rescan', 'as' => 'bills.rescan']); # rescan for matching.
Route::get('/bills/create', ['uses' => 'BillController@create', 'as' => 'bills.create']);
Route::get('/bills/edit/{bill}', ['uses' => 'BillController@edit', 'as' => 'bills.edit']);
Route::get('/bills/delete/{bill}', ['uses' => 'BillController@delete', 'as' => 'bills.delete']);
Route::get('/bills/show/{bill}', ['uses' => 'BillController@show', 'as' => 'bills.show']);
// repeated expenses controller:
Route::get('/repeatedexpenses', ['uses' => 'RepeatedExpenseController@index', 'as' => 'repeated.index']);
@@ -328,10 +328,10 @@ Route::group(
// profile controller
Route::post('/profile/change-password', ['uses' => 'ProfileController@postChangePassword']);
// recurring controller
Route::post('/recurring/store', ['uses' => 'RecurringController@store', 'as' => 'recurring.store']);
Route::post('/recurring/update/{recurring}', ['uses' => 'RecurringController@update', 'as' => 'recurring.update']);
Route::post('/recurring/destroy/{recurring}', ['uses' => 'RecurringController@destroy', 'as' => 'recurring.destroy']);
// bills controller
Route::post('/bills/store', ['uses' => 'BillController@store', 'as' => 'bills.store']);
Route::post('/bills/update/{bill}', ['uses' => 'BillController@update', 'as' => 'bills.update']);
Route::post('/bills/destroy/{bill}', ['uses' => 'BillController@destroy', 'as' => 'bills.destroy']);
// transaction controller:
Route::post('/transactions/store/{what}', ['uses' => 'TransactionController@store', 'as' => 'transactions.store'])->where(

View File

@@ -1,7 +1,7 @@
@extends('layouts.default')
@section('content')
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName()) }}
{{Form::open(['class' => 'form-horizontal','id' => 'store','url' => route('recurring.store')])}}
{{Form::open(['class' => 'form-horizontal','id' => 'store','url' => route('bills.store')])}}
<div class="row">
<div class="col-lg-6 col-md-12 col-sm-6">
@@ -21,7 +21,7 @@
</div>
<p>
<button type="submit" class="btn btn-lg btn-success">
<i class="fa fa-plus-circle"></i> Store new recurring transaction
<i class="fa fa-plus-circle"></i> Store new bill
</button>
</p>
</div>
@@ -44,7 +44,7 @@
<i class="fa fa-bolt"></i> Options
</div>
<div class="panel-body">
{{Form::ffOptionsList('create','recurring transaction')}}
{{Form::ffOptionsList('create','bill')}}
</div>
</div>

View File

@@ -1,12 +1,12 @@
@extends('layouts.default')
@section('content')
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $recurringTransaction) }}
{{Form::open(['class' => 'form-horizontal','id' => 'destroy','url' => route('recurring.destroy',$recurringTransaction->id)])}}
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $bill) }}
{{Form::open(['class' => 'form-horizontal','id' => 'destroy','url' => route('bills.destroy',$bill->id)])}}
<div class="row">
<div class="col-lg-6 col-md-12 col-sm-12">
<div class="panel panel-red">
<div class="panel-heading">
Delete recurring transaction "{{{$recurringTransaction->name}}}"
Delete bill "{{{$bill->name}}}"
</div>
<div class="panel-body">
<p>

View File

@@ -1,7 +1,7 @@
@extends('layouts.default')
@section('content')
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $recurringTransaction) }}
{{Form::model($recurringTransaction, ['class' => 'form-horizontal','id' => 'update','url' => route('recurring.update', $recurringTransaction->id)])}}
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $bill) }}
{{Form::model($bill, ['class' => 'form-horizontal','id' => 'update','url' => route('bills.update', $bill->id)])}}
<div class="row">
<div class="col-lg-6 col-md-12 col-sm-6">
@@ -15,14 +15,14 @@
{{Form::ffTags('match')}}
{{Form::ffAmount('amount_min')}}
{{Form::ffAmount('amount_max')}}
{{Form::ffDate('date',$recurringTransaction->date->format('Y-m-d'))}}
{{Form::ffDate('date',$bill->date->format('Y-m-d'))}}
{{Form::ffSelect('repeat_freq',$periods)}}
</div>
</div>
<p>
<button type="submit" class="btn btn-lg btn-success">
<i class="fa fa-plus-circle"></i> Update recurring transaction
<i class="fa fa-plus-circle"></i> Update bill
</button>
</p>
</div>
@@ -44,7 +44,7 @@
<i class="fa fa-bolt"></i> Options
</div>
<div class="panel-body">
{{Form::ffOptionsList('update','recurring transaction')}}
{{Form::ffOptionsList('update','bill')}}
</div>
</div>

View File

@@ -9,7 +9,7 @@
<!-- TODO add menu -->
</div>
<div class="panel-body">
@include('list.recurring')
@include('list.bills')
</div>
</div>
</div>

View File

@@ -1,19 +1,19 @@
@extends('layouts.default')
@section('content')
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $recurring) }}
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $bill) }}
<div class="row">
<div class="col-lg-6 col-sm-12 col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-rotate-right"></i> {{{$recurring->name}}}
<i class="fa fa-rotate-right"></i> {{{$bill->name}}}
@if($recurring->active)
@if($bill->active)
<span class="glyphicon glyphicon-ok" title="Active"></span>
@else
<span class="glyphicon glyphicon-remove" title="Inactive"></span>
@endif
@if($recurring->automatch)
@if($bill->automatch)
<span class="glyphicon glyphicon-ok" title="Automatically matched by Firefly"></span>
@else
<span class="glyphicon glyphicon-remove" title="Not automatically matched by Firefly"></span>
@@ -27,8 +27,8 @@
<span class="caret"></span>
</button>
<ul class="dropdown-menu pull-right" role="menu">
<li><a href="{{route('recurring.edit',$recurring->id)}}"><span class="glyphicon glyphicon-pencil"></span> edit</a></li>
<li><a href="{{route('recurring.delete',$recurring->id)}}"><span class="glyphicon glyphicon-trash"></span> delete</a></li>
<li><a href="{{route('bills.edit',$bill->id)}}"><span class="glyphicon glyphicon-pencil"></span> edit</a></li>
<li><a href="{{route('bills.delete',$bill->id)}}"><span class="glyphicon glyphicon-trash"></span> delete</a></li>
</ul>
</div>
</div>
@@ -39,17 +39,17 @@
<tr>
<td colspan="2">
Matching on
@foreach(explode(',',$recurring->match) as $word)
@foreach(explode(',',$bill->match) as $word)
<span class="label label-info">{{{$word}}}</span>
@endforeach
between {{mf($recurring->amount_min)}} and {{mf($recurring->amount_max)}}.
Repeats {{$recurring->repeat_freq}}.</td>
between {{mf($bill->amount_min)}} and {{mf($bill->amount_max)}}.
Repeats {{$bill->repeat_freq}}.</td>
</tr>
<tr>
<td>Next expected match</td>
<td>
<?php $nextExpectedMatch = $recurring->nextExpectedMatch();?>
<?php $nextExpectedMatch = $bill->nextExpectedMatch();?>
@if($nextExpectedMatch)
{{$nextExpectedMatch->format('j F Y')}}
@else
@@ -68,7 +68,7 @@
</div>
<div class="panel-body">
<p>
<a href="{{route('recurring.rescan',$recurring->id)}}" class="btn btn-default">Rescan old transactions</a>
<a href="{{route('bills.rescan',$bill->id)}}" class="btn btn-default">Rescan old transactions</a>
</p>
</div>
</div>
@@ -82,7 +82,7 @@
Chart
</div>
<div class="panel-body">
<div id="recurring-overview"></div>
<div id="bill-overview"></div>
</div>
</div>
</div>
@@ -105,7 +105,7 @@
@section('scripts')
<script type="text/javascript">
var recurringID = {{{$recurring->id}}};
var billID = {{{$bill->id}}};
var currencyCode = '{{getCurrencyCode()}}';
</script>
<!-- load the libraries and scripts necessary for Google Charts: -->
@@ -113,5 +113,5 @@
{{HTML::script('assets/javascript/firefly/gcharts.options.js')}}
{{HTML::script('assets/javascript/firefly/gcharts.js')}}
{{HTML::script('assets/javascript/firefly/recurring.js')}}
{{HTML::script('assets/javascript/firefly/bills.js')}}
@stop

View File

@@ -67,10 +67,10 @@
<!-- REMINDERS -->
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-line-chart"></i> Recurring transactions
<i class="fa fa-line-chart"></i> Bills
</div>
<div class="panel-body">
<div id="recurring-chart"></div>
<div id="bill-chart"></div>
</div>
</div>

View File

@@ -10,16 +10,16 @@
<th>Will be automatched</th>
<th>Repeats every</th>
</tr>
@foreach($recurring as $entry)
@foreach($bills as $entry)
<tr>
<td>
<div class="btn-group btn-group-xs">
<a href="{{route('recurring.edit',$entry->id)}}" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pencil"></span></a>
<a href="{{route('recurring.delete',$entry->id)}}" class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-trash"></span></a>
<a href="{{route('bills.edit',$entry->id)}}" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pencil"></span></a>
<a href="{{route('bills.delete',$entry->id)}}" class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-trash"></span></a>
</div>
</td>
<td>
<a href="{{route('recurring.show',$entry->id)}}" title="{{{$entry->name}}}">{{{$entry->name}}}</a>
<a href="{{route('bills.show',$entry->id)}}" title="{{{$entry->name}}}">{{{$entry->name}}}</a>
</td>
<td>
@foreach(explode(',',$entry->match) as $match)

View File

@@ -15,8 +15,8 @@
@if(!isset($hideCategory) || (isset($hideCategory) && $hideCategory=== false))
<th><i class="fa fa-bar-chart fa-fw" title="Category"></i></th>
@endif
@if(!isset($hideRecurring) || (isset($hideRecurring) && $hideRecurring=== false))
<th><i class="fa fa-fw fa-rotate-right" title="Recurring transaction"></i></th>
@if(!isset($hideBill) || (isset($hideBill) && $hideBill=== false))
<th><i class="fa fa-fw fa-rotate-right" title="Bill"></i></th>
@endif
</tr>
@foreach($journals as $journal)
@@ -100,10 +100,10 @@
@endif
</td>
@endif
@if(!isset($hideRecurring) || (isset($hideRecurring) && $hideRecurring=== false))
@if(!isset($hideBill) || (isset($hideBill) && $hideBill=== false))
<td>
@if($journal->recurringTransaction)
<a href="{{route('recurring.show',$journal->recurring_transaction_id)}}">{{{$journal->recurringTransaction->name}}}</a>
@if($journal->bill)
<a href="{{route('bills.show',$journal->bill_id)}}">{{{$journal->bill->name}}}</a>
@endif
</td>
@endif

View File

@@ -137,9 +137,9 @@
</li>
<?php
$isMM = !(strpos($r,'piggy_banks') === false) || !(strpos($r,'recurring') === false) | !(strpos($r,'repeated') === false);
$isMM = !(strpos($r,'piggy_banks') === false) || !(strpos($r,'bills') === false) | !(strpos($r,'repeated') === false);
$isPiggy = !(strpos($r,'piggy_banks') === false);
$isRec = !(strpos($r,'recurring') === false) && strpos($r,'recurring.create') === false;
$isBill = !(strpos($r,'bills') === false) && strpos($r,'bills.create') === false;
$isRep = !(strpos($r,'repeated') === false);
?>
<li @if($isMM)class="active"@endif>
@@ -149,7 +149,7 @@
<a @if($isPiggy)class="active"@endif href="{{route('piggy_banks.index')}}"><i class="fa fa-sort-amount-asc fa-fw"></i> Piggy banks</a>
</li>
<li>
<a @if($isRec)class="active"@endif href="{{route('recurring.index')}}"><i class="fa fa-rotate-right fa-fw"></i> Recurring transactions</a>
<a @if($isBill)class="active"@endif href="{{route('bills.index')}}"><i class="fa fa-rotate-right fa-fw"></i> Bills</a>
</li>
<li>
<a @if($isRep)class="active"@endif href="{{route('repeated.index')}}"><i class="fa fa-rotate-left fa-fw"></i> Repeated expenses</a>
@@ -162,7 +162,7 @@
$isWithdrawal = $r == 'transactions.create' && isset($what) && $what == 'withdrawal';
$isDeposit = $r == 'transactions.create' && isset($what) && $what == 'deposit';
$isTransfer = $r == 'transactions.create' && isset($what) && $what == 'transfer';
$isRecurring = $r == 'recurring.create';
$isBill = $r == 'bills.create';
?>
<li @if($creating)class="active"@endif>
<a href="#"><i class="fa fa-plus fa-fw"></i> Create new<span class="fa arrow"></span></a>
@@ -177,7 +177,7 @@
<a @if($isTransfer)class="active"@endif href="{{route('transactions.create','transfer')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfer</a>
</li>
<li>
<a @if($isRecurring)class="active"@endif href="{{route('recurring.create')}}"><i class="fa fa-rotate-right fa-fw"></i> Recurring transaction</a>
<a @if($isBill)class="active"@endif href="{{route('bills.create')}}"><i class="fa fa-rotate-right fa-fw"></i> Bills</a>
</li>
</ul>
<!-- /.nav-second-level -->

View File

@@ -181,7 +181,7 @@
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Recurring transactions</div>
<div class="panel-heading">Bills</div>
<div class="panel-body">Body</div>
</div>
</div>

View File

@@ -0,0 +1,7 @@
$(document).ready(function () {
if (typeof(googleComboChart) == 'function' && typeof(billID) != 'undefined') {
googleComboChart('chart/bills/' + billID, 'bill-overview');
}
}
);

View File

@@ -5,5 +5,5 @@ function drawChart() {
googleLineChart('chart/home/account', 'accounts-chart');
googleBarChart('chart/home/budgets','budgets-chart');
googleColumnChart('chart/home/categories','categories-chart');
googlePieChart('chart/home/recurring','recurring-chart')
googlePieChart('chart/home/bills','bills-chart')
}

View File

@@ -1,14 +0,0 @@
$(document).ready(function () {
if (typeof(googleTable) == 'function') {
googleTable('table/recurring', 'recurring-table');
if (typeof(recurringID) != 'undefined') {
googleTable('table/recurring/' + recurringID + '/transactions', 'transaction-table');
}
}
if (typeof(googleComboChart) == 'function' && typeof(recurringID) != 'undefined') {
googleComboChart('chart/recurring/' + recurringID, 'recurring-overview');
}
}
);

View File

@@ -1,9 +1,9 @@
<?php
/**
* Class RecurringControllerCest
* Class BillControllerCest
*/
class RecurringControllerCest
class BillControllerCest
{
/**
@@ -26,8 +26,8 @@ class RecurringControllerCest
*/
public function create(FunctionalTester $I)
{
$I->wantTo('create a recurring transaction');
$I->amOnPage('/recurring/create');
$I->wantTo('create a bill');
$I->amOnPage('/bills/create');
}
/**
@@ -35,8 +35,8 @@ class RecurringControllerCest
*/
public function delete(FunctionalTester $I)
{
$I->wantTo('delete a recurring transaction');
$I->amOnPage('/recurring/delete/1');
$I->wantTo('delete a bill');
$I->amOnPage('/bills/delete/1');
$I->see('Delete "Huur"');
}
@@ -45,11 +45,11 @@ class RecurringControllerCest
*/
public function destroy(FunctionalTester $I)
{
$I->wantTo('destroy a recurring transaction');
$I->amOnPage('/recurring/delete/1');
$I->wantTo('destroy a bill');
$I->amOnPage('/bills/delete/1');
$I->see('Delete "Huur"');
$I->submitForm('#destroy', []);
$I->see('The recurring transaction was deleted.');
$I->see('The bill was deleted.');
}
@@ -58,8 +58,8 @@ class RecurringControllerCest
*/
public function edit(FunctionalTester $I)
{
$I->wantTo('edit a recurring transaction');
$I->amOnPage('/recurring/edit/1');
$I->wantTo('edit a bill');
$I->amOnPage('/bills/edit/1');
}
@@ -69,8 +69,8 @@ class RecurringControllerCest
*/
public function index(FunctionalTester $I)
{
$I->wantTo('see all recurring transactions');
$I->amOnPage('/recurring');
$I->wantTo('see all bills');
$I->amOnPage('/bills');
}
/**
@@ -78,8 +78,8 @@ class RecurringControllerCest
*/
public function rescan(FunctionalTester $I)
{
$I->wantTo('rescan a recurring transaction');
$I->amOnPage('/recurring/rescan/1');
$I->wantTo('rescan a bill');
$I->amOnPage('/bills/rescan/1');
$I->see('Rescanned everything.');
}
@@ -88,9 +88,9 @@ class RecurringControllerCest
*/
public function rescanInactive(FunctionalTester $I)
{
$I->wantTo('rescan an inactive recurring transaction');
$I->amOnPage('/recurring/rescan/2');
$I->see('Inactive recurring transactions cannot be scanned.');
$I->wantTo('rescan an inactive bill');
$I->amOnPage('/bills/rescan/2');
$I->see('Inactive bills cannot be scanned.');
}
/**
@@ -98,8 +98,8 @@ class RecurringControllerCest
*/
public function show(FunctionalTester $I)
{
$I->wantTo('show a recurring transaction');
$I->amOnPage('/recurring/show/1');
$I->wantTo('show a bill');
$I->amOnPage('/bills/show/1');
$I->see('Huur');
}
@@ -108,11 +108,11 @@ class RecurringControllerCest
*/
public function store(FunctionalTester $I)
{
$I->wantTo('store a recurring transaction');
$I->amOnPage('/recurring/create');
$I->wantTo('store a bill');
$I->amOnPage('/bills/create');
$I->submitForm(
'#store', [
'name' => 'Some recurring',
'name' => 'Some bill',
'match' => 'one,two',
'amount_min' => 10,
'amount_max' => 20,
@@ -122,7 +122,7 @@ class RecurringControllerCest
'skip' => 0
]
);
$I->see('Recurring transaction &quot;Some recurring&quot; stored.');
$I->see('Bill &quot;Some bill&quot; stored.');
}
/**
@@ -130,11 +130,11 @@ class RecurringControllerCest
*/
public function storeFail(FunctionalTester $I)
{
$I->wantTo('store a recurring transaction and fail');
$I->amOnPage('/recurring/create');
$I->wantTo('store a bill and fail');
$I->amOnPage('/bills/create');
$I->submitForm(
'#store', [
'name' => 'Some recurring',
'name' => 'Some bill',
'match' => '',
'amount_min' => 10,
'amount_max' => 20,
@@ -143,17 +143,17 @@ class RecurringControllerCest
'skip' => 0
]
);
$I->dontSeeInDatabase('recurring_transactions', ['name' => 'Some recurring']);
$I->see('Could not store recurring transaction');
$I->dontSeeInDatabase('bills', ['name' => 'Some bill']);
$I->see('Could not store bill');
}
public function storeRecreate(FunctionalTester $I)
{
$I->wantTo('validate a recurring transaction and create another one');
$I->amOnPage('/recurring/create');
$I->wantTo('validate a bill and create another one');
$I->amOnPage('/bills/create');
$I->submitForm(
'#store', [
'name' => 'Some recurring',
'name' => 'Some bill',
'match' => 'one,two',
'amount_min' => 10,
'amount_max' => 20,
@@ -164,7 +164,7 @@ class RecurringControllerCest
]
);
$I->see('Recurring transaction &quot;Some recurring&quot; stored.');
$I->see('Bill &quot;Some bill&quot; stored.');
}
/**
@@ -172,11 +172,11 @@ class RecurringControllerCest
*/
public function storeValidate(FunctionalTester $I)
{
$I->wantTo('validate a recurring transaction');
$I->amOnPage('/recurring/create');
$I->wantTo('validate a bill');
$I->amOnPage('/bills/create');
$I->submitForm(
'#store', [
'name' => 'Some recurring',
'name' => 'Some bill',
'match' => 'one,two',
'amount_min' => 10,
'amount_max' => 20,
@@ -195,11 +195,11 @@ class RecurringControllerCest
*/
public function update(FunctionalTester $I)
{
$I->wantTo('update a recurring transaction');
$I->amOnPage('/recurring/edit/1');
$I->wantTo('update a bill');
$I->amOnPage('/bills/edit/1');
$I->submitForm(
'#update', [
'name' => 'Some recurring',
'name' => 'Some bill',
'match' => 'bla,bla',
'amount_min' => 10,
'amount_max' => 20,
@@ -208,7 +208,7 @@ class RecurringControllerCest
'skip' => 0
]
);
$I->see('Recurring transaction &quot;Some recurring&quot; updated.');
$I->see('Bill &quot;Some bill&quot; updated.');
}
/**
@@ -216,11 +216,11 @@ class RecurringControllerCest
*/
public function updateReturn(FunctionalTester $I)
{
$I->wantTo('update a recurring transaction and return to edit it');
$I->amOnPage('/recurring/edit/1');
$I->wantTo('update a bill and return to edit it');
$I->amOnPage('/bills/edit/1');
$I->submitForm(
'#update', [
'name' => 'Some recurring',
'name' => 'Some bill',
'match' => 'bla,bla',
'amount_min' => 10,
'amount_max' => 20,
@@ -230,7 +230,7 @@ class RecurringControllerCest
'skip' => 0
]
);
$I->see('Recurring transaction &quot;Some recurring&quot; updated.');
$I->see('Bill &quot;Some bill&quot; updated.');
}
/**
@@ -238,11 +238,11 @@ class RecurringControllerCest
*/
public function updateFail(FunctionalTester $I)
{
$I->wantTo('update a recurring transaction and fail');
$I->amOnPage('/recurring/edit/1');
$I->wantTo('update a bill and fail');
$I->amOnPage('/bills/edit/1');
$I->submitForm(
'#update', [
'name' => 'Some recurring',
'name' => 'Some bill',
'match' => '',
'amount_min' => 10,
'amount_max' => 20,
@@ -251,7 +251,7 @@ class RecurringControllerCest
'skip' => 0
]
);
$I->see('Could not update recurring transaction');
$I->see('Could not update bill');
}
}

View File

@@ -138,30 +138,30 @@ class GoogleChartControllerCest
/**
* @param FunctionalTester $I
*/
public function recurringOverview(FunctionalTester $I)
public function billOverview(FunctionalTester $I)
{
$I->wantTo('see the chart for the history of a recurring transaction');
$I->amOnPage('/chart/recurring/1');
$I->wantTo('see the chart for the history of a bill');
$I->amOnPage('/chart/bills/1');
$I->seeResponseCodeIs(200);
}
/**
* @param FunctionalTester $I
*/
public function emptyRecurringOverview(FunctionalTester $I)
public function emptyBillOverview(FunctionalTester $I)
{
$I->wantTo('see the chart for the history of an empty recurring transaction');
$I->amOnPage('/chart/recurring/2');
$I->wantTo('see the chart for the history of an empty bill');
$I->amOnPage('/chart/bills/2');
$I->seeResponseCodeIs(200);
}
/**
* @param FunctionalTester $I
*/
public function recurringTransactionsOverview(FunctionalTester $I)
public function billsOverview(FunctionalTester $I)
{
$I->wantTo('see the chart for which recurring transactions I have yet to pay');
$I->amOnPage('/chart/home/recurring');
$I->wantTo('see the chart for which bills I have yet to pay');
$I->amOnPage('/chart/home/bills');
$I->seeResponseCodeIs(200);
}