mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 15:35:15 +00:00
Merge branch 'release/3.3.3'
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -26,3 +26,4 @@ db.sqlite-journal
|
||||
tests/_output/*
|
||||
.env
|
||||
clover.xml
|
||||
node_modules/
|
@@ -1,4 +1,6 @@
|
||||
language: php
|
||||
sudo: false
|
||||
|
||||
|
||||
php:
|
||||
- 5.5
|
||||
@@ -13,9 +15,11 @@ install:
|
||||
- composer install
|
||||
- php artisan env
|
||||
- mv -v .env.testing .env
|
||||
- touch tests/database/db.sqlite
|
||||
- php artisan migrate --seed
|
||||
|
||||
script:
|
||||
- phpunit
|
||||
- phpunit --debug
|
||||
|
||||
after_script:
|
||||
- php vendor/bin/coveralls
|
||||
|
@@ -1,4 +1,4 @@
|
||||
Firefly III (v3.3.2)
|
||||
Firefly III (v3.3.3)
|
||||
===========
|
||||
|
||||
[](https://travis-ci.org/JC5/firefly-iii)
|
||||
|
@@ -5,6 +5,11 @@ use FireflyIII\Events\Event;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class JournalCreated
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalCreated extends Event {
|
||||
|
||||
use SerializesModels;
|
||||
@@ -23,9 +28,6 @@ class JournalCreated extends Event {
|
||||
$this->journal = $journal;
|
||||
$this->piggyBankId = $piggyBankId;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -38,6 +38,9 @@ class ConnectJournalToPiggyBank
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $event->journal;
|
||||
$piggyBankId = $event->piggyBankId;
|
||||
if(intval($piggyBankId) < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::debug('JournalCreated event: ' . $journal->id . ', ' . $piggyBankId);
|
||||
|
||||
@@ -63,6 +66,7 @@ class ConnectJournalToPiggyBank
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@@ -25,10 +25,7 @@ class ReminderHelper implements ReminderHelperInterface
|
||||
*/
|
||||
public function createReminder(PiggyBank $piggyBank, Carbon $start, Carbon $end)
|
||||
{
|
||||
$reminder = Auth::user()->reminders()
|
||||
->where('remindersable_id', $piggyBank->id)
|
||||
->onDates($start, $end)
|
||||
->first();
|
||||
$reminder = Auth::user()->reminders()->where('remindersable_id', $piggyBank->id)->onDates($start, $end)->first();
|
||||
if (is_null($reminder)) {
|
||||
|
||||
if (!is_null($piggyBank->targetdate)) {
|
||||
@@ -134,7 +131,8 @@ class ReminderHelper implements ReminderHelperInterface
|
||||
{
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = $reminder->remindersable;
|
||||
if(is_null($piggyBank)) {
|
||||
|
||||
if (is_null($piggyBank)) {
|
||||
return 'Piggy bank no longer exists.';
|
||||
}
|
||||
|
||||
|
@@ -87,6 +87,9 @@ class ReportQuery implements ReportQueryInterface
|
||||
->whereNull('budget_transaction_journal.budget_id')->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('otherJournals.deleted_at')
|
||||
->where('transactions.account_id', $account->id)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
->whereNotNull('transaction_group_transaction_journal.transaction_group_id')
|
||||
->get(
|
||||
[
|
||||
|
@@ -168,7 +168,7 @@ class AccountController extends Controller
|
||||
$what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
|
||||
$journals = $repository->getJournals($account, $page);
|
||||
$subTitle = 'Details for ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"';
|
||||
|
||||
$journals->setPath('accounts/show/'.$account->id);
|
||||
return view('accounts.show', compact('account', 'what', 'subTitleIcon', 'journals', 'subTitle'));
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ class AccountController extends Controller
|
||||
Session::flash('success', 'New account "' . $account->name . '" stored!');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
return Redirect::route('accounts.create', $request->input('what'));
|
||||
return Redirect::route('accounts.create', $request->input('what'))->withInput();
|
||||
}
|
||||
|
||||
return Redirect::route('accounts.index', $request->input('what'));
|
||||
|
@@ -63,7 +63,10 @@ class AuthController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
$this->auth->login($this->registrar->create($request->all()));
|
||||
$data =$request->all();
|
||||
$data['password'] = bcrypt($data['password']);
|
||||
|
||||
$this->auth->login($this->registrar->create($data));
|
||||
|
||||
// get the email address
|
||||
$email = $this->auth->user()->email;
|
||||
|
@@ -138,7 +138,12 @@ class BillController extends Controller
|
||||
*/
|
||||
public function show(Bill $bill, BillRepositoryInterface $repository)
|
||||
{
|
||||
$journals = $bill->transactionjournals()->withRelevantData()->orderBy('date', 'DESC')->get();
|
||||
$journals = $bill->transactionjournals()->withRelevantData()
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
|
||||
->get();
|
||||
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill);
|
||||
$hideBill = true;
|
||||
|
||||
@@ -210,42 +215,6 @@ class BillController extends Controller
|
||||
|
||||
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']);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -133,7 +133,9 @@ class BudgetController extends Controller
|
||||
->whereNull('budget_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date')
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
->get(['transaction_journals.*']);
|
||||
$subTitle = 'Transactions without a budget in ' . $start->format('F Y');
|
||||
|
||||
@@ -152,6 +154,12 @@ class BudgetController extends Controller
|
||||
return Redirect::route('budgets.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetFormRequest $request
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(BudgetFormRequest $request, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$budgetData = [
|
||||
@@ -204,6 +212,10 @@ class BudgetController extends Controller
|
||||
|
||||
Session::flash('success', 'Budget "' . $budget->name . '" updated.');
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
return Redirect::route('budgets.edit', $budget->id);
|
||||
}
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
|
||||
}
|
||||
|
@@ -88,7 +88,11 @@ class CategoryController extends Controller
|
||||
|
||||
$categories->each(
|
||||
function (Category $category) {
|
||||
$latest = $category->transactionjournals()->orderBy('date', 'DESC')->first();
|
||||
$latest = $category->transactionjournals()
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
->first();
|
||||
if ($latest) {
|
||||
$category->lastActivity = $latest->date;
|
||||
}
|
||||
@@ -111,7 +115,9 @@ class CategoryController extends Controller
|
||||
->whereNull('category_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date')
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
->get(['transaction_journals.*']);
|
||||
|
||||
$subTitle = 'Transactions without a category between ' . $start->format('jS F Y') . ' and ' . $end->format('jS F Y');
|
||||
@@ -129,7 +135,13 @@ class CategoryController extends Controller
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page'));
|
||||
$offset = $page > 0 ? $page * 50 : 0;
|
||||
$set = $category->transactionJournals()->withRelevantData()->take(50)->offset($offset)->orderBy('date', 'DESC')->get(
|
||||
$set = $category->transactionJournals()->withRelevantData()->take(50)->offset($offset)
|
||||
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
|
||||
->get(
|
||||
['transaction_journals.*']
|
||||
);
|
||||
$count = $category->transactionJournals()->count();
|
||||
@@ -154,6 +166,10 @@ class CategoryController extends Controller
|
||||
$category = $repository->store($categoryData);
|
||||
|
||||
Session::flash('success', 'New category "' . $category->name . '" stored!');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
return Redirect::route('categories.create')->withInput();
|
||||
}
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
return Redirect::route('categories.create');
|
||||
@@ -181,6 +197,10 @@ class CategoryController extends Controller
|
||||
|
||||
Session::flash('success', 'Category "' . $category->name . '" updated.');
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
return Redirect::route('categories.edit', $category->id);
|
||||
}
|
||||
|
||||
return Redirect::route('categories.index');
|
||||
|
||||
}
|
||||
|
@@ -148,7 +148,7 @@ class CurrencyController extends Controller
|
||||
Session::flash('success', 'Currency "' . $currency->name . '" created');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
return Redirect::route('currency.create');
|
||||
return Redirect::route('currency.create')->withInput();
|
||||
}
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
|
@@ -235,7 +235,9 @@ class GoogleChartController extends Controller
|
||||
// query!
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$set = TransactionJournal::leftJoin(
|
||||
$set = TransactionJournal::
|
||||
where('transaction_journals.user_id',Auth::user()->id)
|
||||
->leftJoin(
|
||||
'transactions',
|
||||
function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('amount', '>', 0);
|
||||
@@ -247,6 +249,7 @@ class GoogleChartController extends Controller
|
||||
->leftJoin('categories', 'categories.id', '=', 'category_transaction_journal.category_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->before($end)
|
||||
->where('categories.user_id',Auth::user()->id)
|
||||
->after($start)
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->groupBy('categories.id')
|
||||
@@ -503,7 +506,7 @@ class GoogleChartController extends Controller
|
||||
{
|
||||
// oldest transaction in category:
|
||||
/** @var TransactionJournal $first */
|
||||
$start = Session::get('start');
|
||||
$start = clone Session::get('start');
|
||||
$chart->addColumn('Period', 'date');
|
||||
$chart->addColumn('Spent', 'number');
|
||||
|
||||
@@ -532,10 +535,13 @@ class GoogleChartController extends Controller
|
||||
$chart->addColumn('Date', 'date');
|
||||
$chart->addColumn('Balance', 'number');
|
||||
|
||||
$set = \DB::table('piggy_bank_events')->where('piggy_bank_id', $piggyBank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]);
|
||||
/** @var Collection $set */
|
||||
$set = DB::table('piggy_bank_events')->where('piggy_bank_id', $piggyBank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]);
|
||||
$sum = 0;
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$chart->addRow(new Carbon($entry->date), floatval($entry->sum));
|
||||
$sum += floatval($entry->sum);
|
||||
$chart->addRow(new Carbon($entry->date), $sum);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
@@ -1,6 +1,5 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
@@ -64,6 +63,7 @@ class HomeController extends Controller
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$accounts = $repository->getFrontpageAccounts($frontPage);
|
||||
$savings = $repository->getSavingsAccounts();
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = $repository->getFrontpageTransactions($account, $start, $end);
|
||||
@@ -74,7 +74,7 @@ class HomeController extends Controller
|
||||
|
||||
// var_dump($transactions);
|
||||
|
||||
return view('index', compact('count', 'title', 'subTitle', 'mainTitleIcon', 'transactions'));
|
||||
return view('index', compact('count', 'title','savings', 'subTitle', 'mainTitleIcon', 'transactions'));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -136,14 +136,13 @@ class PiggyBankController extends Controller
|
||||
return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'accounts', 'periods', 'preFilled'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
{
|
||||
/** @var Collection $piggyBanks */
|
||||
$piggyBanks = Auth::user()->piggyBanks()->where('repeats', 0)->get();
|
||||
$piggyBanks = Auth::user()->piggyBanks()->where('repeats', 0)->orderBy('order', 'ASC')->get();
|
||||
|
||||
$accounts = [];
|
||||
/** @var PiggyBank $piggyBank */
|
||||
@@ -175,6 +174,22 @@ class PiggyBankController extends Controller
|
||||
return view('piggy-banks.index', compact('piggyBanks', 'accounts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow user to order piggy banks.
|
||||
*/
|
||||
public function order(PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
$data = Input::get('order');
|
||||
|
||||
// set all users piggy banks to zero:
|
||||
$repository->reset();
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $order => $id) {
|
||||
$repository->setOrder(intval($id), (intval($order) + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST add money to piggy bank
|
||||
@@ -276,7 +291,10 @@ class PiggyBankController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBankFormRequest $request
|
||||
* @param PiggyBankRepositoryInterface $repository
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
|
@@ -12,6 +12,7 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use View;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class RepeatedExpenseController
|
||||
@@ -144,7 +145,10 @@ class RepeatedExpenseController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
* @param PiggyBankFormRequest $request
|
||||
* @param PiggyBankRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
@@ -159,6 +163,7 @@ class RepeatedExpenseController extends Controller
|
||||
'reminder' => $request->get('reminder'),
|
||||
'skip' => intval($request->get('skip')),
|
||||
'rep_every' => intval($request->get('rep_every')),
|
||||
'rep_length' => $request->get('rep_length'),
|
||||
'rep_times' => intval($request->get('rep_times')),
|
||||
];
|
||||
|
||||
@@ -166,6 +171,11 @@ class RepeatedExpenseController extends Controller
|
||||
|
||||
Session::flash('success', 'Stored repeated expense "' . e($piggyBank->name) . '".');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
return Redirect::route('repeated.create', $request->input('what'))->withInput();
|
||||
}
|
||||
|
||||
|
||||
return Redirect::route('repeated.index');
|
||||
}
|
||||
|
||||
@@ -194,6 +204,10 @@ class RepeatedExpenseController extends Controller
|
||||
|
||||
$piggyBank = $repository->update($repeatedExpense, $piggyBankData);
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
return Redirect::route('repeated.edit', $piggyBank->id);
|
||||
}
|
||||
|
||||
Session::flash('success', 'Updated repeated expense "' . e($piggyBank->name) . '".');
|
||||
|
||||
return Redirect::route('repeated.index');
|
||||
|
@@ -15,7 +15,7 @@ use Input;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
use Response;
|
||||
|
||||
/**
|
||||
* Class TransactionController
|
||||
@@ -180,29 +180,33 @@ class TransactionController extends Controller
|
||||
case 'withdrawal':
|
||||
$subTitleIcon = 'fa-long-arrow-left';
|
||||
$subTitle = 'Expenses';
|
||||
//$journals = $this->_repository->getWithdrawalsPaginated(50);
|
||||
$types = ['Withdrawal'];
|
||||
$types = ['Withdrawal'];
|
||||
break;
|
||||
case 'revenue':
|
||||
case 'deposit':
|
||||
$subTitleIcon = 'fa-long-arrow-right';
|
||||
$subTitle = 'Revenue, income and deposits';
|
||||
// $journals = $this->_repository->getDepositsPaginated(50);
|
||||
$types = ['Deposit'];
|
||||
$types = ['Deposit'];
|
||||
break;
|
||||
case 'transfer':
|
||||
case 'transfers':
|
||||
$subTitleIcon = 'fa-arrows-h';
|
||||
$subTitleIcon = 'fa-exchange';
|
||||
$subTitle = 'Transfers';
|
||||
//$journals = $this->_repository->getTransfersPaginated(50);
|
||||
$types = ['Transfer'];
|
||||
$types = ['Transfer'];
|
||||
break;
|
||||
}
|
||||
|
||||
$page = intval(\Input::get('page'));
|
||||
$offset = $page > 0 ? ($page - 1) * 50 : 0;
|
||||
|
||||
$set = Auth::user()->transactionJournals()->transactionTypes($types)->withRelevantData()->take(50)->offset($offset)->orderBy('date', 'DESC')->get(
|
||||
$set = Auth::user()->
|
||||
transactionJournals()->
|
||||
transactionTypes($types)->
|
||||
withRelevantData()->take(50)->offset($offset)
|
||||
->orderBy('date', 'DESC')
|
||||
->orderBy('order','ASC')
|
||||
->orderBy('id','DESC')
|
||||
->get(
|
||||
['transaction_journals.*']
|
||||
);
|
||||
$count = Auth::user()->transactionJournals()->transactionTypes($types)->count();
|
||||
@@ -213,6 +217,27 @@ class TransactionController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorder transactions (which all must have the same date)
|
||||
*/
|
||||
public function reorder()
|
||||
{
|
||||
$ids = Input::get('items');
|
||||
if (count($ids) > 0) {
|
||||
$order = 0;
|
||||
foreach ($ids as $id) {
|
||||
$journal = Auth::user()->transactionjournals()->where('id', $id)->where('date', Input::get('date'))->first();
|
||||
if($journal) {
|
||||
$journal->order = $order;
|
||||
$order++;
|
||||
$journal->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Response::json(true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
@@ -225,9 +250,11 @@ class TransactionController extends Controller
|
||||
$t->before = floatval(
|
||||
$t->account->transactions()->leftJoin(
|
||||
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
|
||||
)->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d'))->where(
|
||||
'transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s')
|
||||
)->where('transaction_journals.id', '!=', $journal->id)->sum('transactions.amount')
|
||||
)
|
||||
->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d'))
|
||||
->where('transaction_journals.order','>=',$journal->order)
|
||||
->where('transaction_journals.id', '!=', $journal->id)
|
||||
->sum('transactions.amount')
|
||||
);
|
||||
$t->after = $t->before + $t->amount;
|
||||
}
|
||||
@@ -239,6 +266,12 @@ class TransactionController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param JournalFormRequest $request
|
||||
* @param JournalRepositoryInterface $repository
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository)
|
||||
{
|
||||
$journalData = [
|
||||
@@ -284,7 +317,6 @@ class TransactionController extends Controller
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @return $this
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function update(TransactionJournal $journal, JournalFormRequest $request, JournalRepositoryInterface $repository)
|
||||
{
|
||||
@@ -317,6 +349,7 @@ class TransactionController extends Controller
|
||||
return Redirect::route('transactions.edit', $journal->id);
|
||||
}
|
||||
|
||||
|
||||
return Redirect::route('transactions.index', $journalData['what']);
|
||||
|
||||
}
|
||||
|
@@ -37,6 +37,7 @@ class Kernel extends HttpKernel
|
||||
'guest' => 'FireflyIII\Http\Middleware\RedirectIfAuthenticated',
|
||||
'range' => 'FireflyIII\Http\Middleware\Range',
|
||||
'reminders' => 'FireflyIII\Http\Middleware\Reminders',
|
||||
'piggybanks' => 'FireflyIII\Http\Middleware\PiggyBanks',
|
||||
];
|
||||
|
||||
}
|
||||
|
141
app/Http/Middleware/PiggyBanks.php
Normal file
141
app/Http/Middleware/PiggyBanks.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Reminder;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
use Navigation;
|
||||
use Session;
|
||||
|
||||
|
||||
/**
|
||||
* Class PiggyBanks
|
||||
*
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class PiggyBanks
|
||||
{
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest()) {
|
||||
// get piggy banks without a repetition:
|
||||
/** @var Collection $set */
|
||||
$set = $this->auth->user()->piggybanks()
|
||||
->leftJoin('piggy_bank_repetitions', 'piggy_banks.id', '=', 'piggy_bank_repetitions.piggy_bank_id')
|
||||
->where('piggy_banks.repeats', 0)
|
||||
->whereNull('piggy_bank_repetitions.id')
|
||||
->get(['piggy_banks.id', 'piggy_banks.startdate', 'piggy_banks.targetdate']);
|
||||
if ($set->count() > 0) {
|
||||
/** @var PiggyBank $partialPiggy */
|
||||
foreach ($set as $partialPiggy) {
|
||||
$repetition = new PiggyBankRepetition;
|
||||
$repetition->piggyBank()->associate($partialPiggy);
|
||||
$repetition->startdate = is_null($partialPiggy->startdate) ? null : $partialPiggy->startdate;
|
||||
$repetition->targetdate = is_null($partialPiggy->targetdate) ? null : $partialPiggy->targetdate;
|
||||
$repetition->currentamount = 0;
|
||||
$repetition->save();
|
||||
}
|
||||
}
|
||||
unset($partialPiggy, $set, $repetition);
|
||||
|
||||
// get repeating piggy banks without a repetition for current time frame.
|
||||
/** @var Collection $set */
|
||||
$set = $this->auth->user()->piggybanks()->leftJoin(
|
||||
'piggy_bank_repetitions', function (JoinClause $join) {
|
||||
$join->on('piggy_bank_repetitions.piggy_bank_id', '=', 'piggy_banks.id')
|
||||
->where('piggy_bank_repetitions.targetdate', '>=', Session::get('start')->format('Y-m-d'))
|
||||
->where('piggy_bank_repetitions.startdate', '<=', Session::get('end')->format('Y-m-d'));
|
||||
}
|
||||
)
|
||||
->where('repeats', 1)
|
||||
->whereNull('piggy_bank_repetitions.id')
|
||||
->get(['piggy_banks.*']);
|
||||
|
||||
// these piggy banks are missing a repetition. start looping and create them!
|
||||
if ($set->count() > 0) {
|
||||
/** @var PiggyBank $piggyBank */
|
||||
foreach ($set as $piggyBank) {
|
||||
$start = clone $piggyBank->startdate;
|
||||
$end = clone $piggyBank->targetdate;
|
||||
$max = clone $piggyBank->targetdate;
|
||||
$index = 0;
|
||||
|
||||
// first loop: start date to target date.
|
||||
// then, continue looping until end is > today
|
||||
while ($start <= $max) {
|
||||
// first loop fixes this date. or should fix it.
|
||||
$max = new Carbon;
|
||||
|
||||
echo '[#'.$piggyBank->id.', from: '.$start->format('Y-m-d.').' to '.$end->format('Y-m-d.').']';
|
||||
// create stuff. Or at least, try:
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->onDates($start, $end)->first();
|
||||
if(!$repetition) {
|
||||
$repetition = new PiggyBankRepetition;
|
||||
$repetition->piggyBank()->associate($piggyBank);
|
||||
$repetition->startdate = $start;
|
||||
$repetition->targetdate = $end;
|
||||
$repetition->currentamount = 0;
|
||||
// it might exist, catch:
|
||||
$repetition->save();
|
||||
}
|
||||
|
||||
// start where end 'ended':
|
||||
$start = clone $end;
|
||||
// move end.
|
||||
$end = Navigation::addPeriod($end, $piggyBank->rep_length, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// first repetition: from original start to original target.
|
||||
$repetition = new PiggyBankRepetition;
|
||||
$repetition->piggyBank()->associate($piggyBank);
|
||||
$repetition->startdate = is_null($piggyBank->startdate) ? null : $piggyBank->startdate;
|
||||
$repetition->targetdate = is_null($piggyBank->targetdate) ? null : $piggyBank->targetdate;
|
||||
$repetition->currentamount = 0;
|
||||
// it might exist, catch:
|
||||
//$repetition->save();
|
||||
|
||||
// then, loop from original target up to now.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@@ -45,7 +45,7 @@ class Reminders
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check()) {
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest()) {
|
||||
// do reminders stuff.
|
||||
$piggyBanks = $this->auth->user()->piggyBanks()->where('remind_me', 1)->get();
|
||||
$today = new Carbon;
|
||||
@@ -67,15 +67,14 @@ class Reminders
|
||||
}
|
||||
}
|
||||
// delete invalid reminders
|
||||
$reminders = $this->auth->user()->reminders()->get();
|
||||
foreach($reminders as $reminder) {
|
||||
if(is_null($reminder->remindersable)) {
|
||||
$reminder->delete();
|
||||
}
|
||||
$set = $this->auth->user()->reminders()->leftJoin('piggy_banks', 'piggy_banks.id', '=', 'remindersable_id')->whereNull('piggy_banks.id')->get(
|
||||
['reminders.id']
|
||||
);
|
||||
foreach ($set as $reminder) {
|
||||
$reminder->delete();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get and list active reminders:
|
||||
$reminders = $this->auth->user()->reminders()->today()->get();
|
||||
$reminders->each(
|
||||
|
@@ -31,9 +31,9 @@ class AccountFormRequest extends Request
|
||||
$accountRoles = join(',', array_keys(Config::get('firefly.accountRoles')));
|
||||
$types = join(',', array_keys(Config::get('firefly.subTitlesByIdentifier')));
|
||||
|
||||
$nameRule = 'required|between:1,100|uniqueForUser:accounts,name';
|
||||
$nameRule = 'required|between:1,100|uniqueAccountForUser';
|
||||
if (Account::find(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,100';
|
||||
$nameRule = 'required|between:1,100|belongsToUser:accounts|uniqueForUser:'.Input::get('id');
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -46,4 +46,4 @@ class AccountFormRequest extends Request
|
||||
'what' => 'in:' . $types
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,8 +3,10 @@
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use Input;
|
||||
use Navigation;
|
||||
|
||||
/**
|
||||
* Class PiggyBankFormRequest
|
||||
@@ -36,8 +38,14 @@ class PiggyBankFormRequest extends Request
|
||||
|
||||
if (intval(Input::get('repeats')) == 1) {
|
||||
$targetDateRule = 'required|date|after:' . date('Y-m-d');
|
||||
// switch on rep_every, make sure it's not too far away.
|
||||
if (!is_null(Input::get('rep_length'))) {
|
||||
$end = Navigation::addPeriod(new Carbon, Input::get('rep_length'), 0);
|
||||
$targetDateRule .= '|before:' . $end->format('Y-m-d');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$rules = [
|
||||
'repeats' => 'required|boolean',
|
||||
'name' => $nameRule,
|
||||
|
@@ -156,7 +156,7 @@ Route::controllers(
|
||||
* Home Controller
|
||||
*/
|
||||
Route::group(
|
||||
['middleware' => ['auth', 'range', 'reminders']], function () {
|
||||
['middleware' => ['auth', 'range', 'reminders','piggybanks']], function () {
|
||||
Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']);
|
||||
Route::get('/home', ['uses' => 'HomeController@index', 'as' => 'home']);
|
||||
Route::post('/daterange', ['uses' => 'HomeController@dateRange', 'as' => 'daterange']);
|
||||
@@ -279,6 +279,7 @@ Route::group(
|
||||
Route::post('/piggy-banks/destroy/{piggyBank}', ['uses' => 'PiggyBankController@destroy', 'as' => 'piggy-banks.destroy']);
|
||||
Route::post('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@postAdd', 'as' => 'piggy-banks.add']); # add money
|
||||
Route::post('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@postRemove', 'as' => 'piggy-banks.remove']); # remove money.
|
||||
Route::post('/piggy-banks/sort', ['uses' => 'PiggyBankController@order', 'as' => 'piggy-banks.order']);
|
||||
|
||||
/**
|
||||
* Preferences Controller
|
||||
@@ -365,6 +366,7 @@ Route::group(
|
||||
);
|
||||
Route::post('/transaction/update/{tj}', ['uses' => 'TransactionController@update', 'as' => 'transactions.update']);
|
||||
Route::post('/transaction/destroy/{tj}', ['uses' => 'TransactionController@destroy', 'as' => 'transactions.destroy']);
|
||||
Route::post('/transaction/reorder', ['uses' => 'TransactionController@reorder', 'as' => 'transactions.reorder']);
|
||||
|
||||
/**
|
||||
* Auth\Auth Controller
|
||||
|
@@ -18,7 +18,7 @@ class Account extends Model
|
||||
= [
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'account_type_id' => 'required|exists:account_types,id',
|
||||
'name' => 'required|between:1,1024|uniqueForUser:accounts,name',
|
||||
'name' => 'required|between:1,1024|uniqueAccountForUser',
|
||||
'active' => 'required|boolean'
|
||||
];
|
||||
|
||||
|
@@ -12,6 +12,8 @@ class Component extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['user_id', 'name','class'];
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
@@ -14,7 +14,9 @@ class PiggyBank extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['repeats', 'name', 'account_id','rep_every', 'rep_times', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder','remind_me'];
|
||||
protected $fillable
|
||||
= ['repeats', 'name', 'account_id', 'rep_every', 'rep_times', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder', 'remind_me',
|
||||
'rep_length'];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
@@ -24,15 +26,6 @@ class PiggyBank extends Model
|
||||
return $this->belongsTo('FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRemindMeAttribute($value) {
|
||||
return intval($value) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the PiggyBankRepetition that's currently relevant / active
|
||||
*
|
||||
@@ -40,10 +33,10 @@ class PiggyBank extends Model
|
||||
*/
|
||||
public function currentRelevantRep()
|
||||
{
|
||||
if ($this->currentRep) {
|
||||
if (!is_null($this->currentRep)) {
|
||||
return $this->currentRep;
|
||||
}
|
||||
if ($this->repeats == 0) {
|
||||
if (intval($this->repeats) === 0) {
|
||||
$rep = $this->piggyBankRepetitions()->first(['piggy_bank_repetitions.*']);
|
||||
$this->currentRep = $rep;
|
||||
|
||||
@@ -104,6 +97,16 @@ class PiggyBank extends Model
|
||||
return ['created_at', 'updated_at', 'deleted_at', 'startdate', 'targetdate'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRemindMeAttribute($value)
|
||||
{
|
||||
return intval($value) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
|
@@ -37,15 +37,27 @@ class PiggyBankRepetition extends Model
|
||||
{
|
||||
return $query->where(
|
||||
function($q) use ($date) {
|
||||
$q->where('startdate', '>=', $date->format('Y-m-d 00:00:00'));
|
||||
$q->where('startdate', '<=', $date->format('Y-m-d 00:00:00'));
|
||||
$q->orWhereNull('startdate');
|
||||
})
|
||||
|
||||
->where(function($q) use ($date) {
|
||||
|
||||
$q->where('targetdate', '<=', $date->format('Y-m-d 00:00:00'));
|
||||
$q->where('targetdate', '>=', $date->format('Y-m-d 00:00:00'));
|
||||
$q->orWhereNull('targetdate');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param Carbon $start
|
||||
* @param Carbon $target
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function scopeOnDates(EloquentBuilder $query, Carbon $start, Carbon $target)
|
||||
{
|
||||
return $query->where('startdate',$start->format('Y-m-d'))->where('targetdate',$target->format('Y-m-d'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -74,6 +74,8 @@ class EventServiceProvider extends ServiceProvider
|
||||
}
|
||||
);
|
||||
|
||||
// move this routine to a filter
|
||||
// in case of repeated piggy banks and/or other problems.
|
||||
PiggyBank::created(
|
||||
function (PiggyBank $piggyBank) {
|
||||
$repetition = new PiggyBankRepetition;
|
||||
|
@@ -18,6 +18,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Session;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* Class AccountRepository
|
||||
@@ -64,6 +65,10 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used on the front page where (in turn) its viewed journals-tiny.php which (in turn)
|
||||
* is almost the only place where formatJournal is used. Aka, we can use some custom querying to get some specific.
|
||||
* fields using left joins.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
@@ -74,15 +79,17 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
return Auth::user()
|
||||
->transactionjournals()
|
||||
->with(['transactions', 'transactioncurrency', 'transactiontype'])
|
||||
->with(['transactions'])
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')->where('accounts.id', $account->id)
|
||||
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transaction_journals.transaction_currency_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->take(10)
|
||||
->get(['transaction_journals.*']);
|
||||
->get(['transaction_journals.*', 'transaction_currencies.symbol', 'transaction_types.type']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +106,9 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
->withRelevantData()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->where('transactions.account_id', $account->id)
|
||||
->orderBy('date', 'DESC');
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC');
|
||||
|
||||
$query->before(Session::get('end', Carbon::now()->endOfMonth()));
|
||||
$query->after(Session::get('start', Carbon::now()->startOfMonth()));
|
||||
@@ -114,6 +123,48 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get savings accounts and the balance difference in the period.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getSavingsAccounts()
|
||||
{
|
||||
$accounts = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC')
|
||||
->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id')
|
||||
->where('account_meta.name', 'accountRole')
|
||||
->where('account_meta.data', '"savingAsset"')
|
||||
->get(['accounts.*']);
|
||||
$start = clone Session::get('start');
|
||||
$end = clone Session::get('end');
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($start, $end) {
|
||||
$account->startBalance = Steam::balance($account, $start);
|
||||
$account->endBalance = Steam::balance($account, $end);
|
||||
|
||||
// diff (negative when lost, positive when gained)
|
||||
$diff = $account->endBalance - $account->startBalance;
|
||||
|
||||
if ($diff < 0 && $account->startBalance > 0) {
|
||||
// percentage lost compared to start.
|
||||
$pct = (($diff * -1) / $account->startBalance) * 100;
|
||||
} else {
|
||||
if ($diff >= 0 && $account->startBalance > 0) {
|
||||
$pct = ($diff / $account->startBalance) * 100;
|
||||
} else {
|
||||
$pct = 100;
|
||||
}
|
||||
}
|
||||
$pct = $pct > 100 ? 100 : $pct;
|
||||
$account->difference = $diff;
|
||||
$account->percentage = round($pct);
|
||||
}
|
||||
);
|
||||
|
||||
return $accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
@@ -236,12 +287,14 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
'active' => $data['active'] === true ? true : false,
|
||||
]
|
||||
);
|
||||
|
||||
if (!$newAccount->isValid()) {
|
||||
// does the account already exist?
|
||||
$existingAccount = Account::where('user_id', $data['user'])->where('account_type_id', $accountType->id)->where('name', $data['name'])->first();
|
||||
if (!$existingAccount) {
|
||||
Log::error('Account create error: ' . $newAccount->getErrors()->toJson());
|
||||
var_dump($newAccount->getErrors()->toArray());
|
||||
App::abort(500);
|
||||
|
||||
}
|
||||
$newAccount = $existingAccount;
|
||||
}
|
||||
|
@@ -78,4 +78,11 @@ interface AccountRepositoryInterface
|
||||
* @return float
|
||||
*/
|
||||
public function leftOnAccount(Account $account);
|
||||
|
||||
/**
|
||||
* Get savings accounts and the balance difference in the period.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getSavingsAccounts();
|
||||
}
|
@@ -42,7 +42,10 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
$offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $take : 0;
|
||||
|
||||
|
||||
$setQuery = $budget->transactionJournals()->withRelevantData()->take($take)->offset($offset)->orderBy('date', 'DESC');
|
||||
$setQuery = $budget->transactionJournals()->withRelevantData()->take($take)->offset($offset)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC');
|
||||
$countQuery = $budget->transactionJournals();
|
||||
|
||||
|
||||
|
@@ -11,6 +11,7 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class JournalRepository
|
||||
|
@@ -2,9 +2,8 @@
|
||||
|
||||
namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
use Amount;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Reminder;
|
||||
@@ -88,6 +87,39 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
return $part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all piggy banks to order 0.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
DB::table('piggy_banks')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.id')
|
||||
->where('accounts.user_id', Auth::user()->id)
|
||||
->update(['order' => 0, 'piggy_banks.updated_at' => DB::Raw('NOW()')]);
|
||||
//Auth::user()->piggyBanks()->update(['order' => 0]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* set id of piggy bank.
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $order
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setOrder($id, $order)
|
||||
{
|
||||
$piggyBank = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')->where('accounts.user_id', Auth::user()->id)
|
||||
->where('piggy_banks.id',$id)->first(['piggy_banks.*']);
|
||||
if ($piggyBank) {
|
||||
$piggyBank->order = $order;
|
||||
$piggyBank->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
@@ -132,5 +164,4 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
|
||||
}
|
@@ -37,6 +37,23 @@ interface PiggyBankRepositoryInterface
|
||||
*/
|
||||
public function createPiggyBankPart(array $data);
|
||||
|
||||
/**
|
||||
* Set all piggy banks to order 0.
|
||||
* @return void
|
||||
*/
|
||||
public function reset();
|
||||
|
||||
/**
|
||||
*
|
||||
* set id of piggy bank.
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $order
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setOrder($id, $order);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@@ -5,6 +5,7 @@ namespace FireflyIII\Support;
|
||||
use Cache;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Preferences as Prefs;
|
||||
|
||||
/**
|
||||
@@ -30,19 +31,27 @@ class Amount
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Transaction|\Transaction $transaction
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatTransaction(Transaction $transaction, $coloured = true)
|
||||
public function getCurrencySymbol()
|
||||
{
|
||||
$symbol = $transaction->transactionJournal->transactionCurrency->symbol;
|
||||
$amount = floatval($transaction->amount);
|
||||
if (defined('FFCURRENCYSYMBOL')) {
|
||||
return FFCURRENCYSYMBOL;
|
||||
}
|
||||
if (\Cache::has('FFCURRENCYSYMBOL')) {
|
||||
define('FFCURRENCYSYMBOL', \Cache::get('FFCURRENCYSYMBOL'));
|
||||
|
||||
return $this->formatWithSymbol($symbol, $amount, $coloured);
|
||||
return FFCURRENCYSYMBOL;
|
||||
}
|
||||
|
||||
$currencyPreference = Prefs::get('currencyPreference', 'EUR');
|
||||
$currency = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
|
||||
\Cache::forever('FFCURRENCYSYMBOL', $currency->symbol);
|
||||
|
||||
define('FFCURRENCYSYMBOL', $currency->symbol);
|
||||
|
||||
return $currency->symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,29 +82,56 @@ class Amount
|
||||
return $symbol . ' ' . $string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*/
|
||||
public function getCurrencySymbol()
|
||||
public function formatJournal(TransactionJournal $journal, $coloured = true)
|
||||
{
|
||||
if (defined('FFCURRENCYSYMBOL')) {
|
||||
return FFCURRENCYSYMBOL;
|
||||
$showPositive = true;
|
||||
if (is_null($journal->symbol)) {
|
||||
$symbol = $journal->transactionCurrency->symbol;
|
||||
} else {
|
||||
$symbol = $journal->symbol;
|
||||
}
|
||||
if (\Cache::has('FFCURRENCYSYMBOL')) {
|
||||
define('FFCURRENCYSYMBOL', \Cache::get('FFCURRENCYSYMBOL'));
|
||||
$amount = 0;
|
||||
|
||||
return FFCURRENCYSYMBOL;
|
||||
if (is_null($journal->type)) {
|
||||
$type = $journal->transactionType->type;
|
||||
} else {
|
||||
$type = $journal->type;
|
||||
}
|
||||
|
||||
$currencyPreference = Prefs::get('currencyPreference', 'EUR');
|
||||
$currency = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
if ($type == 'Withdrawal') {
|
||||
$showPositive = false;
|
||||
}
|
||||
|
||||
\Cache::forever('FFCURRENCYSYMBOL', $currency->symbol);
|
||||
foreach ($journal->transactions as $t) {
|
||||
if (floatval($t->amount) > 0 && $showPositive === true) {
|
||||
$amount = floatval($t->amount);
|
||||
break;
|
||||
}
|
||||
if (floatval($t->amount) < 0 && $showPositive === false) {
|
||||
$amount = floatval($t->amount);
|
||||
}
|
||||
}
|
||||
|
||||
define('FFCURRENCYSYMBOL', $currency->symbol);
|
||||
return $this->formatWithSymbol($symbol, $amount, $coloured);
|
||||
}
|
||||
|
||||
return $currency->symbol;
|
||||
/**
|
||||
* @param Transaction $transaction
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatTransaction(Transaction $transaction, $coloured = true)
|
||||
{
|
||||
$symbol = $transaction->transactionJournal->transactionCurrency->symbol;
|
||||
$amount = floatval($transaction->amount);
|
||||
|
||||
return $this->formatWithSymbol($symbol, $amount, $coloured);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Amount as Amt;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Input;
|
||||
use Session;
|
||||
use View;
|
||||
use Amount as Amt;
|
||||
|
||||
/**
|
||||
* Class ExpandedForm
|
||||
@@ -96,24 +96,14 @@ class ExpandedForm
|
||||
public function getHolderClasses($name)
|
||||
{
|
||||
/*
|
||||
* Get errors, warnings and successes from session:
|
||||
* Get errors from session:
|
||||
*/
|
||||
/** @var MessageBag $errors */
|
||||
$errors = Session::get('errors');
|
||||
$errors = Session::get('errors');
|
||||
$classes = 'form-group';
|
||||
|
||||
/** @var MessageBag $successes */
|
||||
$successes = Session::get('successes');
|
||||
|
||||
switch (true) {
|
||||
case (!is_null($errors) && $errors->has($name)):
|
||||
$classes = 'form-group has-error has-feedback';
|
||||
break;
|
||||
case (!is_null($successes) && $successes->has($name)):
|
||||
$classes = 'form-group has-success has-feedback';
|
||||
break;
|
||||
default:
|
||||
$classes = 'form-group';
|
||||
break;
|
||||
if (!is_null($errors) && $errors->has($name)) {
|
||||
$classes = 'form-group has-error has-feedback';
|
||||
}
|
||||
|
||||
return $classes;
|
||||
|
@@ -3,11 +3,12 @@
|
||||
namespace FireflyIII\Support\Search;
|
||||
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Auth;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class Search
|
||||
@@ -23,7 +24,7 @@ class Search implements SearchInterface
|
||||
*/
|
||||
public function searchAccounts(array $words)
|
||||
{
|
||||
return \Auth::user()->accounts()->with('accounttype')->where(
|
||||
return Auth::user()->accounts()->with('accounttype')->where(
|
||||
function (EloquentBuilder $q) use ($words) {
|
||||
foreach ($words as $word) {
|
||||
$q->orWhere('name', 'LIKE', '%' . e($word) . '%');
|
||||
@@ -40,7 +41,7 @@ class Search implements SearchInterface
|
||||
public function searchBudgets(array $words)
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$set = \Auth::user()->budgets()->get();
|
||||
$set = Auth::user()->budgets()->get();
|
||||
$newSet = $set->filter(
|
||||
function (Budget $b) use ($words) {
|
||||
$found = 0;
|
||||
@@ -65,7 +66,7 @@ class Search implements SearchInterface
|
||||
public function searchCategories(array $words)
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$set = \Auth::user()->categories()->get();
|
||||
$set = Auth::user()->categories()->get();
|
||||
$newSet = $set->filter(
|
||||
function (Category $c) use ($words) {
|
||||
$found = 0;
|
||||
@@ -101,12 +102,39 @@ class Search implements SearchInterface
|
||||
*/
|
||||
public function searchTransactions(array $words)
|
||||
{
|
||||
return \Auth::user()->transactionjournals()->withRelevantData()->where(
|
||||
// decrypted transaction journals:
|
||||
$decrypted = Auth::user()->transactionjournals()->withRelevantData()->where('encrypted', 0)->where(
|
||||
function (EloquentBuilder $q) use ($words) {
|
||||
foreach ($words as $word) {
|
||||
$q->orWhere('description', 'LIKE', '%' . e($word) . '%');
|
||||
}
|
||||
}
|
||||
)->get();
|
||||
|
||||
// encrypted
|
||||
$all = Auth::user()->transactionjournals()->withRelevantData()->where('encrypted', 1)->get();
|
||||
$set = $all->filter(
|
||||
function (TransactionJournal $journal) use ($words) {
|
||||
foreach ($words as $word) {
|
||||
$haystack = strtolower($journal->description);
|
||||
$word = strtolower($word);
|
||||
if (!(strpos($haystack, $word) === false)) {
|
||||
return $journal;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
$filtered = $set->merge($decrypted);
|
||||
|
||||
$filtered->sortBy(
|
||||
function (TransactionJournal $journal) {
|
||||
return intval($journal->date->format('U'));
|
||||
}
|
||||
);
|
||||
|
||||
$filtered = $filtered->reverse();
|
||||
|
||||
return $filtered;
|
||||
}
|
||||
}
|
||||
|
@@ -4,8 +4,11 @@ namespace FireflyIII\Validation;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use DB;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Input;
|
||||
use Navigation;
|
||||
|
||||
/**
|
||||
@@ -34,6 +37,13 @@ class FireflyValidator extends Validator
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
* @param $parameters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validatePiggyBankReminder($attribute, $value, $parameters)
|
||||
{
|
||||
$array = $this->data;
|
||||
@@ -51,14 +61,65 @@ class FireflyValidator extends Validator
|
||||
return true;
|
||||
}
|
||||
|
||||
$nextReminder = Navigation::addPeriod($startDate, $array['reminder'],0);
|
||||
$nextReminder = Navigation::addPeriod($startDate, $array['reminder'], 0);
|
||||
// reminder is beyond target?
|
||||
if($nextReminder > $targetDate) {
|
||||
if ($nextReminder > $targetDate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
* @param $parameters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateUniqueAccountForUser($attribute, $value, $parameters)
|
||||
{
|
||||
// get account type from data, we must have this:
|
||||
$validTypes = array_keys(Config::get('firefly.subTitlesByIdentifier'));
|
||||
|
||||
|
||||
$type = isset($this->data['what']) && in_array($this->data['what'],$validTypes) ? $this->data['what'] : null;
|
||||
// some fallback:
|
||||
if(is_null($type)) {
|
||||
$type = in_array(Input::get('what'),$validTypes) ? Input::get('what') : null;
|
||||
}
|
||||
// still null?
|
||||
if(is_null($type)) {
|
||||
// find by other field:
|
||||
$type = isset($this->data['account_type_id']) ? $this->data['account_type_id'] : 0;
|
||||
$dbType = AccountType::find($type);
|
||||
} else {
|
||||
$longType = Config::get('firefly.accountTypeByIdentifier.' . $type);
|
||||
$dbType = AccountType::whereType($longType)->first();
|
||||
}
|
||||
|
||||
if (is_null($dbType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// user id?
|
||||
$userId = Auth::check() ? Auth::user()->id : $this->data['user_id'];
|
||||
|
||||
$query = DB::table('accounts')->where('name', $value)->where('account_type_id', $dbType->id)->where('user_id', $userId);
|
||||
|
||||
if (isset($parameters[0])) {
|
||||
$query->where('id', '!=', $parameters[0]);
|
||||
}
|
||||
$count = $query->count();
|
||||
if ($count == 0) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
@@ -69,6 +130,7 @@ class FireflyValidator extends Validator
|
||||
public function validateUniqueForUser($attribute, $value, $parameters)
|
||||
{
|
||||
$query = DB::table($parameters[0])->where($parameters[1], $value);
|
||||
$query->where('user_id', Auth::user()->id);
|
||||
if (isset($paramers[2])) {
|
||||
$query->where('id', '!=', $parameters[2]);
|
||||
}
|
||||
|
@@ -48,7 +48,7 @@ return [
|
||||
|
||||
'sqlite' => [
|
||||
'driver' => 'sqlite',
|
||||
'database' => realpath(__DIR__ . '/../tests/_data/db.sqlite'),
|
||||
'database' => realpath(__DIR__ . '/../tests/database/db.sqlite'),
|
||||
'prefix' => '',
|
||||
],
|
||||
|
||||
|
@@ -19,7 +19,8 @@ return [
|
||||
|
||||
'accountRoles' => [
|
||||
'defaultAsset' => 'Default asset account',
|
||||
'sharedAsset' => 'Shared asset account'
|
||||
'sharedAsset' => 'Shared asset account',
|
||||
'savingAsset' => 'Savings account'
|
||||
],
|
||||
|
||||
'range_to_text' => [
|
||||
|
@@ -18,14 +18,14 @@ class ChangesForV332 extends Migration {
|
||||
|
||||
Schema::table(
|
||||
'accounts', function (Blueprint $table) {
|
||||
$table->boolean('encrypted');
|
||||
$table->boolean('encrypted')->default(0);
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
Schema::table(
|
||||
'reminders', function (Blueprint $table) {
|
||||
$table->text('metadata');
|
||||
$table->text('metadata')->nullable();
|
||||
|
||||
}
|
||||
);
|
||||
|
33
database/migrations/2015_03_27_061038_changes_for_v333.php
Normal file
33
database/migrations/2015_03_27_061038_changes_for_v333.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class ChangesForV333 extends Migration {
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table(
|
||||
'transaction_journals', function (Blueprint $table) {
|
||||
$table->smallInteger('order',false,true)->default(0);
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
}
|
@@ -116,9 +116,9 @@ class TestDataSeeder extends Seeder
|
||||
*/
|
||||
public function createUsers()
|
||||
{
|
||||
User::create(['email' => 'reset@example.com', 'password' => 'functional', 'reset' => 'okokokokokokokokokokokokokokokok', 'remember_token' => null]);
|
||||
User::create(['email' => 'functional@example.com', 'password' => 'functional', 'reset' => null, 'remember_token' => null]);
|
||||
User::create(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james', 'reset' => null, 'remember_token' => null]);
|
||||
User::create(['email' => 'reset@example.com', 'password' => bcrypt('functional'), 'reset' => 'okokokokokokokokokokokokokokokok', 'remember_token' => null]);
|
||||
User::create(['email' => 'functional@example.com', 'password' => bcrypt('functional'), 'reset' => null, 'remember_token' => null]);
|
||||
User::create(['email' => 'thegrumpydictator@gmail.com', 'password' => bcrypt('james'), 'reset' => null, 'remember_token' => null]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +139,7 @@ class TestDataSeeder extends Seeder
|
||||
|
||||
// create account meta:
|
||||
$meta_a = AccountMeta::create(['account_id' => $acc_a->id, 'name' => 'accountRole', 'data' => 'defaultAsset']);
|
||||
$meta_b = AccountMeta::create(['account_id' => $acc_b->id, 'name' => 'accountRole', 'data' => 'defaultAsset']);
|
||||
$meta_b = AccountMeta::create(['account_id' => $acc_b->id, 'name' => 'accountRole', 'data' => 'savingAsset']);
|
||||
$meta_c = AccountMeta::create(['account_id' => $acc_c->id, 'name' => 'accountRole', 'data' => 'defaultAsset']);
|
||||
// var_dump($meta_a->toArray());
|
||||
// var_dump($meta_b->toArray());
|
||||
|
@@ -21,11 +21,9 @@
|
||||
</filter>
|
||||
|
||||
<!-- code coverage -->
|
||||
<!--
|
||||
<logging>
|
||||
<log type="coverage-clover" target="./storage/coverage/clover.xml" charset="UTF-8" />
|
||||
</logging>
|
||||
-->
|
||||
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
|
2
public/bootstrap/css/bootstrap-theme.css
vendored
2
public/bootstrap/css/bootstrap-theme.css
vendored
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.2 (http://getbootstrap.com)
|
||||
* Bootstrap v3.3.4 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
2
public/bootstrap/css/bootstrap-theme.min.css
vendored
2
public/bootstrap/css/bootstrap-theme.min.css
vendored
File diff suppressed because one or more lines are too long
54
public/bootstrap/css/bootstrap.css
vendored
54
public/bootstrap/css/bootstrap.css
vendored
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.2 (http://getbootstrap.com)
|
||||
* Bootstrap v3.3.4 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
@@ -958,12 +958,24 @@ th {
|
||||
.glyphicon-bitcoin:before {
|
||||
content: "\e227";
|
||||
}
|
||||
.glyphicon-btc:before {
|
||||
content: "\e227";
|
||||
}
|
||||
.glyphicon-xbt:before {
|
||||
content: "\e227";
|
||||
}
|
||||
.glyphicon-yen:before {
|
||||
content: "\00a5";
|
||||
}
|
||||
.glyphicon-jpy:before {
|
||||
content: "\00a5";
|
||||
}
|
||||
.glyphicon-ruble:before {
|
||||
content: "\20bd";
|
||||
}
|
||||
.glyphicon-rub:before {
|
||||
content: "\20bd";
|
||||
}
|
||||
.glyphicon-scale:before {
|
||||
content: "\e230";
|
||||
}
|
||||
@@ -1074,7 +1086,7 @@ html {
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
body {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
@@ -1161,6 +1173,9 @@ hr {
|
||||
overflow: visible;
|
||||
clip: auto;
|
||||
}
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
@@ -2564,10 +2579,13 @@ output {
|
||||
.form-control[disabled],
|
||||
.form-control[readonly],
|
||||
fieldset[disabled] .form-control {
|
||||
cursor: not-allowed;
|
||||
background-color: #eee;
|
||||
opacity: 1;
|
||||
}
|
||||
.form-control[disabled],
|
||||
fieldset[disabled] .form-control {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
textarea.form-control {
|
||||
height: auto;
|
||||
}
|
||||
@@ -2634,6 +2652,7 @@ input[type="search"] {
|
||||
}
|
||||
.radio-inline,
|
||||
.checkbox-inline {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-left: 20px;
|
||||
margin-bottom: 0;
|
||||
@@ -2667,6 +2686,7 @@ fieldset[disabled] .checkbox label {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.form-control-static {
|
||||
min-height: 34px;
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
margin-bottom: 0;
|
||||
@@ -2708,6 +2728,7 @@ select[multiple].form-group-sm .form-control {
|
||||
}
|
||||
.form-group-sm .form-control-static {
|
||||
height: 30px;
|
||||
min-height: 32px;
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
@@ -2744,6 +2765,7 @@ select[multiple].form-group-lg .form-control {
|
||||
}
|
||||
.form-group-lg .form-control-static {
|
||||
height: 46px;
|
||||
min-height: 38px;
|
||||
padding: 10px 16px;
|
||||
font-size: 18px;
|
||||
line-height: 1.3333333;
|
||||
@@ -3365,11 +3387,9 @@ input[type="button"].btn-block {
|
||||
}
|
||||
.collapse {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
.collapse.in {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
}
|
||||
tr.collapse.in {
|
||||
display: table-row;
|
||||
@@ -3397,7 +3417,7 @@ tbody.collapse.in {
|
||||
height: 0;
|
||||
margin-left: 2px;
|
||||
vertical-align: middle;
|
||||
border-top: 4px solid;
|
||||
border-top: 4px dashed;
|
||||
border-right: 4px solid transparent;
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
@@ -4037,11 +4057,9 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
}
|
||||
.tab-content > .tab-pane {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
.tab-content > .active {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
}
|
||||
.nav-tabs .dropdown-menu {
|
||||
margin-top: -1px;
|
||||
@@ -4088,7 +4106,6 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
height: auto !important;
|
||||
padding-bottom: 0;
|
||||
overflow: visible !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
.navbar-collapse.in {
|
||||
overflow-y: visible;
|
||||
@@ -4813,7 +4830,8 @@ a.label:focus {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
.btn-xs .badge {
|
||||
.btn-xs .badge,
|
||||
.btn-group-xs > .btn .badge {
|
||||
top: 0;
|
||||
padding: 1px 5px;
|
||||
}
|
||||
@@ -5645,10 +5663,10 @@ a.list-group-item-danger.active:focus {
|
||||
height: 100%;
|
||||
border: 0;
|
||||
}
|
||||
.embed-responsive.embed-responsive-16by9 {
|
||||
.embed-responsive-16by9 {
|
||||
padding-bottom: 56.25%;
|
||||
}
|
||||
.embed-responsive.embed-responsive-4by3 {
|
||||
.embed-responsive-4by3 {
|
||||
padding-bottom: 75%;
|
||||
}
|
||||
.well {
|
||||
@@ -5707,7 +5725,7 @@ button.close {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
z-index: 1050;
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
@@ -5750,10 +5768,12 @@ button.close {
|
||||
box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
|
||||
}
|
||||
.modal-backdrop {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
background-color: #000;
|
||||
}
|
||||
.modal-backdrop.fade {
|
||||
@@ -5824,11 +5844,10 @@ button.close {
|
||||
position: absolute;
|
||||
z-index: 1070;
|
||||
display: block;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
line-height: 1.4;
|
||||
visibility: visible;
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -5932,7 +5951,7 @@ button.close {
|
||||
display: none;
|
||||
max-width: 276px;
|
||||
padding: 1px;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 1.42857143;
|
||||
@@ -6348,7 +6367,6 @@ button.close {
|
||||
}
|
||||
.hidden {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
.affix {
|
||||
position: fixed;
|
||||
|
File diff suppressed because one or more lines are too long
4
public/bootstrap/css/bootstrap.min.css
vendored
4
public/bootstrap/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
205
public/bootstrap/js/bootstrap.js
vendored
205
public/bootstrap/js/bootstrap.js
vendored
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap v3.3.2 (http://getbootstrap.com)
|
||||
* Bootstrap v3.3.4 (http://getbootstrap.com)
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
@@ -17,7 +17,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: transition.js v3.3.2
|
||||
* Bootstrap: transition.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#transitions
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -77,7 +77,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: alert.js v3.3.2
|
||||
* Bootstrap: alert.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#alerts
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -96,7 +96,7 @@ if (typeof jQuery === 'undefined') {
|
||||
$(el).on('click', dismiss, this.close)
|
||||
}
|
||||
|
||||
Alert.VERSION = '3.3.2'
|
||||
Alert.VERSION = '3.3.4'
|
||||
|
||||
Alert.TRANSITION_DURATION = 150
|
||||
|
||||
@@ -172,7 +172,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: button.js v3.3.2
|
||||
* Bootstrap: button.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#buttons
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -192,7 +192,7 @@ if (typeof jQuery === 'undefined') {
|
||||
this.isLoading = false
|
||||
}
|
||||
|
||||
Button.VERSION = '3.3.2'
|
||||
Button.VERSION = '3.3.4'
|
||||
|
||||
Button.DEFAULTS = {
|
||||
loadingText: 'loading...'
|
||||
@@ -289,7 +289,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: carousel.js v3.3.2
|
||||
* Bootstrap: carousel.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#carousel
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -307,10 +307,10 @@ if (typeof jQuery === 'undefined') {
|
||||
this.$element = $(element)
|
||||
this.$indicators = this.$element.find('.carousel-indicators')
|
||||
this.options = options
|
||||
this.paused =
|
||||
this.sliding =
|
||||
this.interval =
|
||||
this.$active =
|
||||
this.paused = null
|
||||
this.sliding = null
|
||||
this.interval = null
|
||||
this.$active = null
|
||||
this.$items = null
|
||||
|
||||
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
|
||||
@@ -320,7 +320,7 @@ if (typeof jQuery === 'undefined') {
|
||||
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
|
||||
}
|
||||
|
||||
Carousel.VERSION = '3.3.2'
|
||||
Carousel.VERSION = '3.3.4'
|
||||
|
||||
Carousel.TRANSITION_DURATION = 600
|
||||
|
||||
@@ -527,7 +527,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: collapse.js v3.3.2
|
||||
* Bootstrap: collapse.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#collapse
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -544,7 +544,8 @@ if (typeof jQuery === 'undefined') {
|
||||
var Collapse = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
||||
this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]')
|
||||
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
|
||||
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
|
||||
this.transitioning = null
|
||||
|
||||
if (this.options.parent) {
|
||||
@@ -556,13 +557,12 @@ if (typeof jQuery === 'undefined') {
|
||||
if (this.options.toggle) this.toggle()
|
||||
}
|
||||
|
||||
Collapse.VERSION = '3.3.2'
|
||||
Collapse.VERSION = '3.3.4'
|
||||
|
||||
Collapse.TRANSITION_DURATION = 350
|
||||
|
||||
Collapse.DEFAULTS = {
|
||||
toggle: true,
|
||||
trigger: '[data-toggle="collapse"]'
|
||||
toggle: true
|
||||
}
|
||||
|
||||
Collapse.prototype.dimension = function () {
|
||||
@@ -700,7 +700,7 @@ if (typeof jQuery === 'undefined') {
|
||||
var data = $this.data('bs.collapse')
|
||||
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
|
||||
if (!data && options.toggle && option == 'show') options.toggle = false
|
||||
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
|
||||
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
@@ -731,7 +731,7 @@ if (typeof jQuery === 'undefined') {
|
||||
|
||||
var $target = getTargetFromTrigger($this)
|
||||
var data = $target.data('bs.collapse')
|
||||
var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })
|
||||
var option = data ? 'toggle' : $this.data()
|
||||
|
||||
Plugin.call($target, option)
|
||||
})
|
||||
@@ -739,7 +739,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: dropdown.js v3.3.2
|
||||
* Bootstrap: dropdown.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#dropdowns
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -759,7 +759,7 @@ if (typeof jQuery === 'undefined') {
|
||||
$(element).on('click.bs.dropdown', this.toggle)
|
||||
}
|
||||
|
||||
Dropdown.VERSION = '3.3.2'
|
||||
Dropdown.VERSION = '3.3.4'
|
||||
|
||||
Dropdown.prototype.toggle = function (e) {
|
||||
var $this = $(this)
|
||||
@@ -812,7 +812,7 @@ if (typeof jQuery === 'undefined') {
|
||||
return $this.trigger('click')
|
||||
}
|
||||
|
||||
var desc = ' li:not(.divider):visible a'
|
||||
var desc = ' li:not(.disabled):visible a'
|
||||
var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
|
||||
|
||||
if (!$items.length) return
|
||||
@@ -901,7 +901,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: modal.js v3.3.2
|
||||
* Bootstrap: modal.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#modals
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -916,12 +916,15 @@ if (typeof jQuery === 'undefined') {
|
||||
// ======================
|
||||
|
||||
var Modal = function (element, options) {
|
||||
this.options = options
|
||||
this.$body = $(document.body)
|
||||
this.$element = $(element)
|
||||
this.$backdrop =
|
||||
this.isShown = null
|
||||
this.scrollbarWidth = 0
|
||||
this.options = options
|
||||
this.$body = $(document.body)
|
||||
this.$element = $(element)
|
||||
this.$dialog = this.$element.find('.modal-dialog')
|
||||
this.$backdrop = null
|
||||
this.isShown = null
|
||||
this.originalBodyPad = null
|
||||
this.scrollbarWidth = 0
|
||||
this.ignoreBackdropClick = false
|
||||
|
||||
if (this.options.remote) {
|
||||
this.$element
|
||||
@@ -932,7 +935,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}
|
||||
}
|
||||
|
||||
Modal.VERSION = '3.3.2'
|
||||
Modal.VERSION = '3.3.4'
|
||||
|
||||
Modal.TRANSITION_DURATION = 300
|
||||
Modal.BACKDROP_TRANSITION_DURATION = 150
|
||||
@@ -966,6 +969,12 @@ if (typeof jQuery === 'undefined') {
|
||||
|
||||
this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
|
||||
|
||||
this.$dialog.on('mousedown.dismiss.bs.modal', function () {
|
||||
that.$element.one('mouseup.dismiss.bs.modal', function (e) {
|
||||
if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
|
||||
})
|
||||
})
|
||||
|
||||
this.backdrop(function () {
|
||||
var transition = $.support.transition && that.$element.hasClass('fade')
|
||||
|
||||
@@ -977,7 +986,6 @@ if (typeof jQuery === 'undefined') {
|
||||
.show()
|
||||
.scrollTop(0)
|
||||
|
||||
if (that.options.backdrop) that.adjustBackdrop()
|
||||
that.adjustDialog()
|
||||
|
||||
if (transition) {
|
||||
@@ -993,7 +1001,7 @@ if (typeof jQuery === 'undefined') {
|
||||
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
|
||||
|
||||
transition ?
|
||||
that.$element.find('.modal-dialog') // wait for modal to slide in
|
||||
that.$dialog // wait for modal to slide in
|
||||
.one('bsTransitionEnd', function () {
|
||||
that.$element.trigger('focus').trigger(e)
|
||||
})
|
||||
@@ -1022,6 +1030,9 @@ if (typeof jQuery === 'undefined') {
|
||||
.removeClass('in')
|
||||
.attr('aria-hidden', true)
|
||||
.off('click.dismiss.bs.modal')
|
||||
.off('mouseup.dismiss.bs.modal')
|
||||
|
||||
this.$dialog.off('mousedown.dismiss.bs.modal')
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade') ?
|
||||
this.$element
|
||||
@@ -1082,13 +1093,18 @@ if (typeof jQuery === 'undefined') {
|
||||
var doAnimate = $.support.transition && animate
|
||||
|
||||
this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
|
||||
.prependTo(this.$element)
|
||||
.on('click.dismiss.bs.modal', $.proxy(function (e) {
|
||||
if (e.target !== e.currentTarget) return
|
||||
this.options.backdrop == 'static'
|
||||
? this.$element[0].focus.call(this.$element[0])
|
||||
: this.hide.call(this)
|
||||
}, this))
|
||||
.appendTo(this.$body)
|
||||
|
||||
this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
|
||||
if (this.ignoreBackdropClick) {
|
||||
this.ignoreBackdropClick = false
|
||||
return
|
||||
}
|
||||
if (e.target !== e.currentTarget) return
|
||||
this.options.backdrop == 'static'
|
||||
? this.$element[0].focus()
|
||||
: this.hide()
|
||||
}, this))
|
||||
|
||||
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
|
||||
|
||||
@@ -1123,16 +1139,9 @@ if (typeof jQuery === 'undefined') {
|
||||
// these following methods are used to handle overflowing modals
|
||||
|
||||
Modal.prototype.handleUpdate = function () {
|
||||
if (this.options.backdrop) this.adjustBackdrop()
|
||||
this.adjustDialog()
|
||||
}
|
||||
|
||||
Modal.prototype.adjustBackdrop = function () {
|
||||
this.$backdrop
|
||||
.css('height', 0)
|
||||
.css('height', this.$element[0].scrollHeight)
|
||||
}
|
||||
|
||||
Modal.prototype.adjustDialog = function () {
|
||||
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
|
||||
|
||||
@@ -1150,17 +1159,23 @@ if (typeof jQuery === 'undefined') {
|
||||
}
|
||||
|
||||
Modal.prototype.checkScrollbar = function () {
|
||||
this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight
|
||||
var fullWindowWidth = window.innerWidth
|
||||
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
|
||||
var documentElementRect = document.documentElement.getBoundingClientRect()
|
||||
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
|
||||
}
|
||||
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
|
||||
this.scrollbarWidth = this.measureScrollbar()
|
||||
}
|
||||
|
||||
Modal.prototype.setScrollbar = function () {
|
||||
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
|
||||
this.originalBodyPad = document.body.style.paddingRight || ''
|
||||
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
|
||||
}
|
||||
|
||||
Modal.prototype.resetScrollbar = function () {
|
||||
this.$body.css('padding-right', '')
|
||||
this.$body.css('padding-right', this.originalBodyPad)
|
||||
}
|
||||
|
||||
Modal.prototype.measureScrollbar = function () { // thx walsh
|
||||
@@ -1226,7 +1241,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: tooltip.js v3.3.2
|
||||
* Bootstrap: tooltip.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#tooltip
|
||||
* Inspired by the original jQuery.tipsy by Jason Frame
|
||||
* ========================================================================
|
||||
@@ -1242,17 +1257,17 @@ if (typeof jQuery === 'undefined') {
|
||||
// ===============================
|
||||
|
||||
var Tooltip = function (element, options) {
|
||||
this.type =
|
||||
this.options =
|
||||
this.enabled =
|
||||
this.timeout =
|
||||
this.hoverState =
|
||||
this.type = null
|
||||
this.options = null
|
||||
this.enabled = null
|
||||
this.timeout = null
|
||||
this.hoverState = null
|
||||
this.$element = null
|
||||
|
||||
this.init('tooltip', element, options)
|
||||
}
|
||||
|
||||
Tooltip.VERSION = '3.3.2'
|
||||
Tooltip.VERSION = '3.3.4'
|
||||
|
||||
Tooltip.TRANSITION_DURATION = 150
|
||||
|
||||
@@ -1279,6 +1294,10 @@ if (typeof jQuery === 'undefined') {
|
||||
this.options = this.getOptions(options)
|
||||
this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
|
||||
|
||||
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
|
||||
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
|
||||
}
|
||||
|
||||
var triggers = this.options.trigger.split(' ')
|
||||
|
||||
for (var i = triggers.length; i--;) {
|
||||
@@ -1499,10 +1518,10 @@ if (typeof jQuery === 'undefined') {
|
||||
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
|
||||
}
|
||||
|
||||
Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
|
||||
Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
|
||||
this.arrow()
|
||||
.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
|
||||
.css(isHorizontal ? 'top' : 'left', '')
|
||||
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
|
||||
.css(isVertical ? 'top' : 'left', '')
|
||||
}
|
||||
|
||||
Tooltip.prototype.setContent = function () {
|
||||
@@ -1515,7 +1534,7 @@ if (typeof jQuery === 'undefined') {
|
||||
|
||||
Tooltip.prototype.hide = function (callback) {
|
||||
var that = this
|
||||
var $tip = this.tip()
|
||||
var $tip = $(this.$tip)
|
||||
var e = $.Event('hide.bs.' + this.type)
|
||||
|
||||
function complete() {
|
||||
@@ -1532,7 +1551,7 @@ if (typeof jQuery === 'undefined') {
|
||||
|
||||
$tip.removeClass('in')
|
||||
|
||||
$.support.transition && this.$tip.hasClass('fade') ?
|
||||
$.support.transition && $tip.hasClass('fade') ?
|
||||
$tip
|
||||
.one('bsTransitionEnd', complete)
|
||||
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
|
||||
@@ -1676,7 +1695,7 @@ if (typeof jQuery === 'undefined') {
|
||||
var data = $this.data('bs.tooltip')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data && option == 'destroy') return
|
||||
if (!data && /destroy|hide/.test(option)) return
|
||||
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
@@ -1699,7 +1718,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: popover.js v3.3.2
|
||||
* Bootstrap: popover.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#popovers
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -1719,7 +1738,7 @@ if (typeof jQuery === 'undefined') {
|
||||
|
||||
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
|
||||
|
||||
Popover.VERSION = '3.3.2'
|
||||
Popover.VERSION = '3.3.4'
|
||||
|
||||
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
|
||||
placement: 'right',
|
||||
@@ -1775,11 +1794,6 @@ if (typeof jQuery === 'undefined') {
|
||||
return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
|
||||
}
|
||||
|
||||
Popover.prototype.tip = function () {
|
||||
if (!this.$tip) this.$tip = $(this.options.template)
|
||||
return this.$tip
|
||||
}
|
||||
|
||||
|
||||
// POPOVER PLUGIN DEFINITION
|
||||
// =========================
|
||||
@@ -1790,7 +1804,7 @@ if (typeof jQuery === 'undefined') {
|
||||
var data = $this.data('bs.popover')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data && option == 'destroy') return
|
||||
if (!data && /destroy|hide/.test(option)) return
|
||||
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
@@ -1813,7 +1827,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: scrollspy.js v3.3.2
|
||||
* Bootstrap: scrollspy.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#scrollspy
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -1828,10 +1842,8 @@ if (typeof jQuery === 'undefined') {
|
||||
// ==========================
|
||||
|
||||
function ScrollSpy(element, options) {
|
||||
var process = $.proxy(this.process, this)
|
||||
|
||||
this.$body = $('body')
|
||||
this.$scrollElement = $(element).is('body') ? $(window) : $(element)
|
||||
this.$body = $(document.body)
|
||||
this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
|
||||
this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
|
||||
this.selector = (this.options.target || '') + ' .nav li > a'
|
||||
this.offsets = []
|
||||
@@ -1839,12 +1851,12 @@ if (typeof jQuery === 'undefined') {
|
||||
this.activeTarget = null
|
||||
this.scrollHeight = 0
|
||||
|
||||
this.$scrollElement.on('scroll.bs.scrollspy', process)
|
||||
this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
|
||||
this.refresh()
|
||||
this.process()
|
||||
}
|
||||
|
||||
ScrollSpy.VERSION = '3.3.2'
|
||||
ScrollSpy.VERSION = '3.3.4'
|
||||
|
||||
ScrollSpy.DEFAULTS = {
|
||||
offset: 10
|
||||
@@ -1855,20 +1867,19 @@ if (typeof jQuery === 'undefined') {
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.refresh = function () {
|
||||
var offsetMethod = 'offset'
|
||||
var offsetBase = 0
|
||||
var that = this
|
||||
var offsetMethod = 'offset'
|
||||
var offsetBase = 0
|
||||
|
||||
this.offsets = []
|
||||
this.targets = []
|
||||
this.scrollHeight = this.getScrollHeight()
|
||||
|
||||
if (!$.isWindow(this.$scrollElement[0])) {
|
||||
offsetMethod = 'position'
|
||||
offsetBase = this.$scrollElement.scrollTop()
|
||||
}
|
||||
|
||||
this.offsets = []
|
||||
this.targets = []
|
||||
this.scrollHeight = this.getScrollHeight()
|
||||
|
||||
var self = this
|
||||
|
||||
this.$body
|
||||
.find(this.selector)
|
||||
.map(function () {
|
||||
@@ -1883,8 +1894,8 @@ if (typeof jQuery === 'undefined') {
|
||||
})
|
||||
.sort(function (a, b) { return a[0] - b[0] })
|
||||
.each(function () {
|
||||
self.offsets.push(this[0])
|
||||
self.targets.push(this[1])
|
||||
that.offsets.push(this[0])
|
||||
that.targets.push(this[1])
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1913,7 +1924,7 @@ if (typeof jQuery === 'undefined') {
|
||||
for (i = offsets.length; i--;) {
|
||||
activeTarget != targets[i]
|
||||
&& scrollTop >= offsets[i]
|
||||
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
|
||||
&& (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
|
||||
&& this.activate(targets[i])
|
||||
}
|
||||
}
|
||||
@@ -1924,8 +1935,8 @@ if (typeof jQuery === 'undefined') {
|
||||
this.clear()
|
||||
|
||||
var selector = this.selector +
|
||||
'[data-target="' + target + '"],' +
|
||||
this.selector + '[href="' + target + '"]'
|
||||
'[data-target="' + target + '"],' +
|
||||
this.selector + '[href="' + target + '"]'
|
||||
|
||||
var active = $(selector)
|
||||
.parents('li')
|
||||
@@ -1989,7 +2000,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: tab.js v3.3.2
|
||||
* Bootstrap: tab.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#tabs
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -2007,7 +2018,7 @@ if (typeof jQuery === 'undefined') {
|
||||
this.element = $(element)
|
||||
}
|
||||
|
||||
Tab.VERSION = '3.3.2'
|
||||
Tab.VERSION = '3.3.4'
|
||||
|
||||
Tab.TRANSITION_DURATION = 150
|
||||
|
||||
@@ -2078,7 +2089,7 @@ if (typeof jQuery === 'undefined') {
|
||||
element.removeClass('fade')
|
||||
}
|
||||
|
||||
if (element.parent('.dropdown-menu')) {
|
||||
if (element.parent('.dropdown-menu').length) {
|
||||
element
|
||||
.closest('li.dropdown')
|
||||
.addClass('active')
|
||||
@@ -2143,7 +2154,7 @@ if (typeof jQuery === 'undefined') {
|
||||
}(jQuery);
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap: affix.js v3.3.2
|
||||
* Bootstrap: affix.js v3.3.4
|
||||
* http://getbootstrap.com/javascript/#affix
|
||||
* ========================================================================
|
||||
* Copyright 2011-2015 Twitter, Inc.
|
||||
@@ -2165,14 +2176,14 @@ if (typeof jQuery === 'undefined') {
|
||||
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
|
||||
|
||||
this.$element = $(element)
|
||||
this.affixed =
|
||||
this.unpin =
|
||||
this.affixed = null
|
||||
this.unpin = null
|
||||
this.pinnedOffset = null
|
||||
|
||||
this.checkPosition()
|
||||
}
|
||||
|
||||
Affix.VERSION = '3.3.2'
|
||||
Affix.VERSION = '3.3.4'
|
||||
|
||||
Affix.RESET = 'affix affix-top affix-bottom'
|
||||
|
||||
@@ -2222,7 +2233,7 @@ if (typeof jQuery === 'undefined') {
|
||||
var offset = this.options.offset
|
||||
var offsetTop = offset.top
|
||||
var offsetBottom = offset.bottom
|
||||
var scrollHeight = $('body').height()
|
||||
var scrollHeight = $(document.body).height()
|
||||
|
||||
if (typeof offset != 'object') offsetBottom = offsetTop = offset
|
||||
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
|
||||
|
6
public/bootstrap/js/bootstrap.min.js
vendored
6
public/bootstrap/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -54,7 +54,7 @@
|
||||
}
|
||||
|
||||
.daterangepicker .calendar th, .daterangepicker .calendar td {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
font-family: Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
min-width: 32px;
|
||||
|
@@ -1,2 +1,3 @@
|
||||
#daterange {cursor:pointer;}
|
||||
.google-chart-error {height:30px;background:url('/images/error.png') no-repeat center center;}
|
||||
.google-chart-error {height:30px;background:url('/images/error.png') no-repeat center center;}
|
||||
.handle {cursor:move;}
|
@@ -1,5 +1,5 @@
|
||||
var google = google || {};
|
||||
google.load('visualization', '1.1', {'packages': ['corechart', 'bar', 'sankey', 'table']});
|
||||
google.load('visualization', '1.1', {'packages': ['corechart', 'bar', 'line', 'sankey', 'table']});
|
||||
|
||||
function googleChart(chartType, URL, container, options) {
|
||||
if ($('#' + container).length === 1) {
|
||||
@@ -13,10 +13,10 @@ function googleChart(chartType, URL, container, options) {
|
||||
Format as money
|
||||
*/
|
||||
var money = new google.visualization.NumberFormat({
|
||||
decimalSymbol: ',',
|
||||
groupingSymbol: '.',
|
||||
prefix: currencyCode + ' '
|
||||
});
|
||||
decimalSymbol: ',',
|
||||
groupingSymbol: '.',
|
||||
prefix: currencyCode + ' '
|
||||
});
|
||||
for (var i = 1; i < gdata.getNumberOfColumns(); i++) {
|
||||
money.format(gdata, i);
|
||||
}
|
||||
@@ -24,14 +24,14 @@ function googleChart(chartType, URL, container, options) {
|
||||
/*
|
||||
Create a new google charts object.
|
||||
*/
|
||||
var chart = false
|
||||
var chart = false;
|
||||
var options = false;
|
||||
if (chartType === 'line') {
|
||||
chart = new google.visualization.LineChart(document.getElementById(container));
|
||||
options = options || defaultLineChartOptions;
|
||||
}
|
||||
if (chartType === 'column') {
|
||||
chart = new google.charts.Bar(document.getElementById(container));
|
||||
chart = new google.visualization.ColumnChart(document.getElementById(container));
|
||||
options = options || defaultColumnChartOptions;
|
||||
}
|
||||
if (chartType === 'pie') {
|
||||
@@ -39,7 +39,7 @@ function googleChart(chartType, URL, container, options) {
|
||||
options = options || defaultPieChartOptions;
|
||||
}
|
||||
if (chartType === 'bar') {
|
||||
chart = new google.charts.Bar(document.getElementById(container));
|
||||
chart = new google.visualization.BarChart(document.getElementById(container));
|
||||
options = options || defaultBarChartOptions;
|
||||
}
|
||||
if (chartType === 'stackedColumn') {
|
||||
|
@@ -16,19 +16,19 @@ var defaultLineChartOptions = {
|
||||
hAxis: {
|
||||
textStyle: {
|
||||
color: '#838383',
|
||||
fontName: 'Roboto2',
|
||||
fontSize: '12'
|
||||
},
|
||||
baselineColor: '#aaaaaa',
|
||||
gridlines: {
|
||||
color: 'transparent'
|
||||
}
|
||||
},
|
||||
fontName: 'Roboto',
|
||||
fontSize: 11,
|
||||
vAxis: {
|
||||
textStyle: {
|
||||
color: '#838383',
|
||||
fontName: 'Roboto2',
|
||||
fontSize: '12'
|
||||
},
|
||||
baselineColor: '#aaaaaa',
|
||||
format: '\u20AC #'
|
||||
}
|
||||
|
||||
@@ -38,9 +38,30 @@ var defaultLineChartOptions = {
|
||||
var defaultBarChartOptions = {
|
||||
height: 400,
|
||||
bars: 'horizontal',
|
||||
hAxis: {format: '\u20AC #'},
|
||||
hAxis: {
|
||||
textStyle: {
|
||||
color: '#838383',
|
||||
},
|
||||
baselineColor: '#aaaaaa',
|
||||
format: '\u20AC #'
|
||||
|
||||
},
|
||||
fontName: 'Roboto',
|
||||
fontSize: 11,
|
||||
colors: ["#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||
vAxis: {
|
||||
textStyle: {
|
||||
color: '#838383',
|
||||
},
|
||||
textPosition: 'in',
|
||||
gridlines: {
|
||||
|
||||
color: 'transparent'
|
||||
},
|
||||
baselineColor: '#aaaaaa'
|
||||
},
|
||||
chartArea: {
|
||||
left: 75,
|
||||
left: 15,
|
||||
top: 10,
|
||||
width: '100%',
|
||||
height: '90%'
|
||||
@@ -63,6 +84,8 @@ var defaultComboChartOptions = {
|
||||
minValue: 0,
|
||||
format: '\u20AC #'
|
||||
},
|
||||
fontName: 'Roboto',
|
||||
fontSize: 11,
|
||||
legend: {
|
||||
position: 'none'
|
||||
},
|
||||
@@ -82,7 +105,26 @@ var defaultColumnChartOptions = {
|
||||
width: '85%',
|
||||
height: '80%'
|
||||
},
|
||||
vAxis: {format: '\u20AC #'},
|
||||
fontName: 'Roboto',
|
||||
fontSize: 11,
|
||||
hAxis: {
|
||||
textStyle: {
|
||||
color: '#838383',
|
||||
},
|
||||
gridlines: {
|
||||
color: 'transparent'
|
||||
},
|
||||
baselineColor: '#aaaaaa'
|
||||
|
||||
},
|
||||
colors: ["#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||
vAxis: {
|
||||
textStyle: {
|
||||
color: '#838383',
|
||||
},
|
||||
baselineColor: '#aaaaaa',
|
||||
format: '\u20AC #'
|
||||
},
|
||||
legend: {
|
||||
position: 'none'
|
||||
},
|
||||
@@ -99,13 +141,13 @@ var defaultStackedColumnChartOptions = {
|
||||
legend: {
|
||||
position: 'none'
|
||||
},
|
||||
fontName: 'Roboto',
|
||||
fontSize: 11,
|
||||
isStacked: true,
|
||||
colors: ["#4285f4", "#db4437", "#f4b400", "#0f9d58", "#ab47bc", "#00acc1", "#ff7043", "#9e9d24", "#5c6bc0", "#f06292", "#00796b", "#c2185b"],
|
||||
hAxis: {
|
||||
textStyle: {
|
||||
color: '#838383',
|
||||
fontName: 'Roboto2',
|
||||
fontSize: '12'
|
||||
},
|
||||
gridlines: {
|
||||
color: 'transparent'
|
||||
@@ -114,8 +156,6 @@ var defaultStackedColumnChartOptions = {
|
||||
vAxis: {
|
||||
textStyle: {
|
||||
color: '#838383',
|
||||
fontName: 'Roboto2',
|
||||
fontSize: '12'
|
||||
},
|
||||
format: '\u20AC #'
|
||||
}
|
||||
@@ -128,6 +168,8 @@ var defaultPieChartOptions = {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
},
|
||||
fontName: 'Roboto',
|
||||
fontSize: 11,
|
||||
height: 200,
|
||||
legend: {
|
||||
position: 'none'
|
||||
|
7
public/js/jquery-ui.min.js
vendored
Executable file
7
public/js/jquery-ui.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
@@ -5,18 +5,41 @@ $(function () {
|
||||
if (typeof(googleLineChart) === 'function' && typeof(piggyBankID) !== 'undefined') {
|
||||
googleLineChart('chart/piggy-history/' + piggyBankID, 'piggy-bank-history');
|
||||
}
|
||||
$('#sortable').sortable(
|
||||
{
|
||||
stop: stopSorting,
|
||||
handle: '.handle'
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function addMoney(e) {
|
||||
var pigID = parseInt($(e.target).data('id'));
|
||||
$('#moneyManagementModal').empty().load('piggy-banks/add/' + pigID, function() {$('#moneyManagementModal').modal('show');});
|
||||
$('#moneyManagementModal').empty().load('piggy-banks/add/' + pigID, function () {
|
||||
$('#moneyManagementModal').modal('show');
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function removeMoney(e) {
|
||||
var pigID = parseInt($(e.target).data('id'));
|
||||
$('#moneyManagementModal').empty().load('piggy-banks/remove/' + pigID, function() {$('#moneyManagementModal').modal('show');});
|
||||
$('#moneyManagementModal').empty().load('piggy-banks/remove/' + pigID, function () {
|
||||
$('#moneyManagementModal').modal('show');
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
function stopSorting() {
|
||||
$('.loadSpin').addClass('fa fa-refresh fa-spin');
|
||||
var order = [];
|
||||
$.each($('#sortable>div'), function(i,v) {
|
||||
var holder = $(v);
|
||||
var id = holder.data('id');
|
||||
order.push(id);
|
||||
});
|
||||
$.post('/piggy-banks/sort',{_token: token, order: order}).success(function(data) {
|
||||
"use strict";
|
||||
$('.loadSpin').removeClass('fa fa-refresh fa-spin');
|
||||
});
|
||||
}
|
@@ -14,8 +14,80 @@ if ($('input[name="category"]').length > 0) {
|
||||
});
|
||||
}
|
||||
|
||||
// Return a helper with preserved width of cells
|
||||
var fixHelper = function (e, ui) {
|
||||
ui.children().each(function () {
|
||||
$(this).width($(this).width());
|
||||
});
|
||||
return ui;
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
if(typeof googleTablePaged != 'undefined') {
|
||||
googleTablePaged('table/transactions/' + what,'transaction-table');
|
||||
if (typeof googleTablePaged != 'undefined') {
|
||||
googleTablePaged('table/transactions/' + what, 'transaction-table');
|
||||
}
|
||||
});
|
||||
|
||||
// sortable!
|
||||
$(".sortable-table tbody").sortable(
|
||||
{
|
||||
helper: fixHelper,
|
||||
items: 'tr:not(.ignore)',
|
||||
stop: sortStop,
|
||||
handle: '.handle'
|
||||
}
|
||||
).disableSelection();
|
||||
});
|
||||
|
||||
function sortStop(event, ui) {
|
||||
var current = $(ui.item);
|
||||
var thisDate = current.data('date');
|
||||
var originalBG = current.css('backgroundColor');
|
||||
|
||||
|
||||
if (current.prev().data('date') != thisDate && current.next().data('date') != thisDate) {
|
||||
//console.log('False!');
|
||||
//console.log('[' + current.prev().data('date') + '] [' + thisDate + '] [' + current.next().data('date') + ']');
|
||||
// animate something with color:
|
||||
current.animate({
|
||||
backgroundColor: "#d9534f"
|
||||
}, 200, function () {
|
||||
$(this).animate({
|
||||
backgroundColor: originalBG
|
||||
}, 200);
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// do update
|
||||
var list = $('tr[data-date="' + thisDate + '"]');
|
||||
var submit = [];
|
||||
$.each(list, function (i, v) {
|
||||
var row = $(v);
|
||||
var id = row.data('id');
|
||||
submit.push(id);
|
||||
});
|
||||
|
||||
// do extra animation when done?
|
||||
$.post('/transaction/reorder',{items: submit,date: thisDate,_token:token});
|
||||
console.log(submit);
|
||||
|
||||
//console.log('TRUE!');
|
||||
//console.log('[' + current.prev().data('date') + '] [' + thisDate + '] [' + current.next().data('date') + ']');
|
||||
|
||||
current.animate({
|
||||
backgroundColor: "#5cb85c"
|
||||
}, 200, function () {
|
||||
$(this).animate({
|
||||
backgroundColor: originalBG
|
||||
}, 200);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
//else update some order thing bla bla.
|
||||
//check if the item above OR under this one have the same date
|
||||
//if not. return false
|
||||
|
||||
}
|
@@ -37,7 +37,7 @@
|
||||
<i class="fa fa-repeat fa-fw"></i> Transactions
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@include('list.journals-full')
|
||||
@include('list.journals-full',['sorting' => true])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,10 +49,14 @@
|
||||
<script type="text/javascript">
|
||||
var accountID = {{{$account->id}}};
|
||||
var currencyCode = '{{Amount::getCurrencyCode()}}';
|
||||
var token = "{{csrf_token()}}";
|
||||
</script>
|
||||
<!-- load the libraries and scripts necessary for Google Charts: -->
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||
<script type="text/javascript" src="js/gcharts.options.js"></script>
|
||||
<script type="text/javascript" src="js/gcharts.js"></script>
|
||||
<script type="text/javascript" src="js/accounts.js"></script>
|
||||
|
||||
<script src="js/jquery-ui.min.js" type="text/javascript"></script>
|
||||
<script src="js/transactions.js" type="text/javascript"></script>
|
||||
@stop
|
||||
|
@@ -8,15 +8,15 @@
|
||||
<i class="fa fa-rotate-right"></i> {{{$bill->name}}}
|
||||
|
||||
@if($bill->active)
|
||||
<span class="glyphicon glyphicon-ok" title="Active"></span>
|
||||
<i class="fa fa-check fa-fw" title="Active"></i>
|
||||
@else
|
||||
<span class="glyphicon glyphicon-remove" title="Inactive"></span>
|
||||
<i class="fa fa-times fa-fw" title="Inactive"></i>
|
||||
@endif
|
||||
|
||||
@if($bill->automatch)
|
||||
<span class="glyphicon glyphicon-ok" title="Automatically matched by Firefly"></span>
|
||||
<i class="fa fa-check fa-fw" title="Automatically matched by Firefly"></i>
|
||||
@else
|
||||
<span class="glyphicon glyphicon-remove" title="Not automatically matched by Firefly"></span>
|
||||
<i class="fa fa-times fa-fw" title="Not automatically matched by Firefly"></i>
|
||||
@endif
|
||||
|
||||
<!-- ACTIONS MENU -->
|
||||
@@ -27,8 +27,8 @@
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu pull-right" role="menu">
|
||||
<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>
|
||||
<li><a href="{{route('bills.edit',$bill->id)}}"><i class="fa fa-fw fa-pencil"></i> edit</a></li>
|
||||
<li><a href="{{route('bills.delete',$bill->id)}}"><i class="fa fa-fw fa-trash-o"></i> delete</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -94,7 +94,7 @@
|
||||
Connected transaction journals
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@include('list.journals-full')
|
||||
@include('list.journals-full',['sorting' => false])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
{{{$subTitle}}}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@include('list.journals-full',['journals' => $list])
|
||||
@include('list.journals-full',['journals' => $list,'sorting' => false])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -16,7 +16,7 @@
|
||||
<div class="panel-heading">
|
||||
Transactions
|
||||
</div>
|
||||
@include('list.journals-full')
|
||||
@include('list.journals-full',['sorting' => false])
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-3 col-md-3 col-sm-5">
|
||||
|
@@ -8,7 +8,7 @@
|
||||
{{{$subTitle}}}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@include('list.journals-full',['journals' => $list])
|
||||
@include('list.journals-full',['journals' => $list,'sorting' => false])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -34,7 +34,7 @@
|
||||
Transactions
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@include('list.journals-full')
|
||||
@include('list.journals-full',['sorting' => false])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,12 +1,4 @@
|
||||
@if($errors->has($name))
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
<span class="form-control-feedback"><i class="fa fa-fw fa-remove"></i></span>
|
||||
<p class="text-danger">{{{$errors->first($name)}}}</p>
|
||||
@endif
|
||||
@if(Session::has('warnings') && Session::get('warnings')->has($name))
|
||||
<span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>
|
||||
<p class="text-warning">{{{Session::get('warnings')->first($name)}}}</p>
|
||||
@endif
|
||||
@if(Session::has('successes') && Session::get('successes')->has($name))
|
||||
<span class="glyphicon glyphicon-ok form-control-feedback"></span>
|
||||
<p class="text-success">{{{Session::get('successes')->first($name)}}}</p>
|
||||
@endif
|
@@ -57,7 +57,54 @@
|
||||
<i class="fa fa-line-chart"></i> Savings
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
(todo)
|
||||
@if(count($savings) == 0)
|
||||
<p class="small"><em>Mark your asset accounts as "Savings account" to fill this panel.</em></p>
|
||||
@else
|
||||
@foreach($savings as $account)
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"><h5><a href="{{route('accounts.show')}}">{{$account->name}}</a></h5></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<!-- start -->
|
||||
<div class="col-lg-2 col-md-2 col-sm-3 col-xs-4">{!! Amount::format($account->startBalance) !!}</div>
|
||||
<!-- bar -->
|
||||
<div class="col-lg-8 col-md-8 col-sm-6 col-xs-4">
|
||||
@if($account->difference < 0)
|
||||
<!-- green (100-pct), then red (pct) -->
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success progress-bar-striped" style="width: {{100 - $account->percentage}}%">
|
||||
@if($account->percentage <= 50)
|
||||
{{Amount::format($account->difference,false)}}
|
||||
@endif
|
||||
</div>
|
||||
<div class="progress-bar progress-bar-danger progress-bar-striped" style="width: {{$account->percentage}}%">
|
||||
@if($account->percentage > 50)
|
||||
{{Amount::format($account->difference,false)}}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<!-- green (pct), then blue (100-pct) -->
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success progress-bar-striped" style="width: {{$account->percentage}}%">
|
||||
@if($account->percentage > 50)
|
||||
{{Amount::format($account->difference,false)}}
|
||||
@endif
|
||||
</div>
|
||||
<div class="progress-bar progress-bar-info progress-bar-striped" style="width: {{100 - $account->percentage}}%">
|
||||
@if($account->percentage <= 50)
|
||||
{{Amount::format($account->difference,false)}}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
<!-- end -->
|
||||
<div class="col-lg-2 col-md-2 col-sm-3 col-xs-4">{!! Amount::format($account->endBalance) !!}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -69,7 +116,7 @@
|
||||
<!-- REMINDERS -->
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-calendar-o"></i> Bills
|
||||
<i class="fa fa-calendar-o"></i> <a href="{{route('bills.index')}}">Bills</a>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="bills-chart"></div>
|
||||
@@ -81,7 +128,7 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-money fa-fw"></i>
|
||||
<a href="{{route('accounts.show',$data[1]->id)}}">{{{$data[1]->name}}}</a>
|
||||
<a href="{{route('accounts.show',$data[1]->id)}}">{{{$data[1]->name}}}</a> ({!! Amount::format(Steam::balance($data[1])) !!})
|
||||
|
||||
|
||||
<!-- ACTIONS MENU -->
|
||||
@@ -94,7 +141,7 @@
|
||||
<ul class="dropdown-menu pull-right" role="menu">
|
||||
<li><a href="{{route('transactions.create','withdrawal')}}?account_id={{{$data[1]->id}}}"><i class="fa fa-long-arrow-left fa-fw"></i> New withdrawal</a></li>
|
||||
<li><a href="{{route('transactions.create','deposit')}}?account_id={{{$data[1]->id}}}"><i class="fa fa-long-arrow-right fa-fw"></i> New deposit</a></li>
|
||||
<li><a href="{{route('transactions.create','transfer')}}?account_from_id={{{$data[1]->id}}}"><i class="fa fa-arrows-h fa-fw"></i> New transfer</a></li>
|
||||
<li><a href="{{route('transactions.create','transfer')}}?account_from_id={{{$data[1]->id}}}"><i class="fa fa-fw fa-exchange"></i> New transfer</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -14,13 +14,12 @@
|
||||
// {{{$subTitle}}}
|
||||
@endif
|
||||
</title>
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,700,300italic" type="ext/css" media="all" />
|
||||
<link rel="stylesheet" href="font-awesome/css/font-awesome.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap-theme.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="css/metisMenu.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="css/sb-admin-2.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="font-awesome/css/font-awesome.min.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto2" type="text/css" media="all" />
|
||||
|
||||
<!-- date range -->
|
||||
<link rel="stylesheet" href="css/daterangepicker-bs3.css" type="text/css" media="all" />
|
||||
|
||||
@@ -29,11 +28,6 @@
|
||||
|
||||
@yield('styles')
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
|
||||
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
|
||||
|
@@ -17,8 +17,8 @@
|
||||
<tr>
|
||||
<td>
|
||||
<div class="btn-group btn-group-xs">
|
||||
<a class="btn btn-default btn-xs" href="{{route('accounts.edit',$account->id)}}"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a class="btn btn-danger btn-xs" href="{{route('accounts.delete',$account->id)}}"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
<a class="btn btn-default btn-xs" href="{{route('accounts.edit',$account->id)}}"><i class="fa fa-fw fa-pencil"></i></a>
|
||||
<a class="btn btn-danger btn-xs" href="{{route('accounts.delete',$account->id)}}"><i class="fa fa-fw fa-trash-o"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
<td><a href="{{route('accounts.show',$account->id)}}">{{{$account->name}}}</a></td>
|
||||
|
@@ -14,8 +14,8 @@
|
||||
<tr>
|
||||
<td>
|
||||
<div class="btn-group btn-group-xs">
|
||||
<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>
|
||||
<a href="{{route('bills.edit',$entry->id)}}" class="btn btn-default btn-xs"><i class="fa fa-fw fa-pencil"></i></a>
|
||||
<a href="{{route('bills.delete',$entry->id)}}" class="btn btn-danger btn-xs"><i class="fa fa-fw fa-trash-o"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
|
@@ -13,8 +13,8 @@
|
||||
<tr>
|
||||
<td>
|
||||
<div class="btn-group btn-group-xs">
|
||||
<a href="{{route('categories.edit',$category->id)}}" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a href="{{route('categories.delete',$category->id)}}" class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
<a href="{{route('categories.edit',$category->id)}}" class="btn btn-default btn-xs"><i class="fa fa-fw fa-pencil"></i></a>
|
||||
<a href="{{route('categories.delete',$category->id)}}" class="btn btn-danger btn-xs"><i class="fa fa-fw fa-trash-o"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
@if(is_object($journals) && method_exists($journals, 'render'))
|
||||
{!! $journals->render() !!}
|
||||
@endif
|
||||
<table class="table table-striped table-bordered">
|
||||
<tr>
|
||||
<table class="table table-striped table-bordered sortable-table">
|
||||
<tr class="ignore">
|
||||
<th colspan="2"> </th>
|
||||
<th>Description</th>
|
||||
<th>Amount</th>
|
||||
@@ -21,10 +21,10 @@
|
||||
</tr>
|
||||
@foreach($journals as $journal)
|
||||
@if(!isset($journal->transactions[1]) || !isset($journal->transactions[0]))
|
||||
<tr>
|
||||
<tr class="ignore">
|
||||
<td>
|
||||
<div class="btn-group btn-group-xs">
|
||||
<a href="{{route('transactions.delete',$journal->id)}}" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
<a href="{{route('transactions.delete',$journal->id)}}" class="btn btn-xs btn-danger"><i class="fa fa-fw fa-trash-o"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
<td> </td>
|
||||
@@ -32,11 +32,14 @@
|
||||
<td colspan="7"><em>Invalid journal: Found {{$journal->transactions()->count()}} transaction(s)</td>
|
||||
</tr>
|
||||
@else
|
||||
<tr>
|
||||
<tr class="drag" data-date="{{$journal->date->format('Y-m-d')}}" data-id="{{$journal->id}}">
|
||||
<td>
|
||||
<div class="btn-group btn-group-xs">
|
||||
<a href="{{route('transactions.edit',$journal->id)}}" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a href="{{route('transactions.delete',$journal->id)}}" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
@if($sorting === true)
|
||||
<a href="#" class="handle btn btn-default btn-xs"><i class="fa fa-fw fa-arrows-v"></i></a>
|
||||
@endif
|
||||
<a href="{{route('transactions.edit',$journal->id)}}" class="btn btn-xs btn-default"><i class="fa fa-fw fa-pencil"></i></a>
|
||||
<a href="{{route('transactions.delete',$journal->id)}}" class="btn btn-xs btn-danger"><i class="fa fa-fw fa-trash-o"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
@@ -47,7 +50,7 @@
|
||||
<span class="glyphicon glyphicon-arrow-right" title="Deposit"></span>
|
||||
@endif
|
||||
@if($journal->transactiontype->type == 'Transfer')
|
||||
<span class="glyphicon glyphicon-resize-full" title="Transfer"></span>
|
||||
<i class="fa fa-fw fa-exchange" title="Transfer"></i>
|
||||
@endif
|
||||
@if($journal->transactiontype->type == 'Opening balance')
|
||||
<span class="glyphicon glyphicon-ban-circle" title="Opening balance"></span>
|
||||
|
@@ -2,32 +2,32 @@
|
||||
@foreach($transactions as $journal)
|
||||
<a class="list-group-item" title="{{$journal->date->format('jS M Y')}}" href="{{route('transactions.show',$journal->id)}}">
|
||||
|
||||
@if($journal->transactiontype->type == 'Withdrawal')
|
||||
<i class="fa fa-long-arrow-left fa-fw" title="Withdrawal"></i>
|
||||
@endif
|
||||
@if($journal->transactiontype->type == 'Deposit')
|
||||
<i class="fa fa-long-arrow-right fa-fw" title="Deposit"></i>
|
||||
@endif
|
||||
@if($journal->transactiontype->type == 'Transfer')
|
||||
<i class="fa fa-arrows-h fa-fw" title="Transfer"></i>
|
||||
@if(is_null($journal->type))
|
||||
@if($journal->transactiontype->type == 'Withdrawal')
|
||||
<i class="fa fa-long-arrow-left fa-fw" title="Withdrawal"></i>
|
||||
@endif
|
||||
@if($journal->transactiontype->type == 'Deposit')
|
||||
<i class="fa fa-long-arrow-right fa-fw" title="Deposit"></i>
|
||||
@endif
|
||||
@if($journal->transactiontype->type == 'Transfer')
|
||||
<i class="fa fa-fw fa-exchange" title="Transfer"></i>
|
||||
@endif
|
||||
@else
|
||||
@if($journal->type == 'Withdrawal')
|
||||
<i class="fa fa-long-arrow-left fa-fw" title="Withdrawal"></i>
|
||||
@endif
|
||||
@if($journal->type == 'Deposit')
|
||||
<i class="fa fa-long-arrow-right fa-fw" title="Deposit"></i>
|
||||
@endif
|
||||
@if($journal->type == 'Transfer')
|
||||
<i class="fa fa-fw fa-exchange" title="Transfer"></i>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
{{{$journal->description}}}
|
||||
|
||||
<span class="pull-right small">
|
||||
@if(isset($account))
|
||||
@foreach($journal->transactions as $index => $t)
|
||||
@if($t->account_id == $account->id)
|
||||
{!! Amount::formatTransaction($t) !!}
|
||||
@endif
|
||||
@endforeach
|
||||
@else
|
||||
@foreach($journal->transactions as $index => $t)
|
||||
@if($index == 0)
|
||||
{!! Amount::formatTransaction($t) !!}
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
{!! Amount::formatJournal($journal) !!}
|
||||
</span>
|
||||
|
||||
</a>
|
||||
|
@@ -24,8 +24,10 @@
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<div class="btn-group">
|
||||
@if($reminder->active === true)
|
||||
@if($reminder->notnow !== true)
|
||||
<a class="btn btn-warning" href="{{route('reminders.dismiss',$reminder->id)}}">Dismiss</a>
|
||||
@endif
|
||||
@if($reminder->active === true)
|
||||
<a class="btn btn-success" href="{{route('reminders.act',$reminder->id)}}">Act</a>
|
||||
@endif
|
||||
</div>
|
||||
|
@@ -141,7 +141,7 @@
|
||||
<a @if($isDeposit)class="active"@endif href="{{route('transactions.index','deposit')}}"><i class="fa fa-long-arrow-right fa-fw"></i> Revenue / income</a>
|
||||
</li>
|
||||
<li>
|
||||
<a @if($isTransfer)class="active"@endif href="{{route('transactions.index','transfers')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfers</a>
|
||||
<a @if($isTransfer)class="active"@endif href="{{route('transactions.index','transfers')}}"><i class="fa fa-fw fa-exchange" title="Transfer"></i> Transfers</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
<a @if($isDeposit)class="active"@endif href="{{route('transactions.create','deposit')}}"><i class="fa fa-long-arrow-right fa-fw"></i> Deposit</a>
|
||||
</li>
|
||||
<li>
|
||||
<a @if($isTransfer)class="active"@endif href="{{route('transactions.create','transfer')}}"><i class="fa fa-arrows-h fa-fw"></i> Transfer</a>
|
||||
<a @if($isTransfer)class="active"@endif href="{{route('transactions.create','transfer')}}"><i class="fa fa-fw fa-exchange" title="Transfer"></i> Transfer</a>
|
||||
</li>
|
||||
<li>
|
||||
<a @if($isBill)class="active"@endif href="{{route('bills.create')}}"><i class="fa fa-calendar-o fa-fw"></i> Bill</a>
|
||||
|
@@ -8,12 +8,13 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row" id="sortable">
|
||||
@foreach($piggyBanks as $piggyBank)
|
||||
<div class="col-lg-3 col-md-4 col-sm-12 col-xs-12">
|
||||
<div class="col-lg-3 col-md-4 col-sm-12 col-xs-12" data-id="{{$piggyBank->id}}">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-fw fa-rocket"></i> <a href="{{route('piggy-banks.show',$piggyBank->id)}}" title="{{{$piggyBank->name}}}">{{{$piggyBank->name}}}</a>
|
||||
<i class="loadSpin"></i>
|
||||
<i class="fa fa-fw fa-bars handle"></i> <a href="{{route('piggy-banks.show',$piggyBank->id)}}" title="{{{$piggyBank->order}}}">{{{$piggyBank->name}}}</a>
|
||||
|
||||
<!-- ACTIONS MENU -->
|
||||
<div class="pull-right">
|
||||
@@ -62,34 +63,15 @@
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- One block -->
|
||||
<!-- <div class="col-lg-1 col-md-4 col-sm-4 col-xs-4">
|
||||
{!! Amount::format($piggyBank->savedSoFar,true) !!}
|
||||
</div> -->
|
||||
<!-- One block -->
|
||||
|
||||
<!-- One block -->
|
||||
<!-- <div class="col-lg-1 col-md-6 col-sm-6 col-xs-6">
|
||||
{!! Amount::format($piggyBank->targetamount,true) !!}
|
||||
</div> -->
|
||||
<!-- One block -->
|
||||
<!-- <div class="col-lg-1 col-md-6 col-sm-6 col-xs-6">
|
||||
@if($piggyBank->leftToSave > 0)
|
||||
{!! Amount::format($piggyBank->leftToSave) !!}
|
||||
@endif
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-4 col-md-4 col-sm-4 col-xs4">
|
||||
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
|
||||
<span title="Saved so far">{!! Amount::format($piggyBank->savedSoFar,true) !!}</span>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-4 col-sm-4 col-xs4">
|
||||
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4" style="text-align: center;">
|
||||
<span title="Target amount">{!! Amount::format($piggyBank->targetamount,true) !!}</span>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-4 col-sm-4 col-xs4">
|
||||
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4" style="text-align: right;">
|
||||
@if($piggyBank->leftToSave > 0)
|
||||
<span title="Left to save">{!! Amount::format($piggyBank->leftToSave) !!}</span>
|
||||
@endif
|
||||
@@ -148,5 +130,9 @@
|
||||
|
||||
@stop
|
||||
@section('scripts')
|
||||
<script type="text/javascript">
|
||||
var token = "{{csrf_token()}}";
|
||||
</script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript" src="js/piggy-banks.js"></script>
|
||||
@stop
|
||||
|
@@ -2,7 +2,8 @@
|
||||
<table class="table table-bordered table-striped table-condensed">
|
||||
@foreach($journals as $journal)
|
||||
<tr>
|
||||
<td><a title="Unlink" data-id="{{$journal->id}}" data-parent="{{$parent->id}}" class="btn unrelate btn-xs btn-default" href="#"><span class="glyphicon glyphicon-resize-full"></span></a></td>
|
||||
<td>
|
||||
<a title="Unlink" data-id="{{$journal->id}}" data-parent="{{$parent->id}}" class="btn unrelate btn-xs btn-default" href="#"><i class="fa fa-fw fa-expand"></i></a></td>
|
||||
<td>
|
||||
@if($journal->transactiontype->type == 'Withdrawal')
|
||||
<i class="fa fa-long-arrow-left fa-fw" title="Withdrawal"></i>
|
||||
@@ -11,7 +12,7 @@
|
||||
<i class="fa fa-long-arrow-right fa-fw" title="Deposit"></i>
|
||||
@endif
|
||||
@if($journal->transactiontype->type == 'Transfer')
|
||||
<i class="fa fa-arrows-h fa-fw" title="Transfer"></i>
|
||||
<i class="fa fa-fw fa-exchange" title="Transfer"></i>
|
||||
@endif
|
||||
</td>
|
||||
<td>{{$journal->date->format('jS M Y')}}</td>
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<table class="table table-bordered table-striped table-condensed">
|
||||
@foreach($journals as $journal)
|
||||
<tr>
|
||||
<td><a title="Link" data-id="{{$journal->id}}" data-parent="{{$parent->id}}" class="btn relate btn-xs btn-default" href="#"><span class="glyphicon glyphicon-resize-small"></span></a></td>
|
||||
<td><a title="Link" data-id="{{$journal->id}}" data-parent="{{$parent->id}}" class="btn relate btn-xs btn-default" href="#"><i class="fa fa-fw fa-expand"></i></a></td>
|
||||
<td>
|
||||
@if($journal->transactiontype->type == 'Withdrawal')
|
||||
<i class="fa fa-long-arrow-left fa-fw" title="Withdrawal"></i>
|
||||
@@ -12,7 +12,7 @@
|
||||
<i class="fa fa-long-arrow-right fa-fw" title="Deposit"></i>
|
||||
@endif
|
||||
@if($journal->transactiontype->type == 'Transfer')
|
||||
<i class="fa fa-arrows-h fa-fw" title="Transfer"></i>
|
||||
<i class="fa fa-fw fa-exchange" title="Transfer"></i>
|
||||
@endif
|
||||
</td>
|
||||
<td>{{$journal->date->format('jS M Y')}}</td>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<h4 class="modal-title">No budget bla bla.</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@include('list.journals-full')
|
||||
@include('list.journals-full',['sorting' => false])
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
|
@@ -77,7 +77,7 @@
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-arrows-h fa-fw"></i>
|
||||
<i class="fa fa-fw fa-exchange" title="Transfer"></i>
|
||||
Income vs. expense
|
||||
</div>
|
||||
<?php
|
||||
|
@@ -10,7 +10,7 @@
|
||||
<i class="fa fa-repeat"></i> Transactions ({{$result['transactions']->count()}})
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@include('list.journals-small',['journals' => $result['transactions']])
|
||||
@include('list.journals-tiny',['transactions' => $result['transactions']])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -7,10 +7,18 @@
|
||||
<div class="panel-heading">
|
||||
<i class="fa {{$subTitleIcon}}"></i> {{{$subTitle}}}
|
||||
</div>
|
||||
@include('list.journals-full')
|
||||
@include('list.journals-full',['sorting' => false])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
||||
@section('scripts')
|
||||
<script type="text/javascript">
|
||||
var token = "{{csrf_token()}}";
|
||||
</script>
|
||||
<script src="js/jquery-ui.min.js" type="text/javascript"></script>
|
||||
<script src="js/transactions.js" type="text/javascript"></script>
|
||||
|
||||
@stop
|
@@ -145,7 +145,7 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default" href="{{route('transactions.edit',$journal->id)}}"><span class="glyphicon glyphicon-pencil"></span> Edit</a> <a href="{{route('transactions.delete',$journal->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> Delete</a>
|
||||
<a class="btn btn-default" href="{{route('transactions.edit',$journal->id)}}"><i class="fa fa-fw fa-pencil"></i> Edit</a> <a href="{{route('transactions.delete',$journal->id)}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
1
tests/database/.gitignore
vendored
Normal file
1
tests/database/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.sqlite
|
Reference in New Issue
Block a user