mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-05 12:12:18 +00:00
New code for bills.
This commit is contained in:
240
app/Http/Controllers/BillController.php
Normal file
240
app/Http/Controllers/BillController.php
Normal file
@@ -0,0 +1,240 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\BillFormRequest;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class BillController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class BillController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Bills');
|
||||
View::share('mainTitleIcon', 'fa-calendar-o');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$periods = \Config::get('firefly.periods_to_text');
|
||||
|
||||
return view('bills.create')->with('periods', $periods)->with('subTitle', 'Create new');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function delete(Bill $bill)
|
||||
{
|
||||
return view('bills.delete')->with('bill', $bill)->with('subTitle', 'Delete "' . e($bill->name) . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Bill $bill)
|
||||
{
|
||||
$bill->delete();
|
||||
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 "' . e($bill->name) . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BillRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(BillRepositoryInterface $repository)
|
||||
{
|
||||
$bills = Auth::user()->bills()->get();
|
||||
$bills->each(
|
||||
function (Bill $bill) use ($repository) {
|
||||
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill);
|
||||
$last = $bill->transactionjournals()->orderBy('date', 'DESC')->first();
|
||||
$bill->lastFoundMatch = null;
|
||||
if ($last) {
|
||||
$bill->lastFoundMatch = $last->date;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return View::make('bills.index', compact('bills'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rescan(Bill $bill, BillRepositoryInterface $repository)
|
||||
{
|
||||
if (intval($bill->active) == 0) {
|
||||
Session::flash('warning', 'Inactive bills cannot be scanned.');
|
||||
|
||||
return Redirect::intended('/');
|
||||
}
|
||||
|
||||
$set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)->get(['transaction_journal_id']);
|
||||
$ids = [];
|
||||
|
||||
/** @var Transaction $entry */
|
||||
foreach ($set as $entry) {
|
||||
$ids[] = intval($entry->transaction_journal_id);
|
||||
}
|
||||
if (count($ids) > 0) {
|
||||
$journals = Auth::user()->transactionjournals()->whereIn('id',$ids)->get();
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$repository->scan($bill, $journal);
|
||||
}
|
||||
}
|
||||
|
||||
Session::flash('success', 'Rescanned everything.');
|
||||
|
||||
return Redirect::to(URL::previous());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function show(Bill $bill, BillRepositoryInterface $repository)
|
||||
{
|
||||
$journals = $bill->transactionjournals()->withRelevantData()->orderBy('date', 'DESC')->get();
|
||||
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill);
|
||||
$hideBill = true;
|
||||
|
||||
|
||||
return View::make('bills.show', compact('journals', 'hideBill', 'bill'))->with('subTitle', e($bill->name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function store(BillFormRequest $request, BillRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
var_dump($request->all());
|
||||
|
||||
$billData = [
|
||||
'name' => $request->get('name'),
|
||||
'match' => $request->get('match'),
|
||||
'amount_min' => floatval($request->get('amount_min')),
|
||||
'amount_currency_id' => floatval($request->get('amount_currency_id')),
|
||||
'amount_max' => floatval($request->get('amount_max')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'user' => Auth::user()->id,
|
||||
'repeat_freq' => $request->get('repeat_freq'),
|
||||
'skip' => intval($request->get('skip')),
|
||||
'automatch' => intval($request->get('automatch')) === 1,
|
||||
'active' => intval($request->get('active')) === 1,
|
||||
];
|
||||
|
||||
$bill = $repository->store($billData);
|
||||
Session::flash('success', 'Bill "' . e($bill->name) . '" stored.');
|
||||
|
||||
return Redirect::route('bills.index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function update(Bill $bill, BillFormRequest $request, BillRepositoryInterface $repository)
|
||||
{
|
||||
$billData = [
|
||||
'name' => $request->get('name'),
|
||||
'match' => $request->get('match'),
|
||||
'amount_min' => floatval($request->get('amount_min')),
|
||||
'amount_currency_id' => floatval($request->get('amount_currency_id')),
|
||||
'amount_max' => floatval($request->get('amount_max')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'user' => Auth::user()->id,
|
||||
'repeat_freq' => $request->get('repeat_freq'),
|
||||
'skip' => intval($request->get('skip')),
|
||||
'automatch' => intval($request->get('automatch')) === 1,
|
||||
'active' => intval($request->get('active')) === 1,
|
||||
];
|
||||
|
||||
$bill = $repository->update($bill, $billData);
|
||||
|
||||
Session::flash('success', 'Bill "' . e($bill->name) . '" updated.');
|
||||
|
||||
return Redirect::route('bills.index');
|
||||
|
||||
|
||||
// $data = Input::except('_token');
|
||||
// $data['active'] = intval(Input::get('active'));
|
||||
// $data['automatch'] = intval(Input::get('automatch'));
|
||||
// $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 Redirect::route('bills.edit', $bill->id)->withInput();
|
||||
// }
|
||||
//
|
||||
// // return to update screen:
|
||||
// if ($data['post_submit_action'] == 'validate_only') {
|
||||
// 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']);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\CategoryFormRequest;
|
||||
use FireflyIII\Models\Category;
|
||||
@@ -55,6 +56,26 @@ class CategoryController extends Controller
|
||||
return view('categories.show', compact('category', 'journals', 'hideCategory'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function noCategory()
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->startOfMonth());
|
||||
$list = Auth::user()
|
||||
->transactionjournals()
|
||||
->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('category_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date')
|
||||
->get(['transaction_journals.*']);
|
||||
$subTitle = 'Transactions without a category in ' . $start->format('F Y');
|
||||
|
||||
return View::make('categories.noCategory', compact('list', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
|
@@ -12,6 +12,7 @@ use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
@@ -21,6 +22,7 @@ use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
use Steam;
|
||||
use Navigation;
|
||||
|
||||
/**
|
||||
* Class GoogleChartController
|
||||
@@ -73,6 +75,50 @@ class GoogleChartController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function billOverview(Bill $bill, GChart $chart)
|
||||
{
|
||||
|
||||
$chart->addColumn('Date', 'date');
|
||||
$chart->addColumn('Max amount', 'number');
|
||||
$chart->addColumn('Min amount', 'number');
|
||||
$chart->addColumn('Current entry', 'number');
|
||||
|
||||
// get first transaction or today for start:
|
||||
$first = $bill->transactionjournals()->orderBy('date', 'ASC')->first();
|
||||
if ($first) {
|
||||
$start = $first->date;
|
||||
} else {
|
||||
$start = new Carbon;
|
||||
}
|
||||
$end = new Carbon;
|
||||
while ($start <= $end) {
|
||||
$result = $bill->transactionjournals()->before($end)->after($start)->first();
|
||||
if ($result) {
|
||||
/** @var Transaction $tr */
|
||||
foreach($result->transactions()->get() as $tr) {
|
||||
if(floatval($tr->amount) > 0) {
|
||||
$amount = floatval($tr->amount);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$amount = 0;
|
||||
}
|
||||
unset($result);
|
||||
$chart->addRow(clone $start, $bill->amount_max, $bill->amount_min, $amount);
|
||||
$start = Navigation::addPeriod($start, $bill->repeat_freq, 0);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
|
@@ -67,4 +67,6 @@ class PiggyBankController extends Controller {
|
||||
return view('piggy-banks.index', compact('piggyBanks', 'accounts'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
55
app/Http/Requests/BillFormRequest.php
Normal file
55
app/Http/Requests/BillFormRequest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 25/02/15
|
||||
* Time: 12:29
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class BillFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class BillFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$nameRule = 'required|between:1,255|uniqueForUser:bills,name';
|
||||
if(intval(Input::get('id')) > 0) {
|
||||
$nameRule .= ','.intval(Input::get('id'));
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'name' => $nameRule,
|
||||
'match' => 'required|between:1,255',
|
||||
'amount_min' => 'required|numeric|min:0.01',
|
||||
'amount_max' => 'required|numeric|min:0.01',
|
||||
'amount_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'date' => 'required|date',
|
||||
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
|
||||
'skip' => 'required|between:0,31',
|
||||
'automatch' => 'in:1',
|
||||
'active' => 'in:1',
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
@@ -4,6 +4,7 @@ use DaveJamesMiller\Breadcrumbs\Generator;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
|
@@ -95,12 +95,16 @@ Route::group(
|
||||
* 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/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/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']);
|
||||
|
||||
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']);
|
||||
|
||||
/**
|
||||
* Budget Controller
|
||||
*/
|
||||
@@ -155,7 +159,7 @@ Route::group(
|
||||
|
||||
Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']);
|
||||
Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']);
|
||||
//Route::get('/chart/bills/{bill}', ['uses' => 'GoogleChartController@billOverview']);
|
||||
Route::get('/chart/bills/{bill}', ['uses' => 'GoogleChartController@billOverview']);
|
||||
|
||||
// JSON controller
|
||||
Route::get('/json/expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'json.expense-accounts']);
|
||||
|
Reference in New Issue
Block a user