mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-12-23 19:51:24 +00:00
Compare commits
109 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb1462b4d9 | ||
|
|
8475757716 | ||
|
|
20ffd8d61b | ||
|
|
8601428c4c | ||
|
|
59998573ee | ||
|
|
293cd72001 | ||
|
|
22ab9ebb2f | ||
|
|
9136e592d3 | ||
|
|
ed8e392616 | ||
|
|
e57ce6e644 | ||
|
|
8204e46086 | ||
|
|
9e365d9f80 | ||
|
|
6b40a933e9 | ||
|
|
8520a5002f | ||
|
|
b38ed06f6e | ||
|
|
48427b1143 | ||
|
|
5d505f4ed0 | ||
|
|
0c02a08954 | ||
|
|
0221bd0f80 | ||
|
|
28216cbcb5 | ||
|
|
3e08a8cd6b | ||
|
|
67fafdeef7 | ||
|
|
cc82505b66 | ||
|
|
fd5f075f63 | ||
|
|
a115960411 | ||
|
|
e9fa4ca816 | ||
|
|
75d92bc7f0 | ||
|
|
74aa6e911e | ||
|
|
9d000c1898 | ||
|
|
b2254875b2 | ||
|
|
78d04230d5 | ||
|
|
1c04477393 | ||
|
|
2a9679c94e | ||
|
|
6009f8ecde | ||
|
|
35cdbec70a | ||
|
|
0faef542c1 | ||
|
|
8b085af6a1 | ||
|
|
e3b11a9eb2 | ||
|
|
72fc88f3c6 | ||
|
|
a5b759f268 | ||
|
|
6a9ffae25d | ||
|
|
64c031c7fe | ||
|
|
720926c50d | ||
|
|
36ec974284 | ||
|
|
cff77c39e2 | ||
|
|
056a0a1736 | ||
|
|
f301da83c6 | ||
|
|
5362231efa | ||
|
|
4bb14cad73 | ||
|
|
7f5188f5a4 | ||
|
|
a80b7aac6c | ||
|
|
83f32478fa | ||
|
|
7578ec6801 | ||
|
|
e14a32f76f | ||
|
|
58faa189ac | ||
|
|
9b4f87d44a | ||
|
|
7830a64170 | ||
|
|
8f0fa02107 | ||
|
|
e000fb5d80 | ||
|
|
566fadad15 | ||
|
|
cf23858c10 | ||
|
|
216a223617 | ||
|
|
638f38d823 | ||
|
|
98ee70f04e | ||
|
|
b365db5a4b | ||
|
|
02e55496df | ||
|
|
e11e53913a | ||
|
|
f8a5fb4225 | ||
|
|
3a49450461 | ||
|
|
3c375fb955 | ||
|
|
011fea2cc6 | ||
|
|
a079eec2cb | ||
|
|
776b37f4ea | ||
|
|
a4d8bbe3da | ||
|
|
72166743fa | ||
|
|
c4312c0b11 | ||
|
|
38ba645415 | ||
|
|
ac12a47071 | ||
|
|
bea321939e | ||
|
|
210f84b6ea | ||
|
|
d4c642741f | ||
|
|
e6b1b58379 | ||
|
|
8d982c1a90 | ||
|
|
be10e836dc | ||
|
|
9be05e7e17 | ||
|
|
bd96b2819f | ||
|
|
f601af3da0 | ||
|
|
70a01c082b | ||
|
|
bcf066ead7 | ||
|
|
24dd3578ed | ||
|
|
d5c39d54d8 | ||
|
|
6e3f6abc67 | ||
|
|
463201df2c | ||
|
|
a7501c396f | ||
|
|
4c8bc49a7e | ||
|
|
f254674f88 | ||
|
|
a97c267378 | ||
|
|
eaa947894b | ||
|
|
fb3a26510b | ||
|
|
bfe8b14e49 | ||
|
|
afb47eb742 | ||
|
|
ba97f96288 | ||
|
|
ecbafb8f4b | ||
|
|
12d3800d67 | ||
|
|
d586b82372 | ||
|
|
ba9877c9b4 | ||
|
|
907933f3df | ||
|
|
2e91d21a88 | ||
|
|
625070a5b9 |
@@ -1,3 +1,3 @@
|
||||
src_dir: .
|
||||
coverage_clover: storage/coverage/clover.xml
|
||||
json_path: storage/coverage/coveralls-upload.json
|
||||
json_path: storage/coverage/coveralls-upload.json
|
||||
|
||||
@@ -12,5 +12,7 @@ CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
|
||||
EMAIL_SMTP=
|
||||
EMAIL_DRIVER=smtp
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
ANALYTICS_ID=
|
||||
@@ -11,3 +11,7 @@ DB_PASSWORD=secret
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
|
||||
EMAIL_SMTP=
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
||||
ANALYTICS_ID=ABC
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,7 +3,6 @@
|
||||
composer.phar
|
||||
Thumbs.db
|
||||
.idea/
|
||||
.DS_Store
|
||||
tests/_output/*
|
||||
_ide_helper.php
|
||||
/build/logs/clover.xml
|
||||
@@ -27,4 +26,5 @@ db.sqlite-journal
|
||||
tests/_output/*
|
||||
.env
|
||||
clover.xml
|
||||
node_modules/
|
||||
node_modules/
|
||||
addNewLines.php
|
||||
|
||||
@@ -11,12 +11,9 @@ addons:
|
||||
repo_token: 26489f9e854fcdf7e7660ba29c1455694685465b1f90329a79f7d2bf448acb61
|
||||
|
||||
install:
|
||||
- rm composer.lock
|
||||
- composer install
|
||||
- composer update
|
||||
- php artisan env
|
||||
- mv -v .env.testing .env
|
||||
- touch tests/database/db.sqlite
|
||||
- php artisan migrate --seed
|
||||
|
||||
script:
|
||||
- phpunit --debug
|
||||
|
||||
19
README.md
19
README.md
@@ -1,11 +1,12 @@
|
||||
Firefly III (v3.3.4)
|
||||
Firefly III (v3.3.7)
|
||||
===========
|
||||
|
||||
[](https://travis-ci.org/JC5/firefly-iii)
|
||||
[](http://stillmaintained.com/JC5/firefly-iii)
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
[](https://coveralls.io/r/JC5/firefly-iii?branch=master)
|
||||
[](https://coveralls.io/r/JC5/firefly-iii?branch=develop)
|
||||
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
@@ -25,9 +26,14 @@ To install and use Firefly III, please read [the installation guide](https://git
|
||||
|
||||
## Current features
|
||||
|
||||
- [A double-entry bookkeeping system](http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system);
|
||||
- [A double-entry bookkeeping system](https://en.wikipedia.org/wiki/Double-entry_bookkeeping_system);
|
||||
- You can store, edit and remove withdrawals, deposits and transfers. This allows you full financial management;
|
||||
- It's possible to create, change and manage money using _budgets_;
|
||||
- You can manage different types of accounts
|
||||
- Asset accounts
|
||||
- Shared asset accounts (household accounts)
|
||||
- Saving accounts
|
||||
- Credit cards
|
||||
- It's possible to create, change and manage money using _[budgets](https://en.wikipedia.org/wiki/Envelope_system)_;
|
||||
- Organize transactions using categories;
|
||||
- Save towards a goal using piggy banks;
|
||||
- Predict and anticipate bills;
|
||||
@@ -48,9 +54,7 @@ Firefly III will feature, but does not feature yet:
|
||||
|
||||
|
||||
- More control over other resources outside of personal finance
|
||||
- Accounts shared with a partner (household accounts)
|
||||
- Debts
|
||||
- Credit cards
|
||||
- More test-coverage;
|
||||
- Firefly will be able to split transactions; a single purchase can be split in multiple entries, for more fine-grained control.
|
||||
- Firefly will be able to join transactions.
|
||||
@@ -73,7 +77,4 @@ Some stuff has been removed:
|
||||
## Current state
|
||||
I have the basics up and running. Test coverage is currently coming, slowly.
|
||||
|
||||
Although I have not checked extensively, some forms and views have CSRF vulnerabilities. This is because not all
|
||||
views escape all characters by default. Will be fixed.
|
||||
|
||||
Questions, ideas or other things to contribute? [Let me know](https://github.com/JC5/firefly-iii/issues/new)!
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Foundation\Inspiring;
|
||||
|
||||
/**
|
||||
* Class Inspire
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class Inspire extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Display an inspiring quote';
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'inspire';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->comment(PHP_EOL . Inspiring::quote() . PHP_EOL);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,6 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected $commands
|
||||
= [
|
||||
'FireflyIII\Console\Commands\Inspire',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -30,8 +29,6 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
$schedule->command('inspire')
|
||||
->hourly();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
@@ -10,24 +8,25 @@ use Illuminate\Queue\SerializesModels;
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
class JournalCreated extends Event {
|
||||
class JournalCreated extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
use SerializesModels;
|
||||
|
||||
public $journal;
|
||||
public $piggyBankId;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(TransactionJournal $journal, $piggyBankId)
|
||||
{
|
||||
//
|
||||
$this->journal = $journal;
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(TransactionJournal $journal, $piggyBankId)
|
||||
{
|
||||
//
|
||||
$this->journal = $journal;
|
||||
$this->piggyBankId = $piggyBankId;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
|
||||
use FireflyIII\Events\Event;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class JournalSaved extends Event {
|
||||
class JournalSaved extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
use SerializesModels;
|
||||
|
||||
public $journal;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(TransactionJournal $journal)
|
||||
{
|
||||
//
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(TransactionJournal $journal)
|
||||
{
|
||||
//
|
||||
$this->journal = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class ConnectJournalToPiggyBank
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = $event->journal;
|
||||
$piggyBankId = $event->piggyBankId;
|
||||
if(intval($piggyBankId) < 1) {
|
||||
if (intval($piggyBankId) < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,8 @@ 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'));
|
||||
Log::debug('Found no repetition for piggy bank for date ' . $journal->date->format('Y M d'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\JournalDeleted;
|
||||
use Illuminate\Contracts\Queue\ShouldBeQueued;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
|
||||
/**
|
||||
* Class JournalDeletedHandler
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class JournalDeletedHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use App;
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use Log;
|
||||
use App;
|
||||
|
||||
/**
|
||||
* Class RescanJournal
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
/**
|
||||
* Class UpdateJournalConnection
|
||||
*
|
||||
* @package FireflyIII\Handlers\Events
|
||||
*/
|
||||
class UpdateJournalConnection
|
||||
{
|
||||
|
||||
@@ -31,8 +35,8 @@ class UpdateJournalConnection
|
||||
|
||||
// get the event connected to this journal:
|
||||
/** @var PiggyBankEvent $event */
|
||||
$event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first();
|
||||
if(is_null($event)) {
|
||||
$event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first();
|
||||
if (is_null($event)) {
|
||||
return;
|
||||
}
|
||||
$piggyBank = $event->piggyBank()->first();
|
||||
|
||||
@@ -95,7 +95,6 @@ class ReminderHelper implements ReminderHelperInterface
|
||||
|
||||
if (!is_null($piggyBank->targetdate)) {
|
||||
// count back until now.
|
||||
// echo 'Count back!<br>';
|
||||
$start = $piggyBank->targetdate;
|
||||
$end = $piggyBank->startdate;
|
||||
|
||||
@@ -143,4 +142,4 @@ class ReminderHelper implements ReminderHelperInterface
|
||||
return 'Add ' . Amount::format($reminder->metadata->perReminder) . ' to fill this piggy bank on ' . $piggyBank->targetdate->format('jS F Y');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
|
||||
namespace FireflyIII\Helpers\Reminders;
|
||||
|
||||
use FireflyIII\Models\Reminder;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Reminder;
|
||||
|
||||
/**
|
||||
* Interface ReminderHelperInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Reminders
|
||||
*/
|
||||
interface ReminderHelperInterface {
|
||||
interface ReminderHelperInterface
|
||||
{
|
||||
/**
|
||||
* Takes a reminder, finds the piggy bank and tells you what to do now.
|
||||
* Aka how much money to put in.
|
||||
@@ -48,4 +49,4 @@ interface ReminderHelperInterface {
|
||||
* @return Reminder
|
||||
*/
|
||||
public function createReminder(PiggyBank $piggyBank, Carbon $start, Carbon $end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
@@ -40,17 +41,20 @@ class ReportHelper implements ReportHelperInterface
|
||||
* This method gets some kind of list for a monthly overview.
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param bool $showSharedReports
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBudgetsForMonth(Carbon $date)
|
||||
public function getBudgetsForMonth(Carbon $date, $showSharedReports = false)
|
||||
{
|
||||
/** @var \FireflyIII\Helpers\Report\ReportQueryInterface $query */
|
||||
$query = App::make('FireflyIII\Helpers\Report\ReportQueryInterface');
|
||||
|
||||
$start = clone $date;
|
||||
$start->startOfMonth();
|
||||
$end = clone $date;
|
||||
$end->endOfMonth();
|
||||
// all budgets
|
||||
$set = Auth::user()->budgets()
|
||||
$set = Auth::user()->budgets()->orderBy('budgets.name', 'ASC')
|
||||
->leftJoin(
|
||||
'budget_limits', function (JoinClause $join) use ($date) {
|
||||
$join->on('budget_limits.budget_id', '=', 'budgets.id')->where('budget_limits.startdate', '=', $date->format('Y-m-d'));
|
||||
@@ -58,22 +62,24 @@ class ReportHelper implements ReportHelperInterface
|
||||
)
|
||||
->get(['budgets.*', 'budget_limits.amount as amount']);
|
||||
|
||||
$budgets = Steam::makeArray($set);
|
||||
$amountSet = $query->journalsByBudget($start, $end, $showSharedReports);
|
||||
$amounts = Steam::makeArray($amountSet);
|
||||
$budgets = Steam::mergeArrays($budgets, $amounts);
|
||||
$budgets[0]['spent'] = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0;
|
||||
$budgets[0]['amount'] = isset($budgets[0]['amount']) ? $budgets[0]['amount'] : 0.0;
|
||||
$budgets[0]['name'] = 'No budget';
|
||||
|
||||
$budgets = $this->_helper->makeArray($set);
|
||||
$amountSet = $this->_queries->journalsByBudget($start, $end);
|
||||
$amounts = $this->_helper->makeArray($amountSet);
|
||||
$combined = $this->_helper->mergeArrays($budgets, $amounts);
|
||||
$combined[0]['spent'] = isset($combined[0]['spent']) ? $combined[0]['spent'] : 0.0;
|
||||
$combined[0]['amount'] = isset($combined[0]['amount']) ? $combined[0]['amount'] : 0.0;
|
||||
$combined[0]['name'] = 'No budget';
|
||||
|
||||
// find transactions to shared expense accounts, which are without a budget by default:
|
||||
$transfers = $this->_queries->sharedExpenses($start, $end);
|
||||
foreach ($transfers as $transfer) {
|
||||
$combined[0]['spent'] += floatval($transfer->amount) * -1;
|
||||
// find transactions to shared asset accounts, which are without a budget by default:
|
||||
// which is only relevant when shared asset accounts are hidden.
|
||||
if ($showSharedReports === false) {
|
||||
$transfers = $query->sharedExpenses($start, $end);
|
||||
foreach ($transfers as $transfer) {
|
||||
$budgets[0]['spent'] += floatval($transfer->amount) * -1;
|
||||
}
|
||||
}
|
||||
|
||||
return $combined;
|
||||
return $budgets;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,6 +119,9 @@ class ReportHelper implements ReportHelperInterface
|
||||
$years[] = $start->format('Y');
|
||||
$start->addYear();
|
||||
}
|
||||
$years[] = Carbon::now()->format('Y');
|
||||
// force the current year.
|
||||
$years = array_unique($years);
|
||||
|
||||
return $years;
|
||||
}
|
||||
@@ -168,4 +177,4 @@ class ReportHelper implements ReportHelperInterface
|
||||
|
||||
return $report;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,4 +55,4 @@ interface ReportHelperInterface
|
||||
* @return array
|
||||
*/
|
||||
public function yearBalanceReport(Carbon $date, $showSharedReports = false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use DB;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
use Steam;
|
||||
@@ -87,9 +89,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')
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->whereNotNull('transaction_group_transaction_journal.transaction_group_id')
|
||||
->get(
|
||||
[
|
||||
@@ -143,7 +145,7 @@ class ReportQuery implements ReportQueryInterface
|
||||
)
|
||||
->orderBy('accounts.name', 'ASC')
|
||||
->where(
|
||||
function (Builder $query) use ($showSharedReports) {
|
||||
function (Builder $query) {
|
||||
|
||||
$query->where('account_meta.data', '!=', '"sharedAsset"');
|
||||
$query->orWhereNull('account_meta.data');
|
||||
@@ -174,26 +176,9 @@ class ReportQuery implements ReportQueryInterface
|
||||
*/
|
||||
public function getBudgetSummary(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
$set = TransactionJournal::
|
||||
leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('budgets', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->where('accounts.id', $account->id)
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->groupBy('budgets.id')
|
||||
->orderBy('budgets.name', 'ASC')
|
||||
->get(['budgets.id', 'budgets.name', DB::Raw('SUM(`transactions`.`amount`) as `amount`')]);
|
||||
$query = $this->queryJournalsNoBudget($account, $start, $end);
|
||||
|
||||
return $set;
|
||||
return $query->get(['budgets.id', 'budgets.name', DB::Raw('SUM(`transactions`.`amount`) as `amount`')]);
|
||||
|
||||
}
|
||||
|
||||
@@ -209,26 +194,9 @@ class ReportQuery implements ReportQueryInterface
|
||||
*/
|
||||
public function getTransactionsWithoutBudget(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
$set = TransactionJournal::
|
||||
leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('budgets', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->where('accounts.id', $account->id)
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->whereNull('budgets.id')
|
||||
->orderBy('transaction_journals.date', 'ASC')
|
||||
->get(['budgets.name', 'transactions.amount', 'transaction_journals.*']);
|
||||
$query = $this->queryJournalsNoBudget($account, $start, $end);
|
||||
|
||||
return $set;
|
||||
return $query->get(['budgets.name', 'transactions.amount', 'transaction_journals.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,43 +212,20 @@ class ReportQuery implements ReportQueryInterface
|
||||
*/
|
||||
public function incomeByPeriod(Carbon $start, Carbon $end, $showSharedReports = false)
|
||||
{
|
||||
$query = TransactionJournal::
|
||||
leftJoin(
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_from', function (JoinClause $join) {
|
||||
$join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_to', function (JoinClause $join) {
|
||||
$join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||
$query = $this->queryJournalsWithTransactions($start, $end);
|
||||
if ($showSharedReports === false) {
|
||||
// only get deposits not to a shared account
|
||||
// and transfers to a shared account.
|
||||
$query->where(
|
||||
function ($query) {
|
||||
function (Builder $query) {
|
||||
$query->where(
|
||||
function ($q) {
|
||||
function (Builder $q) {
|
||||
$q->where('transaction_types.type', 'Deposit');
|
||||
$q->where('acm_to.data', '!=', '"sharedAsset"');
|
||||
}
|
||||
);
|
||||
$query->orWhere(
|
||||
function ($q) {
|
||||
function (Builder $q) {
|
||||
$q->where('transaction_types.type', 'Transfer');
|
||||
$q->where('acm_from.data', '=', '"sharedAsset"');
|
||||
}
|
||||
@@ -291,11 +236,10 @@ class ReportQuery implements ReportQueryInterface
|
||||
// any deposit is fine.
|
||||
$query->where('transaction_types.type', 'Deposit');
|
||||
}
|
||||
$query->before($end)->after($start)
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->groupBy('t_from.account_id')->orderBy('transaction_journals.date');
|
||||
$query->groupBy('t_from.account_id')->orderBy('transaction_journals.date');
|
||||
|
||||
return $query->get(
|
||||
// get everything, decrypt and return
|
||||
$data = $query->get(
|
||||
['transaction_journals.id',
|
||||
'transaction_journals.description',
|
||||
'transaction_journals.encrypted',
|
||||
@@ -303,8 +247,19 @@ class ReportQuery implements ReportQueryInterface
|
||||
DB::Raw('SUM(`t_to`.`amount`) as `amount`'),
|
||||
'transaction_journals.date',
|
||||
't_from.account_id as account_id',
|
||||
'ac_from.name as name']
|
||||
'ac_from.name as name',
|
||||
'ac_from.encrypted as account_encrypted'
|
||||
]
|
||||
);
|
||||
|
||||
$data->each(
|
||||
function (Model $object) {
|
||||
// $object->description = intval($object->encrypted);
|
||||
$object->name = intval($object->account_encrypted) == 1 ? Crypt::decrypt($object->name) : $object->name;
|
||||
}
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,7 +337,15 @@ class ReportQuery implements ReportQueryInterface
|
||||
->groupBy('categories.id')
|
||||
->orderBy('amount');
|
||||
|
||||
return $query->get(['categories.id', 'categories.name', DB::Raw('SUM(`transactions`.`amount`) AS `amount`')]);
|
||||
$data = $query->get(['categories.id', 'categories.encrypted', 'categories.name', DB::Raw('SUM(`transactions`.`amount`) AS `amount`')]);
|
||||
// decrypt data:
|
||||
$data->each(
|
||||
function (Model $object) {
|
||||
$object->name = intval($object->encrypted) == 1 ? Crypt::decrypt($object->name) : $object->name;
|
||||
}
|
||||
);
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
@@ -400,42 +363,20 @@ class ReportQuery implements ReportQueryInterface
|
||||
*/
|
||||
public function journalsByExpenseAccount(Carbon $start, Carbon $end, $showSharedReports = false)
|
||||
{
|
||||
$query = TransactionJournal::leftJoin(
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_from', function (JoinClause $join) {
|
||||
$join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_to', function (JoinClause $join) {
|
||||
$join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||
|
||||
$query = $this->queryJournalsWithTransactions($start, $end);
|
||||
if ($showSharedReports === false) {
|
||||
// get all withdrawals not from a shared accounts
|
||||
// and all transfers to a shared account
|
||||
$query->where(
|
||||
function ($query) {
|
||||
function (Builder $query) {
|
||||
$query->where(
|
||||
function ($q) {
|
||||
function (Builder $q) {
|
||||
$q->where('transaction_types.type', 'Withdrawal');
|
||||
$q->where('acm_from.data', '!=', '"sharedAsset"');
|
||||
}
|
||||
);
|
||||
$query->orWhere(
|
||||
function ($q) {
|
||||
function (Builder $q) {
|
||||
$q->where('transaction_types.type', 'Transfer');
|
||||
$q->where('acm_to.data', '=', '"sharedAsset"');
|
||||
}
|
||||
@@ -446,13 +387,21 @@ class ReportQuery implements ReportQueryInterface
|
||||
// any withdrawal goes:
|
||||
$query->where('transaction_types.type', 'Withdrawal');
|
||||
}
|
||||
$query->before($end)
|
||||
->after($start)
|
||||
$query->before($end)->after($start)
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->groupBy('t_to.account_id')
|
||||
->orderBy('amount', 'DESC');
|
||||
|
||||
return $query->get(['t_to.account_id as id', 'ac_to.name as name', DB::Raw('SUM(t_to.amount) as `amount`')]);
|
||||
$data = $query->get(['t_to.account_id as id', 'ac_to.name as name', 'ac_to.encrypted', DB::Raw('SUM(t_to.amount) as `amount`')]);
|
||||
|
||||
// decrypt
|
||||
$data->each(
|
||||
function (Model $object) {
|
||||
$object->name = intval($object->encrypted) == 1 ? Crypt::decrypt($object->name) : $object->name;
|
||||
}
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -466,44 +415,21 @@ class ReportQuery implements ReportQueryInterface
|
||||
*/
|
||||
public function journalsByRevenueAccount(Carbon $start, Carbon $end, $showSharedReports = false)
|
||||
{
|
||||
$query = TransactionJournal::
|
||||
leftJoin(
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_from', function (JoinClause $join) {
|
||||
$join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_to', function (JoinClause $join) {
|
||||
$join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||
$query = $this->queryJournalsWithTransactions($start, $end);
|
||||
if ($showSharedReports === false) {
|
||||
|
||||
// show queries where transfer type is deposit, and its not to a shared account
|
||||
// or where its a transfer and its from a shared account (both count as incomes)
|
||||
$query->where(
|
||||
function ($query) {
|
||||
function (Builder $query) {
|
||||
$query->where(
|
||||
function ($q) {
|
||||
function (Builder $q) {
|
||||
$q->where('transaction_types.type', 'Deposit');
|
||||
$q->where('acm_to.data', '!=', '"sharedAsset"');
|
||||
}
|
||||
);
|
||||
$query->orWhere(
|
||||
function ($q) {
|
||||
function (Builder $q) {
|
||||
$q->where('transaction_types.type', 'Transfer');
|
||||
$q->where('acm_from.data', '=', '"sharedAsset"');
|
||||
}
|
||||
@@ -514,11 +440,20 @@ class ReportQuery implements ReportQueryInterface
|
||||
// any deposit goes:
|
||||
$query->where('transaction_types.type', 'Deposit');
|
||||
}
|
||||
$query->before($end)->after($start)
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->groupBy('t_from.account_id')->orderBy('amount');
|
||||
|
||||
return $query->get(['t_from.account_id as account_id', 'ac_from.name as name', DB::Raw('SUM(t_from.amount) as `amount`')]);
|
||||
$query->groupBy('t_from.account_id')->orderBy('amount');
|
||||
|
||||
$data = $query->get(
|
||||
['t_from.account_id as account_id', 'ac_from.name as name', 'ac_from.encrypted as encrypted', DB::Raw('SUM(t_from.amount) as `amount`')]
|
||||
);
|
||||
// decrypt
|
||||
$data->each(
|
||||
function (Model $object) {
|
||||
$object->name = intval($object->encrypted) == 1 ? Crypt::decrypt($object->name) : $object->name;
|
||||
}
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -604,4 +539,74 @@ class ReportQuery implements ReportQueryInterface
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* This query will get all transaction journals and budget information for a specified account
|
||||
* in a certain date range, where the transaction journal does not have a budget.
|
||||
* There is no get() specified, this is up to the method itself.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function queryJournalsNoBudget(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
return TransactionJournal::
|
||||
leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('budgets', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->where('accounts.id', $account->id)
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->groupBy('budgets.id')
|
||||
->orderBy('budgets.name', 'ASC');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Builder
|
||||
*/
|
||||
protected function queryJournalsWithTransactions(Carbon $start, Carbon $end)
|
||||
{
|
||||
$query = TransactionJournal::
|
||||
leftJoin(
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_from', function (JoinClause $join) {
|
||||
$join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_to', function (JoinClause $join) {
|
||||
$join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||
$query->before($end)->after($start)->where('transaction_journals.user_id', Auth::user()->id);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -163,4 +163,4 @@ interface ReportQueryInterface
|
||||
* @return Collection
|
||||
*/
|
||||
public function sharedExpensesByCategory(Carbon $start, Carbon $end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
@@ -83,6 +84,7 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function edit(Account $account, AccountRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$what = Config::get('firefly.shortNamesByFullName')[$account->accountType->type];
|
||||
$subTitle = 'Edit ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"';
|
||||
$subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what);
|
||||
@@ -92,15 +94,19 @@ class AccountController extends Controller
|
||||
|
||||
// the opening balance is tricky:
|
||||
$openingBalanceAmount = null;
|
||||
|
||||
if ($openingBalance) {
|
||||
$transaction = $openingBalance->transactions()->where('account_id', $account->id)->first();
|
||||
$transaction = $repository->getFirstTransaction($openingBalance, $account);
|
||||
$openingBalanceAmount = $transaction->amount;
|
||||
}
|
||||
|
||||
$preFilled = [
|
||||
'accountRole' => $account->getMeta('accountRole'),
|
||||
'openingBalanceDate' => $openingBalance ? $openingBalance->date->format('Y-m-d') : null,
|
||||
'openingBalance' => $openingBalanceAmount
|
||||
'accountRole' => $account->getMeta('accountRole'),
|
||||
'ccType' => $account->getMeta('ccType'),
|
||||
'ccMonthlyPaymentDate' => $account->getMeta('ccMonthlyPaymentDate'),
|
||||
'openingBalanceDate' => $openingBalance ? $openingBalance->date->format('Y-m-d') : null,
|
||||
'openingBalance' => $openingBalanceAmount,
|
||||
'virtualBalance' => floatval($account->virtual_balance)
|
||||
];
|
||||
Session::flash('preFilled', $preFilled);
|
||||
|
||||
@@ -108,43 +114,32 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $what
|
||||
* @param $what
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index($what = 'default')
|
||||
public function index($what, AccountRepositoryInterface $repository)
|
||||
{
|
||||
$subTitle = Config::get('firefly.subTitlesByIdentifier.' . $what);
|
||||
$subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what);
|
||||
$types = Config::get('firefly.accountTypesByIdentifier.' . $what);
|
||||
$size = 50;
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$offset = ($page - 1) * $size;
|
||||
|
||||
|
||||
// move to repository:
|
||||
$set = Auth::user()->accounts()->with(
|
||||
['accountmeta' => function ($query) {
|
||||
$query->where('name', 'accountRole');
|
||||
}]
|
||||
)->accountTypeIn($types)->take($size)->offset($offset)->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||
$total = Auth::user()->accounts()->accountTypeIn($types)->count();
|
||||
$set = $repository->getAccounts($types, $page);
|
||||
$total = $repository->countAccounts($types);
|
||||
|
||||
// last activity:
|
||||
$start = clone Session::get('start');
|
||||
/**
|
||||
* HERE WE ARE
|
||||
*/
|
||||
$start = clone Session::get('start', Carbon::now()->startOfMonth());
|
||||
$start->subDay();
|
||||
$set->each(
|
||||
function (Account $account) use ($start) {
|
||||
$lastTransaction = $account->transactions()->leftJoin(
|
||||
'transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
)->orderBy('transaction_journals.date', 'DESC')->first(['transactions.*', 'transaction_journals.date']);
|
||||
if ($lastTransaction) {
|
||||
$account->lastActivityDate = $lastTransaction->transactionjournal->date;
|
||||
} else {
|
||||
$account->lastActivityDate = null;
|
||||
}
|
||||
$account->startBalance = Steam::balance($account, $start);
|
||||
$account->endBalance = Steam::balance($account, clone Session::get('end'));
|
||||
function (Account $account) use ($start, $repository) {
|
||||
$account->lastActivityDate = $repository->getLastActivity($account);
|
||||
$account->startBalance = Steam::balance($account, $start);
|
||||
$account->endBalance = Steam::balance($account, clone Session::get('end', Carbon::now()->endOfMonth()));
|
||||
}
|
||||
);
|
||||
|
||||
@@ -168,7 +163,10 @@ 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);
|
||||
$journals->setPath('accounts/show/' . $account->id);
|
||||
|
||||
|
||||
|
||||
return view('accounts.show', compact('account', 'what', 'subTitleIcon', 'journals', 'subTitle'));
|
||||
}
|
||||
|
||||
@@ -183,6 +181,7 @@ class AccountController extends Controller
|
||||
$accountData = [
|
||||
'name' => $request->input('name'),
|
||||
'accountType' => $request->input('what'),
|
||||
'virtualBalance' => floatval($request->input('virtualBalance')),
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'accountRole' => $request->input('accountRole'),
|
||||
@@ -193,7 +192,7 @@ class AccountController extends Controller
|
||||
];
|
||||
$account = $repository->store($accountData);
|
||||
|
||||
Session::flash('success', 'New account "' . $account->name . '" stored!');
|
||||
Session::flash('success', 'New account "' . $account->name . '" stored!');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
return Redirect::route('accounts.create', $request->input('what'))->withInput();
|
||||
@@ -218,9 +217,12 @@ class AccountController extends Controller
|
||||
'active' => $request->input('active'),
|
||||
'user' => Auth::user()->id,
|
||||
'accountRole' => $request->input('accountRole'),
|
||||
'virtualBalance' => floatval($request->input('virtualBalance')),
|
||||
'openingBalance' => floatval($request->input('openingBalance')),
|
||||
'openingBalanceDate' => new Carbon($request->input('openingBalanceDate')),
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
'ccType' => $request->input('ccType'),
|
||||
'ccMonthlyPaymentDate' => $request->input('ccMonthlyPaymentDate'),
|
||||
];
|
||||
|
||||
$repository->update($account, $accountData);
|
||||
|
||||
@@ -5,6 +5,7 @@ use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Contracts\Auth\Registrar;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Mail\Message;
|
||||
use Mail;
|
||||
use Session;
|
||||
|
||||
@@ -63,7 +64,7 @@ class AuthController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
$data =$request->all();
|
||||
$data = $request->all();
|
||||
$data['password'] = bcrypt($data['password']);
|
||||
|
||||
$this->auth->login($this->registrar->create($data));
|
||||
@@ -73,13 +74,15 @@ class AuthController extends Controller
|
||||
|
||||
// send email.
|
||||
Mail::send(
|
||||
'emails.registered', [], function ($message) use ($email) {
|
||||
'emails.registered', [], function (Message $message) use ($email) {
|
||||
$message->to($email, $email)->subject('Welcome to Firefly III!');
|
||||
}
|
||||
);
|
||||
|
||||
// set flash message
|
||||
Session::flash('success', 'You have registered successfully!');
|
||||
Session::flash('gaEventCategory', 'user');
|
||||
Session::flash('gaEventAction', 'new-registration');
|
||||
|
||||
|
||||
return redirect($this->redirectPath());
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\BillFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use Input;
|
||||
use Redirect;
|
||||
@@ -22,18 +24,64 @@ use View;
|
||||
class BillController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Bills');
|
||||
View::share('mainTitleIcon', 'fa-calendar-o');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function add(Bill $bill, AccountRepositoryInterface $repository)
|
||||
{
|
||||
$matches = explode(',', $bill->match);
|
||||
$description = [];
|
||||
$expense = null;
|
||||
|
||||
// get users expense accounts:
|
||||
$accounts = $repository->getAccounts(Config::get('firefly.accountTypesByIdentifier.expense'), -1);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$match = strtolower($match);
|
||||
// find expense account for each word if not found already:
|
||||
if (is_null($expense)) {
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$name = strtolower($account->name);
|
||||
if (!(strpos($name, $match) === false)) {
|
||||
$expense = $account;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (is_null($expense)) {
|
||||
$description[] = $match;
|
||||
}
|
||||
}
|
||||
$parameters = [
|
||||
'description' => ucfirst(join(' ', $description)),
|
||||
'expense_account' => is_null($expense) ? '' : $expense->name,
|
||||
'amount' => round(($bill->amount_min + $bill->amount_max), 2),
|
||||
];
|
||||
Session::put('preFilled', $parameters);
|
||||
|
||||
return Redirect::to(route('transactions.create', 'withdrawal'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$periods = \Config::get('firefly.periods_to_text');
|
||||
$periods = Config::get('firefly.periods_to_text');
|
||||
|
||||
return view('bills.create')->with('periods', $periods)->with('subTitle', 'Create new');
|
||||
}
|
||||
@@ -53,9 +101,10 @@ class BillController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Bill $bill)
|
||||
public function destroy(Bill $bill, BillRepositoryInterface $repository)
|
||||
{
|
||||
$bill->delete();
|
||||
$repository->destroy($bill);
|
||||
|
||||
Session::flash('success', 'The bill was deleted.');
|
||||
|
||||
return Redirect::route('bills.index');
|
||||
@@ -69,7 +118,7 @@ class BillController extends Controller
|
||||
*/
|
||||
public function edit(Bill $bill)
|
||||
{
|
||||
$periods = \Config::get('firefly.periods_to_text');
|
||||
$periods = Config::get('firefly.periods_to_text');
|
||||
|
||||
return view('bills.edit')->with('periods', $periods)->with('bill', $bill)->with('subTitle', 'Edit "' . e($bill->name) . '"');
|
||||
}
|
||||
@@ -81,15 +130,11 @@ class BillController extends Controller
|
||||
*/
|
||||
public function index(BillRepositoryInterface $repository)
|
||||
{
|
||||
$bills = Auth::user()->bills()->orderBy('name', 'ASC')->get();
|
||||
$bills = $repository->getBills();
|
||||
$bills->each(
|
||||
function (Bill $bill) use ($repository) {
|
||||
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill);
|
||||
$last = $bill->transactionjournals()->orderBy('date', 'DESC')->first();
|
||||
$bill->lastFoundMatch = null;
|
||||
if ($last) {
|
||||
$bill->lastFoundMatch = $last->date;
|
||||
}
|
||||
$bill->lastFoundMatch = $repository->lastFoundMatch($bill);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -106,25 +151,15 @@ class BillController extends Controller
|
||||
if (intval($bill->active) == 0) {
|
||||
Session::flash('warning', 'Inactive bills cannot be scanned.');
|
||||
|
||||
return Redirect::intended('/');
|
||||
return Redirect::to(URL::previous());
|
||||
}
|
||||
|
||||
$set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)->get(
|
||||
['transaction_journal_id']
|
||||
);
|
||||
$ids = [];
|
||||
$journals = $repository->getPossiblyRelatedJournals($bill);
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$repository->scan($bill, $journal);
|
||||
}
|
||||
|
||||
/** @var Transaction $entry */
|
||||
foreach ($set as $entry) {
|
||||
$ids[] = intval($entry->transaction_journal_id);
|
||||
}
|
||||
if (count($ids) > 0) {
|
||||
$journals = Auth::user()->transactionjournals()->whereIn('id', $ids)->get();
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$repository->scan($bill, $journal);
|
||||
}
|
||||
}
|
||||
|
||||
Session::flash('success', 'Rescanned everything.');
|
||||
|
||||
@@ -138,16 +173,10 @@ class BillController extends Controller
|
||||
*/
|
||||
public function show(Bill $bill, BillRepositoryInterface $repository)
|
||||
{
|
||||
$journals = $bill->transactionjournals()->withRelevantData()
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
|
||||
->get();
|
||||
$journals = $repository->getJournals($bill);
|
||||
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill);
|
||||
$hideBill = true;
|
||||
|
||||
|
||||
return view('bills.show', compact('journals', 'hideBill', 'bill'))->with('subTitle', e($bill->name));
|
||||
}
|
||||
|
||||
@@ -156,24 +185,8 @@ class BillController extends Controller
|
||||
*/
|
||||
public function store(BillFormRequest $request, BillRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
var_dump($request->all());
|
||||
|
||||
$billData = [
|
||||
'name' => $request->get('name'),
|
||||
'match' => $request->get('match'),
|
||||
'amount_min' => floatval($request->get('amount_min')),
|
||||
'amount_currency_id' => floatval($request->get('amount_currency_id')),
|
||||
'amount_max' => floatval($request->get('amount_max')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'user' => Auth::user()->id,
|
||||
'repeat_freq' => $request->get('repeat_freq'),
|
||||
'skip' => intval($request->get('skip')),
|
||||
'automatch' => intval($request->get('automatch')) === 1,
|
||||
'active' => intval($request->get('active')) === 1,
|
||||
];
|
||||
|
||||
$bill = $repository->store($billData);
|
||||
$billData = $request->getBillData();
|
||||
$bill = $repository->store($billData);
|
||||
Session::flash('success', 'Bill "' . e($bill->name) . '" stored.');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
@@ -191,21 +204,8 @@ class BillController extends Controller
|
||||
*/
|
||||
public function update(Bill $bill, BillFormRequest $request, BillRepositoryInterface $repository)
|
||||
{
|
||||
$billData = [
|
||||
'name' => $request->get('name'),
|
||||
'match' => $request->get('match'),
|
||||
'amount_min' => floatval($request->get('amount_min')),
|
||||
'amount_currency_id' => floatval($request->get('amount_currency_id')),
|
||||
'amount_max' => floatval($request->get('amount_max')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'user' => Auth::user()->id,
|
||||
'repeat_freq' => $request->get('repeat_freq'),
|
||||
'skip' => intval($request->get('skip')),
|
||||
'automatch' => intval($request->get('automatch')) === 1,
|
||||
'active' => intval($request->get('active')) === 1,
|
||||
];
|
||||
|
||||
$bill = $repository->update($bill, $billData);
|
||||
$billData = $request->getBillData();
|
||||
$bill = $repository->update($bill, $billData);
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
return Redirect::route('bills.edit', $bill->id);
|
||||
|
||||
@@ -5,6 +5,7 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\BudgetFormRequest;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use Input;
|
||||
@@ -12,6 +13,7 @@ use Preferences;
|
||||
use Redirect;
|
||||
use Response;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
/**
|
||||
@@ -22,6 +24,9 @@ use View;
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Budgets');
|
||||
@@ -32,7 +37,6 @@ class BudgetController extends Controller
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function amount(Budget $budget, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
@@ -49,6 +53,12 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (Session::get('budgets.create.fromStore') !== true) {
|
||||
Session::put('budgets.create.url', URL::previous());
|
||||
}
|
||||
Session::forget('budgets.create.fromStore');
|
||||
|
||||
return view('budgets.create')->with('subTitle', 'Create a new budget');
|
||||
}
|
||||
|
||||
@@ -61,6 +71,9 @@ class BudgetController extends Controller
|
||||
{
|
||||
$subTitle = 'Delete budget' . e($budget->name) . '"';
|
||||
|
||||
// put previous url in session
|
||||
Session::put('budgets.delete.url', URL::previous());
|
||||
|
||||
return view('budgets.delete', compact('budget', 'subTitle'));
|
||||
}
|
||||
|
||||
@@ -75,9 +88,10 @@ class BudgetController extends Controller
|
||||
$name = $budget->name;
|
||||
$repository->destroy($budget);
|
||||
|
||||
|
||||
Session::flash('success', 'The budget "' . e($name) . '" was deleted.');
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
return Redirect::to(Session::get('budgets.delete.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,6 +103,12 @@ class BudgetController extends Controller
|
||||
{
|
||||
$subTitle = 'Edit budget "' . e($budget->name) . '"';
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('budgets.edit.fromUpdate') !== true) {
|
||||
Session::put('budgets.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('budgets.edit.fromUpdate');
|
||||
|
||||
return view('budgets.edit', compact('budget', 'subTitle'));
|
||||
|
||||
}
|
||||
@@ -98,46 +118,44 @@ class BudgetController extends Controller
|
||||
*/
|
||||
public function index(BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$budgets = Auth::user()->budgets()->get();
|
||||
$budgets = $repository->getActiveBudgets();
|
||||
$inactive = $repository->getInactiveBudgets();
|
||||
|
||||
/**
|
||||
* Do some cleanup:
|
||||
*/
|
||||
$repository->cleanupBudgets();
|
||||
|
||||
|
||||
// loop the budgets:
|
||||
$budgets->each(
|
||||
function (Budget $budget) use ($repository) {
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$budget->spent = $repository->spentInMonth($budget, $date);
|
||||
$budget->currentRep = $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']);
|
||||
$budget->currentRep = $repository->getCurrentRepetition($budget, $date);
|
||||
}
|
||||
);
|
||||
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
||||
$dateAsString = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
||||
$spent = $budgets->sum('spent');
|
||||
$amount = Preferences::get('budgetIncomeTotal' . $date, 1000)->data;
|
||||
$amount = Preferences::get('budgetIncomeTotal' . $dateAsString, 1000)->data;
|
||||
$overspent = $spent > $amount;
|
||||
$spentPCT = $overspent ? ceil($amount / $spent * 100) : ceil($spent / $amount * 100);
|
||||
$budgetMax = Preferences::get('budgetMaximum', 1000);
|
||||
$budgetMaximum = $budgetMax->data;
|
||||
|
||||
return view('budgets.index', compact('budgetMaximum', 'budgets', 'spent', 'spentPCT', 'overspent', 'amount'));
|
||||
return view('budgets.index', compact('budgetMaximum', 'inactive', 'budgets', 'spent', 'spentPCT', 'overspent', 'amount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function noBudget()
|
||||
public function noBudget(BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$start = \Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = \Session::get('end', Carbon::now()->startOfMonth());
|
||||
$list = Auth::user()
|
||||
->transactionjournals()
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('budget_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->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');
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->startOfMonth());
|
||||
$list = $repository->getWithoutBudget($start, $end);
|
||||
$subTitle = 'Transactions without a budget between ' . $start->format('jS F Y') . ' and ' . $end->format('jS F Y');
|
||||
|
||||
return view('budgets.noBudget', compact('list', 'subTitle'));
|
||||
}
|
||||
@@ -154,6 +172,27 @@ class BudgetController extends Controller
|
||||
return Redirect::route('budgets.index');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param LimitRepetition $repetition
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show(Budget $budget, LimitRepetition $repetition = null, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
if (!is_null($repetition->id) && $repetition->budgetLimit->budget->id != $budget->id) {
|
||||
return view('error')->with('message', 'Invalid selection.');
|
||||
}
|
||||
|
||||
$hideBudget = true; // used in transaction list.
|
||||
$journals = $repository->getJournals($budget, $repetition);
|
||||
$limits = !is_null($repetition->id) ? [$repetition->budgetLimit] : $repository->getBudgetLimits($budget);
|
||||
$subTitle = !is_null($repetition->id) ? e($budget->name) . ' in ' . $repetition->startdate->format('F Y') : e($budget->name);
|
||||
|
||||
return view('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle', 'hideBudget'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetFormRequest $request
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
@@ -170,29 +209,16 @@ class BudgetController extends Controller
|
||||
|
||||
Session::flash('success', 'New budget "' . $budget->name . '" stored!');
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
// set value so create routine will not overwrite URL:
|
||||
Session::put('budgets.create.fromStore', true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param LimitRepetition $repetition
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show(Budget $budget, LimitRepetition $repetition = null, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
if (!is_null($repetition->id) && $repetition->budgetLimit->budget->id != $budget->id) {
|
||||
return view('error')->with('message', 'Invalid selection.');
|
||||
return Redirect::route('budgets.create')->withInput();
|
||||
}
|
||||
|
||||
$hideBudget = true; // used in transaction list.
|
||||
$journals = $repository->getJournals($budget, $repetition);
|
||||
$limits = !is_null($repetition->id) ? [$repetition->budgetLimit] : $budget->budgetLimits()->orderBy('startdate', 'DESC')->get();
|
||||
$subTitle = !is_null($repetition->id) ? e($budget->name) . ' in ' . $repetition->startdate->format('F Y') : e($budget->name);
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('budgets.create.url'));
|
||||
|
||||
return view('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle', 'hideBudget'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,7 +231,8 @@ class BudgetController extends Controller
|
||||
public function update(Budget $budget, BudgetFormRequest $request, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$budgetData = [
|
||||
'name' => $request->input('name'),
|
||||
'name' => $request->input('name'),
|
||||
'active' => intval($request->input('active')) == 1
|
||||
];
|
||||
|
||||
$repository->update($budget, $budgetData);
|
||||
@@ -213,10 +240,14 @@ 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);
|
||||
// set value so edit routine will not overwrite URL:
|
||||
Session::put('budgets.edit.fromUpdate', true);
|
||||
|
||||
return Redirect::route('budgets.edit', $budget->id)->withInput(['return_to_edit' => 1]);
|
||||
}
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('budgets.edit.url'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
|
||||
/**
|
||||
* Class CategoryController
|
||||
*
|
||||
@@ -35,6 +35,12 @@ class CategoryController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (Session::get('categories.create.fromStore') !== true) {
|
||||
Session::put('categories.create.url', URL::previous());
|
||||
}
|
||||
Session::forget('categories.create.fromStore');
|
||||
|
||||
return view('categories.create')->with('subTitle', 'Create a new category');
|
||||
}
|
||||
|
||||
@@ -47,6 +53,9 @@ class CategoryController extends Controller
|
||||
{
|
||||
$subTitle = 'Delete category' . e($category->name) . '"';
|
||||
|
||||
// put previous url in session
|
||||
Session::put('categories.delete.url', URL::previous());
|
||||
|
||||
return view('categories.delete', compact('category', 'subTitle'));
|
||||
}
|
||||
|
||||
@@ -63,7 +72,7 @@ class CategoryController extends Controller
|
||||
|
||||
Session::flash('success', 'The category "' . e($name) . '" was deleted.');
|
||||
|
||||
return Redirect::route('categories.index');
|
||||
return Redirect::to(Session::get('categories.delete.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,27 +84,27 @@ class CategoryController extends Controller
|
||||
{
|
||||
$subTitle = 'Edit category "' . e($category->name) . '"';
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('categories.edit.fromUpdate') !== true) {
|
||||
Session::put('categories.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('categories.edit.fromUpdate');
|
||||
|
||||
return view('categories.edit', compact('category', 'subTitle'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*
|
||||
*/
|
||||
public function index()
|
||||
public function index(CategoryRepositoryInterface $repository)
|
||||
{
|
||||
$categories = Auth::user()->categories()->orderBy('name', 'ASC')->get();
|
||||
$categories = $repository->getCategories();
|
||||
|
||||
$categories->each(
|
||||
function (Category $category) {
|
||||
$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;
|
||||
}
|
||||
function (Category $category) use ($repository) {
|
||||
$category->lastActivity = $repository->getLatestActivity($category);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -105,21 +114,11 @@ class CategoryController extends Controller
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function noCategory()
|
||||
public function noCategory(CategoryRepositoryInterface $repository)
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->startOfMonth());
|
||||
$list = Auth::user()
|
||||
->transactionjournals()
|
||||
->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('category_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
->get(['transaction_journals.*']);
|
||||
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->startOfMonth());
|
||||
$list = $repository->getWithoutCategory($start, $end);
|
||||
$subTitle = 'Transactions without a category between ' . $start->format('jS F Y') . ' and ' . $end->format('jS F Y');
|
||||
|
||||
return view('categories.noCategory', compact('list', 'subTitle'));
|
||||
@@ -134,19 +133,9 @@ 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('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC')
|
||||
|
||||
->get(
|
||||
['transaction_journals.*']
|
||||
);
|
||||
$count = $category->transactionJournals()->count();
|
||||
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
$set = $repository->getJournals($category, $page);
|
||||
$count = $repository->countJournals($category);
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
|
||||
return view('categories.show', compact('category', 'journals', 'hideCategory'));
|
||||
}
|
||||
@@ -166,17 +155,14 @@ class CategoryController extends Controller
|
||||
$category = $repository->store($categoryData);
|
||||
|
||||
Session::flash('success', 'New category "' . $category->name . '" stored!');
|
||||
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
Session::put('categories.create.fromStore', true);
|
||||
|
||||
return Redirect::route('categories.create')->withInput();
|
||||
}
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
return Redirect::route('categories.create');
|
||||
}
|
||||
|
||||
return Redirect::route('categories.index');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -198,10 +184,13 @@ class CategoryController extends Controller
|
||||
Session::flash('success', 'Category "' . $category->name . '" updated.');
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
Session::put('categories.edit.fromUpdate', true);
|
||||
|
||||
return Redirect::route('categories.edit', $category->id);
|
||||
}
|
||||
|
||||
return Redirect::route('categories.index');
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('categories.edit.url'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,14 @@ use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\CurrencyFormRequest;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
|
||||
/**
|
||||
* Class CurrencyController
|
||||
*
|
||||
@@ -39,6 +40,12 @@ class CurrencyController extends Controller
|
||||
$subTitleIcon = 'fa-plus';
|
||||
$subTitle = 'Create a new currency';
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (Session::get('currency.create.fromStore') !== true) {
|
||||
Session::put('currency.create.url', URL::previous());
|
||||
}
|
||||
Session::forget('currency.create.fromStore');
|
||||
|
||||
return view('currency.create', compact('subTitleIcon', 'subTitle'));
|
||||
}
|
||||
|
||||
@@ -50,9 +57,7 @@ class CurrencyController extends Controller
|
||||
public function defaultCurrency(TransactionCurrency $currency)
|
||||
{
|
||||
|
||||
$currencyPreference = Preferences::get('currencyPreference', 'EUR');
|
||||
$currencyPreference->data = $currency->code;
|
||||
$currencyPreference->save();
|
||||
Preferences::set('currencyPreference', $currency->code);
|
||||
|
||||
Session::flash('success', $currency->name . ' is now the default currency.');
|
||||
Cache::forget('FFCURRENCYSYMBOL');
|
||||
@@ -67,14 +72,18 @@ class CurrencyController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function delete(TransactionCurrency $currency)
|
||||
public function delete(TransactionCurrency $currency, CurrencyRepositoryInterface $repository)
|
||||
{
|
||||
if ($currency->transactionJournals()->count() > 0) {
|
||||
|
||||
if ($repository->countJournals($currency) > 0) {
|
||||
Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.');
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
}
|
||||
|
||||
// put previous url in session
|
||||
Session::put('currency.delete.url', URL::previous());
|
||||
|
||||
|
||||
return view('currency.delete', compact('currency'));
|
||||
}
|
||||
@@ -84,10 +93,10 @@ class CurrencyController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(TransactionCurrency $currency)
|
||||
public function destroy(TransactionCurrency $currency, CurrencyRepositoryInterface $repository)
|
||||
{
|
||||
if ($currency->transactionJournals()->count() > 0) {
|
||||
Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.');
|
||||
if ($repository->countJournals($currency) > 0) {
|
||||
Session::flash('error', 'Cannot destroy ' . e($currency->name) . ' because there are still transactions attached to it.');
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
}
|
||||
@@ -96,7 +105,7 @@ class CurrencyController extends Controller
|
||||
|
||||
$currency->delete();
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
return Redirect::to(Session::get('currency.delete.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,6 +119,12 @@ class CurrencyController extends Controller
|
||||
$subTitle = 'Edit currency "' . e($currency->name) . '"';
|
||||
$currency->symbol = htmlentities($currency->symbol);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('currency.edit.fromUpdate') !== true) {
|
||||
Session::put('currency.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('currency.edit.fromUpdate');
|
||||
|
||||
return view('currency.edit', compact('currency', 'subTitle', 'subTitleIcon'));
|
||||
|
||||
}
|
||||
@@ -117,12 +132,10 @@ class CurrencyController extends Controller
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(CurrencyRepositoryInterface $repository)
|
||||
{
|
||||
$currencies = TransactionCurrency::get();
|
||||
$currencyPreference = Preferences::get('currencyPreference', 'EUR');
|
||||
$defaultCurrency = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
|
||||
$currencies = $repository->get();
|
||||
$defaultCurrency = $repository->getCurrencyByPreference(Preferences::get('currencyPreference', 'EUR'));
|
||||
|
||||
return view('currency.index', compact('currencies', 'defaultCurrency'));
|
||||
}
|
||||
@@ -132,26 +145,22 @@ class CurrencyController extends Controller
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(CurrencyFormRequest $request)
|
||||
public function store(CurrencyFormRequest $request, CurrencyRepositoryInterface $repository)
|
||||
{
|
||||
$data = $request->getCurrencyData();
|
||||
$currency = $repository->store($data);
|
||||
|
||||
|
||||
// no repository, because the currency controller is relatively simple.
|
||||
$currency = TransactionCurrency::create(
|
||||
[
|
||||
'name' => $request->get('name'),
|
||||
'code' => $request->get('code'),
|
||||
'symbol' => $request->get('symbol'),
|
||||
]
|
||||
);
|
||||
|
||||
Session::flash('success', 'Currency "' . $currency->name . '" created');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
Session::put('currency.create.fromStore', true);
|
||||
|
||||
return Redirect::route('currency.create')->withInput();
|
||||
}
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('currency.create.url'));
|
||||
|
||||
|
||||
}
|
||||
@@ -161,22 +170,22 @@ class CurrencyController extends Controller
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(TransactionCurrency $currency, CurrencyFormRequest $request)
|
||||
public function update(TransactionCurrency $currency, CurrencyFormRequest $request, CurrencyRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$currency->code = $request->get('code');
|
||||
$currency->symbol = $request->get('symbol');
|
||||
$currency->name = $request->get('name');
|
||||
$currency->save();
|
||||
$data = $request->getCurrencyData();
|
||||
$currency = $repository->update($currency, $data);
|
||||
|
||||
Session::flash('success', 'Currency "' . e($currency->name) . '" updated.');
|
||||
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
Session::put('currency.edit.fromUpdate', true);
|
||||
|
||||
return Redirect::route('currency.edit', $currency->id);
|
||||
}
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('currency.edit.url'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use DB;
|
||||
use Exception;
|
||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
@@ -45,14 +46,15 @@ class GoogleChartController extends Controller
|
||||
*/
|
||||
public function accountBalanceChart(Account $account, GChart $chart)
|
||||
{
|
||||
$accountName = iconv('UTF-8', 'ASCII//TRANSLIT', $account->name);
|
||||
$chart->addColumn('Day of month', 'date');
|
||||
$chart->addColumn('Balance for ' . $account->name, 'number');
|
||||
$chart->addColumn('Balance for ' . $accountName, 'number');
|
||||
$chart->addCertainty(1);
|
||||
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$current = clone $start;
|
||||
$today = new Carbon;
|
||||
$today = new Carbon;
|
||||
|
||||
while ($end >= $current) {
|
||||
$certain = $current < $today;
|
||||
@@ -87,7 +89,8 @@ class GoogleChartController extends Controller
|
||||
$index = 1;
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$chart->addColumn('Balance for ' . $account->name, 'number');
|
||||
$accountName = $account->name;
|
||||
$chart->addColumn('Balance for ' . $accountName, 'number');
|
||||
$chart->addCertainty($index);
|
||||
$index++;
|
||||
}
|
||||
@@ -105,7 +108,7 @@ class GoogleChartController extends Controller
|
||||
$current->addDay();
|
||||
}
|
||||
$chart->generate();
|
||||
|
||||
//header('Content-Type: application/json; charset=utf-8');
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
@@ -238,29 +241,31 @@ class GoogleChartController extends Controller
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$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);
|
||||
}
|
||||
)
|
||||
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);
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
)
|
||||
->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)
|
||||
->where('categories.user_id', Auth::user()->id)
|
||||
->after($start)
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->groupBy('categories.id')
|
||||
->orderBy('sum', 'DESC')
|
||||
->get(['categories.id', 'categories.name', \DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]);
|
||||
->get(['categories.id', 'categories.encrypted', 'categories.name', \DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$entry->name = strlen($entry->name) == 0 ? '(no category)' : $entry->name;
|
||||
$chart->addRow($entry->name, floatval($entry->sum));
|
||||
$isEncrypted = intval($entry->encrypted) == 1 ? true : false;
|
||||
$name = strlen($entry->name) == 0 ? '(no category)' : $entry->name;
|
||||
$name = $isEncrypted ? Crypt::decrypt($name) : $name;
|
||||
$chart->addRow($name, floatval($entry->sum));
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
@@ -280,7 +285,7 @@ class GoogleChartController extends Controller
|
||||
$chart->addColumn('Date', 'date');
|
||||
$chart->addColumn('Max amount', 'number');
|
||||
$chart->addColumn('Min amount', 'number');
|
||||
$chart->addColumn('Current entry', 'number');
|
||||
$chart->addColumn('Recorded bill entry', 'number');
|
||||
|
||||
// get first transaction or today for start:
|
||||
$first = $bill->transactionjournals()->orderBy('date', 'ASC')->first();
|
||||
@@ -289,22 +294,18 @@ class GoogleChartController extends Controller
|
||||
} else {
|
||||
$start = new Carbon;
|
||||
}
|
||||
$end = new Carbon;
|
||||
while ($start <= $end) {
|
||||
$result = $bill->transactionjournals()->before($end)->after($start)->first();
|
||||
if ($result) {
|
||||
/** @var Transaction $tr */
|
||||
foreach ($result->transactions()->get() as $tr) {
|
||||
if (floatval($tr->amount) > 0) {
|
||||
$amount = floatval($tr->amount);
|
||||
}
|
||||
|
||||
$results = $bill->transactionjournals()->after($start)->get();
|
||||
/** @var TransactionJournal $result */
|
||||
foreach ($results as $result) {
|
||||
$amount = 0;
|
||||
/** @var Transaction $tr */
|
||||
foreach ($result->transactions()->get() as $tr) {
|
||||
if (floatval($tr->amount) > 0) {
|
||||
$amount = floatval($tr->amount);
|
||||
}
|
||||
} else {
|
||||
$amount = 0;
|
||||
}
|
||||
unset($result);
|
||||
$chart->addRow(clone $start, $bill->amount_max, $bill->amount_min, $amount);
|
||||
$start = Navigation::addPeriod($start, $bill->repeat_freq, 0);
|
||||
$chart->addRow(clone $result->date, $bill->amount_max, $bill->amount_min, $amount);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
@@ -357,6 +358,49 @@ class GoogleChartController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find credit card accounts and possibly unpaid credit card bills.
|
||||
*/
|
||||
$creditCards = Auth::user()->accounts()
|
||||
->hasMetaValue('accountRole', 'ccAsset')
|
||||
->hasMetaValue('ccType', 'monthlyFull')
|
||||
->get(
|
||||
[
|
||||
'accounts.*',
|
||||
'ccType.data as ccType',
|
||||
'accountRole.data as accountRole'
|
||||
]
|
||||
);
|
||||
// if the balance is not zero, the monthly payment is still underway.
|
||||
/** @var Account $creditCard */
|
||||
foreach ($creditCards as $creditCard) {
|
||||
$balance = Steam::balance($creditCard, null, true);
|
||||
$date = new Carbon($creditCard->getMeta('ccMonthlyPaymentDate'));
|
||||
if ($balance < 0) {
|
||||
// unpaid!
|
||||
$unpaid['amount'] += $balance * -1;
|
||||
$unpaid['items'][] = $creditCard->name . ' (expected ' . Amount::format(($balance * -1), false) . ') on the ' . $date->format('jS') . ')';
|
||||
}
|
||||
if ($balance == 0) {
|
||||
// find a transfer TO the credit card which should account for
|
||||
// anything paid. If not, the CC is not yet used.
|
||||
$transactions = $creditCard->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->before($end)->after($start)->get();
|
||||
if ($transactions->count() > 0) {
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$journal = $transaction->transactionJournal;
|
||||
if ($journal->transactionType->type == 'Transfer') {
|
||||
$paid['amount'] += floatval($transaction->amount);
|
||||
$paid['items'][] = $creditCard->name .
|
||||
' (paid ' . Amount::format((floatval($transaction->amount)), false) .
|
||||
' on the ' . $journal->date->format('jS') . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$chart->addRow('Unpaid: ' . join(', ', $unpaid['items']), $unpaid['amount']);
|
||||
$chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']);
|
||||
$chart->generate();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use Cache;
|
||||
use ErrorException;
|
||||
use FireflyIII\Http\Requests;
|
||||
use League\CommonMark\CommonMarkConverter;
|
||||
use Response;
|
||||
use Route;
|
||||
@@ -33,7 +32,7 @@ class HelpController extends Controller
|
||||
return Response::json($content);
|
||||
}
|
||||
|
||||
if ($this->_inCache($route)) {
|
||||
if ($this->inCache($route)) {
|
||||
$content = [
|
||||
'text' => Cache::get('help.' . $route . '.text'),
|
||||
'title' => Cache::get('help.' . $route . '.title'),
|
||||
@@ -41,7 +40,7 @@ class HelpController extends Controller
|
||||
|
||||
return Response::json($content);
|
||||
}
|
||||
$content = $this->_getFromGithub($route);
|
||||
$content = $this->getFromGithub($route);
|
||||
|
||||
|
||||
Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week.
|
||||
@@ -56,7 +55,7 @@ class HelpController extends Controller
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _inCache($route)
|
||||
protected function inCache($route)
|
||||
{
|
||||
return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text');
|
||||
}
|
||||
@@ -66,7 +65,7 @@ class HelpController extends Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _getFromGithub($route)
|
||||
protected function getFromGithub($route)
|
||||
{
|
||||
$uri = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md';
|
||||
$content = [
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Session;
|
||||
|
||||
use Redirect;
|
||||
use Config;
|
||||
/**
|
||||
* Class HomeController
|
||||
*
|
||||
@@ -29,13 +31,19 @@ class HomeController extends Controller
|
||||
Session::put('end', $end);
|
||||
}
|
||||
|
||||
public function flush() {
|
||||
Session::clear();
|
||||
return Redirect::route('index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$count = $repository->countAssetAccounts();
|
||||
$types = Config::get('firefly.accountTypesByIdentifier.asset');
|
||||
$count = $repository->countAccounts($types);
|
||||
$title = 'Firefly';
|
||||
$subTitle = 'What\'s playing?';
|
||||
$mainTitleIcon = 'fa-fire';
|
||||
@@ -46,6 +54,16 @@ class HomeController extends Controller
|
||||
$accounts = $repository->getFrontpageAccounts($frontPage);
|
||||
$savings = $repository->getSavingsAccounts();
|
||||
|
||||
// check if all books are correct.
|
||||
$sum = floatval(Auth::user()->transactions()->sum('amount'));
|
||||
if ($sum != 0) {
|
||||
Session::flash(
|
||||
'error', 'Your transactions are unbalanced. This means a'
|
||||
. ' withdrawal, deposit or transfer was not stored properly. '
|
||||
. 'Please check your accounts and transactions for errors.'
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = $repository->getFrontpageTransactions($account, $start, $end);
|
||||
if (count($set) > 0) {
|
||||
|
||||
@@ -2,16 +2,19 @@
|
||||
|
||||
use Amount;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
use Config;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* Class JsonController
|
||||
*
|
||||
@@ -71,11 +74,34 @@ class JsonController extends Controller
|
||||
$count = $bill->transactionjournals()->before($range['end'])->after($range['start'])->count();
|
||||
if ($count == 0) {
|
||||
$amount += floatval($bill->amount_max + $bill->amount_min / 2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find credit card accounts and possibly unpaid credit card bills.
|
||||
*/
|
||||
$creditCards = Auth::user()->accounts()
|
||||
->hasMetaValue('accountRole', 'ccAsset')
|
||||
->hasMetaValue('ccType', 'monthlyFull')
|
||||
->get(
|
||||
[
|
||||
'accounts.*',
|
||||
'ccType.data as ccType',
|
||||
'accountRole.data as accountRole'
|
||||
]
|
||||
);
|
||||
// if the balance is not zero, the monthly payment is still underway.
|
||||
/** @var Account $creditCard */
|
||||
foreach ($creditCards as $creditCard) {
|
||||
$balance = Steam::balance($creditCard, null, true);
|
||||
if ($balance < 0) {
|
||||
// unpaid!
|
||||
$amount += $balance * -1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'bills-paid':
|
||||
$box = 'bills-paid';
|
||||
@@ -90,9 +116,8 @@ class JsonController extends Controller
|
||||
// paid a bill in this range?
|
||||
$count = $bill->transactionjournals()->before($range['end'])->after($range['start'])->count();
|
||||
if ($count != 0) {
|
||||
$journal = $bill->transactionjournals()->with('transactions')->before($range['end'])->after($range['start'])->first();
|
||||
$paid['items'][] = $journal->description;
|
||||
$currentAmount = 0;
|
||||
$journal = $bill->transactionjournals()->with('transactions')->before($range['end'])->after($range['start'])->first();
|
||||
$currentAmount = 0;
|
||||
foreach ($journal->transactions as $t) {
|
||||
if (floatval($t->amount) > 0) {
|
||||
$currentAmount = floatval($t->amount);
|
||||
@@ -103,6 +128,41 @@ class JsonController extends Controller
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find credit card accounts and possibly unpaid credit card bills.
|
||||
*/
|
||||
$creditCards = Auth::user()->accounts()
|
||||
->hasMetaValue('accountRole', 'ccAsset')
|
||||
->hasMetaValue('ccType', 'monthlyFull')
|
||||
->get(
|
||||
[
|
||||
'accounts.*',
|
||||
'ccType.data as ccType',
|
||||
'accountRole.data as accountRole'
|
||||
]
|
||||
);
|
||||
// if the balance is not zero, the monthly payment is still underway.
|
||||
/** @var Account $creditCard */
|
||||
foreach ($creditCards as $creditCard) {
|
||||
$balance = Steam::balance($creditCard, null, true);
|
||||
if ($balance == 0) {
|
||||
// find a transfer TO the credit card which should account for
|
||||
// anything paid. If not, the CC is not yet used.
|
||||
$transactions = $creditCard->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->before($end)->after($start)->get();
|
||||
if ($transactions->count() > 0) {
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$journal = $transaction->transactionJournal;
|
||||
if ($journal->transactionType->type == 'Transfer') {
|
||||
$amount += floatval($transaction->amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Response::json(['box' => $box, 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]);
|
||||
@@ -182,16 +242,17 @@ class JsonController extends Controller
|
||||
public function transactionJournals($what)
|
||||
{
|
||||
$descriptions = [];
|
||||
$dbType = TransactionType::whereType($what)->first();
|
||||
$journals = Auth::user()->transactionjournals()->where('transaction_type_id', $dbType->id)
|
||||
->orderBy('id','DESC')->take(50)
|
||||
->get();
|
||||
foreach($journals as $j) {
|
||||
$descriptions[] = $j->description;
|
||||
}
|
||||
$dbType = TransactionType::whereType($what)->first();
|
||||
$journals = Auth::user()->transactionjournals()->where('transaction_type_id', $dbType->id)
|
||||
->orderBy('id', 'DESC')->take(50)
|
||||
->get();
|
||||
foreach ($journals as $j) {
|
||||
$descriptions[] = $j->description;
|
||||
}
|
||||
|
||||
$descriptions = array_unique($descriptions);
|
||||
sort($descriptions);
|
||||
|
||||
return Response::json($descriptions);
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ use Config;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
@@ -18,6 +17,7 @@ use Redirect;
|
||||
use Session;
|
||||
use Steam;
|
||||
use View;
|
||||
use URL;
|
||||
|
||||
/**
|
||||
* Class PiggyBankController
|
||||
@@ -50,9 +50,6 @@ class PiggyBankController extends Controller
|
||||
$leftToSave = $piggyBank->targetamount - $savedSoFar;
|
||||
$maxAmount = min($leftOnAccount, $leftToSave);
|
||||
|
||||
|
||||
\Log::debug('Now going to view for piggy bank #' . $piggyBank->id . ' (' . $piggyBank->name . ')');
|
||||
|
||||
return view('piggy-banks.add', compact('piggyBank', 'maxAmount'));
|
||||
}
|
||||
|
||||
@@ -69,6 +66,12 @@ class PiggyBankController extends Controller
|
||||
$subTitle = 'Create new piggy bank';
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (Session::get('piggy-banks.create.fromStore') !== true) {
|
||||
Session::put('piggy-banks.create.url', URL::previous());
|
||||
}
|
||||
Session::forget('piggy-banks.create.fromStore');
|
||||
|
||||
return view('piggy-banks.create', compact('accounts', 'periods', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
@@ -81,6 +84,9 @@ class PiggyBankController extends Controller
|
||||
{
|
||||
$subTitle = 'Delete "' . e($piggyBank->name) . '"';
|
||||
|
||||
// put previous url in session
|
||||
Session::put('piggy-banks.delete.url', URL::previous());
|
||||
|
||||
return view('piggy-banks.delete', compact('piggyBank', 'subTitle'));
|
||||
}
|
||||
|
||||
@@ -95,7 +101,7 @@ class PiggyBankController extends Controller
|
||||
Session::flash('success', 'Piggy bank "' . e($piggyBank->name) . '" deleted.');
|
||||
$piggyBank->delete();
|
||||
|
||||
return Redirect::route('piggy-banks.index');
|
||||
return Redirect::to(Session::get('piggy-banks.delete.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,6 +139,12 @@ class PiggyBankController extends Controller
|
||||
];
|
||||
Session::flash('preFilled', $preFilled);
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('piggy-banks.edit.fromUpdate') !== true) {
|
||||
Session::put('piggy-banks.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('piggy-banks.edit.fromUpdate');
|
||||
|
||||
return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'accounts', 'periods', 'preFilled'));
|
||||
}
|
||||
|
||||
@@ -142,7 +154,7 @@ class PiggyBankController extends Controller
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
{
|
||||
/** @var Collection $piggyBanks */
|
||||
$piggyBanks = Auth::user()->piggyBanks()->where('repeats', 0)->orderBy('order', 'ASC')->get();
|
||||
$piggyBanks = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get();
|
||||
|
||||
$accounts = [];
|
||||
/** @var PiggyBank $piggyBank */
|
||||
@@ -158,7 +170,7 @@ class PiggyBankController extends Controller
|
||||
if (!isset($accounts[$account->id])) {
|
||||
$accounts[$account->id] = [
|
||||
'name' => $account->name,
|
||||
'balance' => Steam::balance($account),
|
||||
'balance' => Steam::balance($account,null,true),
|
||||
'leftForPiggyBanks' => $repository->leftOnAccount($account),
|
||||
'sumOfSaved' => $piggyBank->savedSoFar,
|
||||
'sumOfTargets' => floatval($piggyBank->targetamount),
|
||||
@@ -299,7 +311,6 @@ class PiggyBankController extends Controller
|
||||
public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
$piggyBankData = [
|
||||
'repeats' => false,
|
||||
'name' => $request->get('name'),
|
||||
'startdate' => new Carbon,
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
@@ -314,11 +325,13 @@ class PiggyBankController extends Controller
|
||||
Session::flash('success', 'Stored piggy bank "' . e($piggyBank->name) . '".');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
Session::put('piggy-banks.create.fromStore', true);
|
||||
return Redirect::route('piggy-banks.create')->withInput();
|
||||
}
|
||||
|
||||
|
||||
return Redirect::route('piggy-banks.index');
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('piggy-banks.create.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,7 +344,6 @@ class PiggyBankController extends Controller
|
||||
public function update(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request)
|
||||
{
|
||||
$piggyBankData = [
|
||||
'repeats' => false,
|
||||
'name' => $request->get('name'),
|
||||
'startdate' => is_null($piggyBank->startdate) ? $piggyBank->created_at : $piggyBank->startdate,
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
@@ -347,11 +359,13 @@ class PiggyBankController extends Controller
|
||||
Session::flash('success', 'Updated piggy bank "' . e($piggyBank->name) . '".');
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
Session::put('piggy-banks.edit.fromUpdate', true);
|
||||
return Redirect::route('piggy-banks.edit', $piggyBank->id);
|
||||
}
|
||||
|
||||
|
||||
return Redirect::route('piggy-banks.index');
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('piggy-banks.edit.url'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Http\Requests;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Redirect;
|
||||
|
||||
@@ -45,7 +45,7 @@ class ProfileController extends Controller
|
||||
|
||||
return Redirect::route('change-password');
|
||||
}
|
||||
$result = $this->_validatePassword($request->get('current_password'), $request->get('new_password'), $request->get('new_password_confirmation'));
|
||||
$result = $this->validatePassword($request->get('current_password'), $request->get('new_password'), $request->get('new_password_confirmation'));
|
||||
if (!($result === true)) {
|
||||
Session::flash('error', $result);
|
||||
|
||||
@@ -70,7 +70,7 @@ class ProfileController extends Controller
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function _validatePassword($old, $new1, $new2)
|
||||
protected function validatePassword($old, $new1, $new2)
|
||||
{
|
||||
if (strlen($new1) == 0 || strlen($new2) == 0) {
|
||||
return 'Do fill in a password!';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Reminders\ReminderHelperInterface;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Models\Reminder;
|
||||
use Redirect;
|
||||
use Session;
|
||||
@@ -83,7 +82,7 @@ class ReminderController extends Controller
|
||||
|
||||
// inactive reminders
|
||||
$inactive = $reminders->filter(
|
||||
function (Reminder $reminder) use ($today) {
|
||||
function (Reminder $reminder) {
|
||||
if ($reminder->active === false) {
|
||||
return $reminder;
|
||||
}
|
||||
@@ -92,7 +91,7 @@ class ReminderController extends Controller
|
||||
|
||||
// dismissed reminders
|
||||
$dismissed = $reminders->filter(
|
||||
function (Reminder $reminder) use ($today) {
|
||||
function (Reminder $reminder) {
|
||||
if ($reminder->notnow === true) {
|
||||
return $reminder;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Preferences;
|
||||
use Session;
|
||||
use Steam;
|
||||
use View;
|
||||
use FireflyIII\Models\Preference;
|
||||
use Crypt;
|
||||
|
||||
/**
|
||||
* Class ReportController
|
||||
@@ -23,11 +21,20 @@ use FireflyIII\Models\Preference;
|
||||
class ReportController extends Controller
|
||||
{
|
||||
|
||||
/** @var ReportHelperInterface */
|
||||
protected $helper;
|
||||
/** @var ReportQueryInterface */
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ReportHelperInterface $helper
|
||||
* @param ReportQueryInterface $query
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(ReportHelperInterface $helper, ReportQueryInterface $query)
|
||||
{
|
||||
$this->query = $query;
|
||||
$this->helper = $helper;
|
||||
|
||||
View::share('title', 'Reports');
|
||||
View::share('mainTitleIcon', 'fa-line-chart');
|
||||
|
||||
@@ -39,7 +46,7 @@ class ReportController extends Controller
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function budget($year = '2014', $month = '1', ReportQueryInterface $query)
|
||||
public function budget($year = '2014', $month = '1')
|
||||
{
|
||||
try {
|
||||
new Carbon($year . '-' . $month . '-01');
|
||||
@@ -53,7 +60,7 @@ class ReportController extends Controller
|
||||
$end->endOfMonth();
|
||||
$start->subDay();
|
||||
|
||||
// shared accounts preference:
|
||||
/** @var Preference $pref */
|
||||
$pref = Preferences::get('showSharedReports', false);
|
||||
$showSharedReports = $pref->data;
|
||||
|
||||
@@ -62,13 +69,13 @@ class ReportController extends Controller
|
||||
$subTitle = 'Budget report for ' . $date->format('F Y');
|
||||
$subTitleIcon = 'fa-calendar';
|
||||
$dayEarly = $dayEarly->subDay();
|
||||
$accounts = $query->getAllAccounts($start, $end, $showSharedReports);
|
||||
$accounts = $this->query->getAllAccounts($start, $end, $showSharedReports);
|
||||
$start->addDay();
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($start, $end, $query) {
|
||||
$budgets = $query->getBudgetSummary($account, $start, $end);
|
||||
$balancedAmount = $query->balancedTransactionsSum($account, $start, $end);
|
||||
function (Account $account) use ($start, $end) {
|
||||
$budgets = $this->query->getBudgetSummary($account, $start, $end);
|
||||
$balancedAmount = $this->query->balancedTransactionsSum($account, $start, $end);
|
||||
$array = [];
|
||||
$hide = true;
|
||||
foreach ($budgets as $budget) {
|
||||
@@ -86,35 +93,10 @@ class ReportController extends Controller
|
||||
}
|
||||
);
|
||||
|
||||
$start = clone $date;
|
||||
$start->startOfMonth();
|
||||
|
||||
/**
|
||||
* Start getBudgetsForMonth DONE
|
||||
*/
|
||||
$set = Auth::user()->budgets()->orderBy('budgets.name', 'ASC')
|
||||
->leftJoin(
|
||||
'budget_limits', function (JoinClause $join) use ($date) {
|
||||
$join->on('budget_limits.budget_id', '=', 'budgets.id')->where('budget_limits.startdate', '=', $date->format('Y-m-d'));
|
||||
}
|
||||
)
|
||||
->get(['budgets.*', 'budget_limits.amount as amount']);
|
||||
$budgets = Steam::makeArray($set);
|
||||
$amountSet = $query->journalsByBudget($start, $end, $showSharedReports);
|
||||
$amounts = Steam::makeArray($amountSet);
|
||||
$budgets = Steam::mergeArrays($budgets, $amounts);
|
||||
$budgets[0]['spent'] = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0;
|
||||
$budgets[0]['amount'] = isset($budgets[0]['amount']) ? $budgets[0]['amount'] : 0.0;
|
||||
$budgets[0]['name'] = 'No budget';
|
||||
|
||||
// find transactions to shared asset accounts, which are without a budget by default:
|
||||
// which is only relevant when shared asset accounts are hidden.
|
||||
if ($showSharedReports === false) {
|
||||
$transfers = $query->sharedExpenses($start, $end);
|
||||
foreach ($transfers as $transfer) {
|
||||
$budgets[0]['spent'] += floatval($transfer->amount) * -1;
|
||||
}
|
||||
}
|
||||
$budgets = $this->helper->getBudgetsForMonth($date, $showSharedReports);
|
||||
|
||||
/**
|
||||
* End getBudgetsForMonth DONE
|
||||
@@ -129,11 +111,11 @@ class ReportController extends Controller
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index(ReportHelperInterface $helper)
|
||||
public function index()
|
||||
{
|
||||
$start = Session::get('first');
|
||||
$months = $helper->listOfMonths($start);
|
||||
$years = $helper->listOfYears($start);
|
||||
$months = $this->helper->listOfMonths($start);
|
||||
$years = $this->helper->listOfYears($start);
|
||||
$title = 'Reports';
|
||||
$mainTitleIcon = 'fa-line-chart';
|
||||
|
||||
@@ -147,7 +129,7 @@ class ReportController extends Controller
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function modalBalancedTransfers(Account $account, $year = '2014', $month = '1', ReportQueryInterface $query)
|
||||
public function modalBalancedTransfers(Account $account, $year = '2014', $month = '1')
|
||||
{
|
||||
|
||||
try {
|
||||
@@ -159,7 +141,7 @@ class ReportController extends Controller
|
||||
$end = clone $start;
|
||||
$end->endOfMonth();
|
||||
|
||||
$journals = $query->balancedTransactionsList($account, $start, $end);
|
||||
$journals = $this->query->balancedTransactionsList($account, $start, $end);
|
||||
|
||||
return view('reports.modal-journal-list', compact('journals'));
|
||||
|
||||
@@ -174,7 +156,7 @@ class ReportController extends Controller
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function modalLeftUnbalanced(Account $account, $year = '2014', $month = '1', ReportQueryInterface $query)
|
||||
public function modalLeftUnbalanced(Account $account, $year = '2014', $month = '1')
|
||||
{
|
||||
try {
|
||||
new Carbon($year . '-' . $month . '-01');
|
||||
@@ -184,7 +166,7 @@ class ReportController extends Controller
|
||||
$start = new Carbon($year . '-' . $month . '-01');
|
||||
$end = clone $start;
|
||||
$end->endOfMonth();
|
||||
$set = $query->getTransactionsWithoutBudget($account, $start, $end);
|
||||
$set = $this->query->getTransactionsWithoutBudget($account, $start, $end);
|
||||
|
||||
$journals = $set->filter(
|
||||
function (TransactionJournal $journal) {
|
||||
@@ -205,7 +187,7 @@ class ReportController extends Controller
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function modalNoBudget(Account $account, $year = '2014', $month = '1', ReportQueryInterface $query)
|
||||
public function modalNoBudget(Account $account, $year = '2014', $month = '1')
|
||||
{
|
||||
try {
|
||||
new Carbon($year . '-' . $month . '-01');
|
||||
@@ -215,7 +197,7 @@ class ReportController extends Controller
|
||||
$start = new Carbon($year . '-' . $month . '-01');
|
||||
$end = clone $start;
|
||||
$end->endOfMonth();
|
||||
$journals = $query->getTransactionsWithoutBudget($account, $start, $end);
|
||||
$journals = $this->query->getTransactionsWithoutBudget($account, $start, $end);
|
||||
|
||||
return view('reports.modal-journal-list', compact('journals'));
|
||||
|
||||
@@ -227,7 +209,7 @@ class ReportController extends Controller
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function month($year = '2014', $month = '1', ReportQueryInterface $query)
|
||||
public function month($year = '2014', $month = '1')
|
||||
{
|
||||
try {
|
||||
new Carbon($year . '-' . $month . '-01');
|
||||
@@ -238,7 +220,7 @@ class ReportController extends Controller
|
||||
$subTitle = 'Report for ' . $date->format('F Y');
|
||||
$subTitleIcon = 'fa-calendar';
|
||||
$displaySum = true; // to show sums in report.
|
||||
|
||||
/** @var Preference $pref */
|
||||
$pref = Preferences::get('showSharedReports', false);
|
||||
$showSharedReports = $pref->data;
|
||||
|
||||
@@ -257,14 +239,15 @@ class ReportController extends Controller
|
||||
/**
|
||||
* Start getIncomeForMonth DONE
|
||||
*/
|
||||
$income = $query->incomeByPeriod($start, $end, $showSharedReports);
|
||||
$income = $this->query->incomeByPeriod($start, $end, $showSharedReports);
|
||||
/**
|
||||
* End getIncomeForMonth DONE
|
||||
*/
|
||||
/**
|
||||
* Start getExpenseGroupedForMonth DONE
|
||||
*/
|
||||
$set = $query->journalsByExpenseAccount($start, $end, $showSharedReports);
|
||||
$set = $this->query->journalsByExpenseAccount($start, $end, $showSharedReports);
|
||||
|
||||
$expenses = Steam::makeArray($set);
|
||||
$expenses = Steam::sortArray($expenses);
|
||||
$expenses = Steam::limitArray($expenses, 10);
|
||||
@@ -274,28 +257,7 @@ class ReportController extends Controller
|
||||
/**
|
||||
* Start getBudgetsForMonth DONE
|
||||
*/
|
||||
$set = Auth::user()->budgets()
|
||||
->leftJoin(
|
||||
'budget_limits', function (JoinClause $join) use ($date) {
|
||||
$join->on('budget_limits.budget_id', '=', 'budgets.id')->where('budget_limits.startdate', '=', $date->format('Y-m-d'));
|
||||
}
|
||||
)
|
||||
->get(['budgets.*', 'budget_limits.amount as amount']);
|
||||
$budgets = Steam::makeArray($set);
|
||||
$amountSet = $query->journalsByBudget($start, $end, $showSharedReports);
|
||||
$amounts = Steam::makeArray($amountSet);
|
||||
$budgets = Steam::mergeArrays($budgets, $amounts);
|
||||
$budgets[0]['spent'] = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0;
|
||||
$budgets[0]['amount'] = isset($budgets[0]['amount']) ? $budgets[0]['amount'] : 0.0;
|
||||
$budgets[0]['name'] = 'No budget';
|
||||
|
||||
// find transactions to shared expense accounts, which are without a budget by default:
|
||||
if ($showSharedReports === false) {
|
||||
$transfers = $query->sharedExpenses($start, $end);
|
||||
foreach ($transfers as $transfer) {
|
||||
$budgets[0]['spent'] += floatval($transfer->amount) * -1;
|
||||
}
|
||||
}
|
||||
$budgets = $this->helper->getBudgetsForMonth($date, $showSharedReports);
|
||||
|
||||
/**
|
||||
* End getBudgetsForMonth DONE
|
||||
@@ -304,18 +266,20 @@ class ReportController extends Controller
|
||||
* Start getCategoriesForMonth DONE
|
||||
*/
|
||||
// all categories.
|
||||
$result = $query->journalsByCategory($start, $end);
|
||||
$result = $this->query->journalsByCategory($start, $end);
|
||||
$categories = Steam::makeArray($result);
|
||||
|
||||
|
||||
// all transfers
|
||||
if ($showSharedReports === false) {
|
||||
$result = $query->sharedExpensesByCategory($start, $end);
|
||||
$result = $this->query->sharedExpensesByCategory($start, $end);
|
||||
$transfers = Steam::makeArray($result);
|
||||
$merged = Steam::mergeArrays($categories, $transfers);
|
||||
} else {
|
||||
$merged = $categories;
|
||||
}
|
||||
|
||||
|
||||
// sort.
|
||||
$sorted = Steam::sortNegativeArray($merged);
|
||||
|
||||
@@ -327,7 +291,7 @@ class ReportController extends Controller
|
||||
/**
|
||||
* Start getAccountsForMonth
|
||||
*/
|
||||
$list = $query->accountList($showSharedReports);
|
||||
$list = $this->query->accountList($showSharedReports);
|
||||
$accounts = [];
|
||||
/** @var Account $account */
|
||||
foreach ($list as $account) {
|
||||
@@ -361,7 +325,7 @@ class ReportController extends Controller
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function year($year, ReportHelperInterface $helper, ReportQueryInterface $query)
|
||||
public function year($year)
|
||||
{
|
||||
try {
|
||||
new Carbon('01-01-' . $year);
|
||||
@@ -378,11 +342,9 @@ class ReportController extends Controller
|
||||
$subTitle = $year;
|
||||
$subTitleIcon = 'fa-bar-chart';
|
||||
$mainTitleIcon = 'fa-line-chart';
|
||||
$balances = $helper->yearBalanceReport($date, $showSharedReports);
|
||||
$groupedIncomes = $query->journalsByRevenueAccount($date, $end, $showSharedReports);
|
||||
$groupedExpenses = $query->journalsByExpenseAccount($date, $end, $showSharedReports);
|
||||
|
||||
//$groupedExpenses = $helper-> expensesGroupedByAccount($date, $end, 15);
|
||||
$balances = $this->helper->yearBalanceReport($date, $showSharedReports);
|
||||
$groupedIncomes = $this->query->journalsByRevenueAccount($date, $end, $showSharedReports);
|
||||
$groupedExpenses = $this->query->journalsByExpenseAccount($date, $end, $showSharedReports);
|
||||
|
||||
return view(
|
||||
'reports.year', compact('date', 'groupedIncomes', 'groupedExpenses', 'year', 'balances', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon')
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Support\Search\SearchInterface;
|
||||
use Input;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Events\JournalCreated;
|
||||
use FireflyIII\Events\JournalSaved;
|
||||
@@ -13,9 +12,10 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use View;
|
||||
use Response;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class TransactionController
|
||||
@@ -61,6 +61,12 @@ class TransactionController extends Controller
|
||||
}
|
||||
Session::put('preFilled', $preFilled);
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (Session::get('transactions.create.fromStore') !== true) {
|
||||
Session::put('transactions.create.url', URL::previous());
|
||||
}
|
||||
Session::forget('transactions.create.fromStore');
|
||||
|
||||
asort($piggies);
|
||||
|
||||
|
||||
@@ -79,7 +85,10 @@ class TransactionController extends Controller
|
||||
$type = strtolower($journal->transactionType->type);
|
||||
$subTitle = 'Delete ' . e($type) . ' "' . e($journal->description) . '"';
|
||||
|
||||
return View::make('transactions.delete', compact('journal', 'subTitle'));
|
||||
// put previous url in session
|
||||
Session::put('transactions.delete.url', URL::previous());
|
||||
|
||||
return view('transactions.delete', compact('journal', 'subTitle'));
|
||||
|
||||
|
||||
}
|
||||
@@ -91,23 +100,12 @@ class TransactionController extends Controller
|
||||
*/
|
||||
public function destroy(TransactionJournal $transactionJournal)
|
||||
{
|
||||
$type = $transactionJournal->transactionType->type;
|
||||
$return = 'withdrawal';
|
||||
|
||||
Session::flash('success', 'Transaction "' . e($transactionJournal->description) . '" destroyed.');
|
||||
|
||||
$transactionJournal->delete();
|
||||
|
||||
switch ($type) {
|
||||
case 'Deposit':
|
||||
$return = 'deposit';
|
||||
break;
|
||||
case 'Transfer':
|
||||
$return = 'transfers';
|
||||
break;
|
||||
}
|
||||
|
||||
return Redirect::route('transactions.index', $return);
|
||||
// redirect to previous URL:
|
||||
return Redirect::to(Session::get('transactions.delete.url'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,6 +162,12 @@ class TransactionController extends Controller
|
||||
$preFilled['account_from_id'] = $transactions[1]->account->id;
|
||||
$preFilled['account_to_id'] = $transactions[0]->account->id;
|
||||
|
||||
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||
if (Session::get('transactions.edit.fromUpdate') !== true) {
|
||||
Session::put('transactions.edit.url', URL::previous());
|
||||
}
|
||||
Session::forget('transactions.edit.fromUpdate');
|
||||
|
||||
|
||||
return View::make('transactions.edit', compact('journal', 'accounts', 'what', 'budgets', 'piggies', 'subTitle'))->with('data', $preFilled);
|
||||
}
|
||||
@@ -199,16 +203,13 @@ class TransactionController extends Controller
|
||||
$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')
|
||||
->orderBy('order','ASC')
|
||||
->orderBy('id','DESC')
|
||||
->get(
|
||||
['transaction_journals.*']
|
||||
);
|
||||
$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();
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
$journals->setPath('transactions/' . $what);
|
||||
@@ -227,13 +228,14 @@ class TransactionController extends Controller
|
||||
$order = 0;
|
||||
foreach ($ids as $id) {
|
||||
$journal = Auth::user()->transactionjournals()->where('id', $id)->where('date', Input::get('date'))->first();
|
||||
if($journal) {
|
||||
if ($journal) {
|
||||
$journal->order = $order;
|
||||
$order++;
|
||||
$journal->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Response::json(true);
|
||||
|
||||
}
|
||||
@@ -251,10 +253,10 @@ class TransactionController extends Controller
|
||||
$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.order','>=',$journal->order)
|
||||
->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;
|
||||
}
|
||||
@@ -274,25 +276,13 @@ class TransactionController extends Controller
|
||||
*/
|
||||
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository)
|
||||
{
|
||||
$journalData = [
|
||||
'what' => $request->get('what'),
|
||||
'description' => $request->get('description'),
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'account_from_id' => intval($request->get('account_from_id')),
|
||||
'account_to_id' => intval($request->get('account_to_id')),
|
||||
'expense_account' => $request->get('expense_account'),
|
||||
'revenue_account' => $request->get('revenue_account'),
|
||||
'amount' => floatval($request->get('amount')),
|
||||
'user' => Auth::user()->id,
|
||||
'amount_currency_id' => intval($request->get('amount_currency_id')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'budget_id' => intval($request->get('budget_id')),
|
||||
'category' => $request->get('category'),
|
||||
];
|
||||
|
||||
$journal = $repository->store($journalData);
|
||||
$journalData = $request->getJournalData();
|
||||
$journal = $repository->store($journalData);
|
||||
|
||||
// rescan journal, UpdateJournalConnection
|
||||
event(new JournalSaved($journal));
|
||||
// ConnectJournalToPiggyBank
|
||||
event(new JournalCreated($journal, intval($request->get('piggy_bank_id'))));
|
||||
|
||||
if (intval($request->get('reminder_id')) > 0) {
|
||||
@@ -304,10 +294,14 @@ class TransactionController extends Controller
|
||||
Session::flash('success', 'New transaction "' . $journal->description . '" stored!');
|
||||
|
||||
if (intval(Input::get('create_another')) === 1) {
|
||||
// set value so create routine will not overwrite URL:
|
||||
Session::put('transactions.create.fromStore', true);
|
||||
|
||||
return Redirect::route('transactions.create', $request->input('what'))->withInput();
|
||||
}
|
||||
|
||||
return Redirect::route('transactions.index', $request->input('what'));
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('transactions.create.url'));
|
||||
|
||||
}
|
||||
|
||||
@@ -321,23 +315,7 @@ class TransactionController extends Controller
|
||||
public function update(TransactionJournal $journal, JournalFormRequest $request, JournalRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
|
||||
$journalData = [
|
||||
'what' => $request->get('what'),
|
||||
'description' => $request->get('description'),
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'account_from_id' => intval($request->get('account_from_id')),
|
||||
'account_to_id' => intval($request->get('account_to_id')),
|
||||
'expense_account' => $request->get('expense_account'),
|
||||
'revenue_account' => $request->get('revenue_account'),
|
||||
'amount' => floatval($request->get('amount')),
|
||||
'user' => Auth::user()->id,
|
||||
'amount_currency_id' => intval($request->get('amount_currency_id')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'budget_id' => intval($request->get('budget_id')),
|
||||
'category' => $request->get('category'),
|
||||
];
|
||||
|
||||
$journalData = $request->getJournalData();
|
||||
$repository->update($journal, $journalData);
|
||||
|
||||
event(new JournalSaved($journal));
|
||||
@@ -346,11 +324,14 @@ class TransactionController extends Controller
|
||||
Session::flash('success', 'Transaction "' . e($journalData['description']) . '" updated.');
|
||||
|
||||
if (intval(Input::get('return_to_edit')) === 1) {
|
||||
return Redirect::route('transactions.edit', $journal->id);
|
||||
// set value so edit routine will not overwrite URL:
|
||||
Session::put('transactions.edit.fromUpdate', true);
|
||||
|
||||
return Redirect::route('transactions.edit', $journal->id)->withInput(['return_to_edit' => 1]);
|
||||
}
|
||||
|
||||
|
||||
return Redirect::route('transactions.index', $journalData['what']);
|
||||
// redirect to previous URL.
|
||||
return Redirect::to(Session::get('transactions.edit.url'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class Authenticate
|
||||
@@ -37,7 +38,7 @@ class Authenticate
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($this->auth->guest()) {
|
||||
if ($request->ajax()) {
|
||||
|
||||
@@ -7,13 +7,13 @@ 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\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Navigation;
|
||||
use Session;
|
||||
|
||||
use App;
|
||||
|
||||
/**
|
||||
* Class PiggyBanks
|
||||
@@ -48,14 +48,13 @@ class PiggyBanks
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest()) {
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest() && App::environment() != 'testing') {
|
||||
// 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) {
|
||||
@@ -70,72 +69,8 @@ class PiggyBanks
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use App;
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\Request;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Session;
|
||||
@@ -44,16 +46,16 @@ class Range
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $theNext)
|
||||
public function handle(Request $request, Closure $theNext)
|
||||
{
|
||||
if ($this->auth->check()) {
|
||||
if ($this->auth->check() && App::environment() != 'testing') {
|
||||
|
||||
// ignore preference. set the range to be the current month:
|
||||
if (!Session::has('start') && !Session::has('end')) {
|
||||
|
||||
/** @var \FireflyIII\Models\Preference $viewRange */
|
||||
$viewRange = Preferences::get('viewRange', '1M');
|
||||
$start = Session::has('start') ? Session::get('start') : new Carbon;
|
||||
$start = new Carbon;
|
||||
$start = Navigation::updateStartDate($viewRange->data, $start);
|
||||
$end = Navigation::updateEndDate($viewRange->data, $start);
|
||||
|
||||
@@ -61,11 +63,16 @@ class Range
|
||||
Session::put('end', $end);
|
||||
}
|
||||
if (!Session::has('first')) {
|
||||
$journal = $this->auth->user()->transactionjournals()->orderBy('date', 'ASC')->first(['transaction_journals.*']);
|
||||
/**
|
||||
* Get helper thing.
|
||||
*/
|
||||
/** @var \FireflyIII\Repositories\Journal\JournalRepositoryInterface $repository */
|
||||
$repository = App::make('FireflyIII\Repositories\Journal\JournalRepositoryInterface');
|
||||
$journal = $repository->first();
|
||||
if ($journal) {
|
||||
Session::put('first', $journal->date);
|
||||
} else {
|
||||
Session::put('first', Carbon::now());
|
||||
Session::put('first', Carbon::now()->startOfYear());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,4 +91,4 @@ class Range
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class RedirectIfAuthenticated
|
||||
@@ -38,7 +39,7 @@ class RedirectIfAuthenticated
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check()) {
|
||||
return new RedirectResponse(url('/'));
|
||||
|
||||
@@ -8,6 +8,7 @@ use Closure;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Reminder;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\Request;
|
||||
use View;
|
||||
|
||||
/**
|
||||
@@ -43,9 +44,9 @@ class Reminders
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest()) {
|
||||
if ($this->auth->check() && !$request->isXmlHttpRequest() && App::environment() != 'testing') {
|
||||
// do reminders stuff.
|
||||
$piggyBanks = $this->auth->user()->piggyBanks()->where('remind_me', 1)->get();
|
||||
$today = new Carbon;
|
||||
@@ -87,4 +88,4 @@ class Reminders
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\Routing\Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ReplaceTestVars
|
||||
*
|
||||
* @package App\Http\Middleware
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class ReplaceTestVars implements Middleware
|
||||
class ReplaceTestVars
|
||||
{
|
||||
/**
|
||||
* The application implementation.
|
||||
@@ -40,17 +40,17 @@ class ReplaceTestVars implements Middleware
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ('testing' === $this->app->environment() && $request->has('_token')) {
|
||||
$input = $request->all();
|
||||
$input['_token'] = $request->session()->token();
|
||||
// we need to update _token value to make sure we get the POST / PUT tests passed.
|
||||
Log::debug('Input token replaced ('.$input['_token'].').');
|
||||
Log::debug('Input token replaced (' . $input['_token'] . ').');
|
||||
$request->replace($input);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,22 +28,29 @@ class AccountFormRequest extends Request
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$accountRoles = join(',', array_keys(Config::get('firefly.accountRoles')));
|
||||
$types = join(',', array_keys(Config::get('firefly.subTitlesByIdentifier')));
|
||||
$accountRoles = join(',', array_keys(Config::get('firefly.accountRoles')));
|
||||
$types = join(',', array_keys(Config::get('firefly.subTitlesByIdentifier')));
|
||||
$ccPaymentTypes = join(',', array_keys(Config::get('firefly.ccTypes')));
|
||||
|
||||
$nameRule = 'required|between:1,100|uniqueAccountForUser';
|
||||
$nameRule = 'required|min:1|uniqueAccountForUser';
|
||||
$idRule = '';
|
||||
if (Account::find(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,100|belongsToUser:accounts|uniqueForUser:'.Input::get('id');
|
||||
$idRule = 'belongsToUser:accounts';
|
||||
$nameRule = 'required|min:1|uniqueAccountForUser:' . Input::get('id');
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $nameRule,
|
||||
'openingBalance' => 'numeric',
|
||||
'openingBalanceDate' => 'date',
|
||||
'accountRole' => 'in:' . $accountRoles,
|
||||
'active' => 'boolean',
|
||||
'balance_currency_id' => 'exists:transaction_currencies,id',
|
||||
'what' => 'in:' . $types
|
||||
'id' => $idRule,
|
||||
'name' => $nameRule,
|
||||
'openingBalance' => 'numeric',
|
||||
'virtualBalance' => 'numeric',
|
||||
'openingBalanceDate' => 'date',
|
||||
'accountRole' => 'in:' . $accountRoles,
|
||||
'active' => 'boolean',
|
||||
'ccType' => 'in:' . $ccPaymentTypes,
|
||||
'ccMonthlyPaymentDate' => 'date',
|
||||
'balance_currency_id' => 'exists:transaction_currencies,id',
|
||||
'what' => 'in:' . $types
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
@@ -21,19 +22,41 @@ class BillFormRequest extends Request
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getBillData()
|
||||
{
|
||||
return [
|
||||
'name' => $this->get('name'),
|
||||
'match' => $this->get('match'),
|
||||
'amount_min' => floatval($this->get('amount_min')),
|
||||
'amount_currency_id' => floatval($this->get('amount_currency_id')),
|
||||
'amount_max' => floatval($this->get('amount_max')),
|
||||
'date' => new Carbon($this->get('date')),
|
||||
'user' => Auth::user()->id,
|
||||
'repeat_freq' => $this->get('repeat_freq'),
|
||||
'skip' => intval($this->get('skip')),
|
||||
'automatch' => intval($this->get('automatch')) === 1,
|
||||
'active' => intval($this->get('active')) === 1,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$nameRule = 'required|between:1,255|uniqueForUser:bills,name';
|
||||
$nameRule = 'required|between:1,255|uniqueObjectForUser:bills,name,name_encrypted';
|
||||
$matchRule = 'required|between:1,255|uniqueObjectForUser:bills,match,match_encrypted';
|
||||
if (intval(Input::get('id')) > 0) {
|
||||
$nameRule = 'required|between:1,255';
|
||||
$nameRule .= ',' . intval(Input::get('id'));
|
||||
$matchRule .= ',' . intval(Input::get('id'));
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'name' => $nameRule,
|
||||
'match' => 'required|between:1,255',
|
||||
'match' => $matchRule,
|
||||
'amount_min' => 'required|numeric|min:0.01',
|
||||
'amount_max' => 'required|numeric|min:0.01',
|
||||
'amount_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
@@ -46,4 +69,4 @@ class BillFormRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,14 @@ class BudgetFormRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$nameRule = 'required|between:1,100|uniqueForUser:budgets,name';
|
||||
$nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,encrypted';
|
||||
if (Budget::find(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,100';
|
||||
$nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,encrypted,'.intval(Input::get('id'));
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $nameRule,
|
||||
'name' => $nameRule,
|
||||
'active' => 'numeric|between:0,1'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,13 @@ class CategoryFormRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$nameRule = 'required|between:1,100|uniqueForUser:categories,name';
|
||||
$nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,encrypted';
|
||||
if (Category::find(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,100';
|
||||
$nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,encrypted,'.intval(Input::get('id'));
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $nameRule,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,18 @@ class CurrencyFormRequest extends Request
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCurrencyData()
|
||||
{
|
||||
return [
|
||||
'name' => $this->get('name'),
|
||||
'code' => $this->get('code'),
|
||||
'symbol' => $this->get('symbol'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -42,4 +54,4 @@ class CurrencyFormRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
@@ -25,6 +26,29 @@ class JournalFormRequest extends Request
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getJournalData()
|
||||
{
|
||||
return [
|
||||
'what' => $this->get('what'),
|
||||
'description' => $this->get('description'),
|
||||
'account_id' => intval($this->get('account_id')),
|
||||
'account_from_id' => intval($this->get('account_from_id')),
|
||||
'account_to_id' => intval($this->get('account_to_id')),
|
||||
'expense_account' => $this->get('expense_account'),
|
||||
'revenue_account' => $this->get('revenue_account'),
|
||||
'amount' => floatval($this->get('amount')),
|
||||
'user' => Auth::user()->id,
|
||||
'amount_currency_id' => intval($this->get('amount_currency_id')),
|
||||
'date' => new Carbon($this->get('date')),
|
||||
'budget_id' => intval($this->get('budget_id')),
|
||||
'category' => $this->get('category'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
// can we switch on the "what"?
|
||||
@@ -62,7 +86,7 @@ class JournalFormRequest extends Request
|
||||
$rules['category'] = 'between:1,255';
|
||||
break;
|
||||
default:
|
||||
die('Cannot handle ' . $what);
|
||||
throw new Exception('Cannot handle ' . $what);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -70,4 +94,4 @@ class JournalFormRequest extends Request
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use Input;
|
||||
use Navigation;
|
||||
|
||||
@@ -30,33 +29,20 @@ class PiggyBankFormRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$nameRule = 'required|between:1,255|uniquePiggyBankForUser:piggy_banks,name';
|
||||
$nameRule = 'required|between:1,255|uniquePiggyBankForUser';
|
||||
$targetDateRule = 'date';
|
||||
if (intval(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,255';
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
$nameRule = 'required|between:1,255|uniquePiggyBankForUser:'.intval(Input::get('id'));
|
||||
}
|
||||
|
||||
|
||||
$rules = [
|
||||
'repeats' => 'required|boolean',
|
||||
'name' => $nameRule,
|
||||
'account_id' => 'required|belongsToUser:accounts',
|
||||
'targetamount' => 'required|min:0.01',
|
||||
'amount_currency_id' => 'exists:transaction_currencies,id',
|
||||
'startdate' => 'date',
|
||||
'targetdate' => $targetDateRule,
|
||||
'rep_length' => 'in:day,week,quarter,month,year',
|
||||
'rep_every' => 'integer|min:0|max:31',
|
||||
'rep_times' => 'integer|min:0|max:99',
|
||||
'reminder' => 'in:day,week,quarter,month,year',
|
||||
'reminder_skip' => 'integer|min:0|max:99',
|
||||
'remind_me' => 'boolean|piggyBankReminder',
|
||||
@@ -66,4 +52,4 @@ class PiggyBankFormRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class ProfileFormRequest
|
||||
@@ -27,9 +26,9 @@ class ProfileFormRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'current_password' => 'required',
|
||||
'current_password' => 'required',
|
||||
'new_password' => 'required|confirmed',
|
||||
'new_password_confirmation' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ use Carbon\Carbon;
|
||||
use DaveJamesMiller\Breadcrumbs\Generator;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Reminder;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Reminder;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
/*
|
||||
* Back home.
|
||||
|
||||
@@ -107,7 +107,7 @@ Route::bind(
|
||||
where('piggy_banks.id', $value)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('accounts.user_id', Auth::user()->id)
|
||||
->where('repeats', 0)->first(['piggy_banks.*']);
|
||||
->first(['piggy_banks.*']);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -132,7 +132,7 @@ Route::get('/register', ['uses' => 'Auth\AuthController@getRegister', 'as' => 'r
|
||||
|
||||
Route::controllers(
|
||||
[
|
||||
'auth' => 'Auth\AuthController',
|
||||
'auth' => 'Auth\AuthController',
|
||||
'password' => 'Auth\PasswordController',
|
||||
]
|
||||
);
|
||||
@@ -142,7 +142,7 @@ Route::controllers(
|
||||
* Home Controller
|
||||
*/
|
||||
Route::group(
|
||||
['middleware' => ['auth', 'range', 'reminders','piggybanks']], 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']);
|
||||
@@ -167,6 +167,7 @@ Route::group(
|
||||
Route::get('/bills/rescan/{bill}', ['uses' => 'BillController@rescan', 'as' => 'bills.rescan']); # rescan for matching.
|
||||
Route::get('/bills/create', ['uses' => 'BillController@create', 'as' => 'bills.create']);
|
||||
Route::get('/bills/edit/{bill}', ['uses' => 'BillController@edit', 'as' => 'bills.edit']);
|
||||
Route::get('/bills/add/{bill}', ['uses' => 'BillController@add', 'as' => 'bills.add']);
|
||||
Route::get('/bills/delete/{bill}', ['uses' => 'BillController@delete', 'as' => 'bills.delete']);
|
||||
Route::get('/bills/show/{bill}', ['uses' => 'BillController@show', 'as' => 'bills.show']);
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use App;
|
||||
use Crypt;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use Crypt;
|
||||
|
||||
/**
|
||||
* Class Account
|
||||
*
|
||||
@@ -14,47 +17,45 @@ class Account extends Model
|
||||
{
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
|
||||
protected $fillable = ['user_id', 'account_type_id', 'name', 'active', 'virtual_balance'];
|
||||
protected $rules
|
||||
= [
|
||||
= [
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'account_type_id' => 'required|exists:account_types,id',
|
||||
'name' => 'required|between:1,1024|uniqueAccountForUser',
|
||||
'active' => 'required|boolean'
|
||||
];
|
||||
|
||||
protected $fillable = ['user_id', 'account_type_id', 'name', 'active'];
|
||||
|
||||
/**
|
||||
* @param $fieldName
|
||||
* @param array $fields
|
||||
*
|
||||
* @return string|null
|
||||
* @return Account|null
|
||||
*/
|
||||
public function getMeta($fieldName)
|
||||
public static function firstOrCreateEncrypted(array $fields)
|
||||
{
|
||||
foreach ($this->accountMeta as $meta) {
|
||||
if ($meta->name == $fieldName) {
|
||||
return $meta->data;
|
||||
// everything but the name:
|
||||
$query = Account::orderBy('id');
|
||||
foreach ($fields as $name => $value) {
|
||||
if ($name != 'name') {
|
||||
$query->where($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute($value)
|
||||
{
|
||||
if ($this->encrypted) {
|
||||
return Crypt::decrypt($value);
|
||||
$set = $query->get(['accounts.*']);
|
||||
/** @var Account $account */
|
||||
foreach ($set as $account) {
|
||||
if ($account->name == $fields['name']) {
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
// create it!
|
||||
$account = Account::create($fields);
|
||||
if (is_null($account->id)) {
|
||||
// could not create account:
|
||||
App::abort(500, 'Could not create new account with data: ' . json_encode($fields));
|
||||
|
||||
}
|
||||
return $account;
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $value;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,6 +82,48 @@ class Account extends Model
|
||||
return ['created_at', 'updated_at', 'deleted_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fieldName
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMeta($fieldName)
|
||||
{
|
||||
foreach ($this->accountMeta as $meta) {
|
||||
if ($meta->name == $fieldName) {
|
||||
return $meta->data;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute($value)
|
||||
{
|
||||
|
||||
if (intval($this->encrypted) == 1) {
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $value;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function piggyBanks()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBank');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param array $types
|
||||
@@ -94,6 +137,31 @@ class Account extends Model
|
||||
$query->whereIn('account_types.type', $types);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public function scopeHasMetaValue(EloquentBuilder $query, $name, $value)
|
||||
{
|
||||
$joinName = str_replace('.', '_', $name);
|
||||
$query->leftJoin(
|
||||
'account_meta as ' . $joinName, function (JoinClause $join) use ($joinName, $name) {
|
||||
$join->on($joinName . '.account_id', '=', 'accounts.id')->where($joinName . '.name', '=', $name);
|
||||
}
|
||||
);
|
||||
$query->where($joinName . '.data', json_encode($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setNameAttribute($value)
|
||||
{
|
||||
$this->attributes['name'] = Crypt::encrypt($value);
|
||||
$this->attributes['encrypted'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
@@ -110,12 +178,4 @@ class Account extends Model
|
||||
return $this->belongsTo('FireflyIII\User');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function piggyBanks()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBank');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@ class AccountMeta extends Model
|
||||
use ValidatingTrait;
|
||||
protected $fillable = ['account_id', 'name', 'data'];
|
||||
protected $rules
|
||||
= [
|
||||
= [
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'name' => 'required|between:1,100',
|
||||
'data' => 'required'
|
||||
];
|
||||
protected $table = 'account_meta';
|
||||
protected $table = 'account_meta';
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Crypt;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
@@ -10,7 +11,8 @@ use Illuminate\Database\Eloquent\Model;
|
||||
class Bill extends Model
|
||||
{
|
||||
|
||||
protected $fillable = ['name', 'match', 'amount_min','user_id', 'amount_max', 'date', 'repeat_freq', 'skip', 'automatch', 'active',];
|
||||
protected $fillable
|
||||
= ['name', 'match', 'amount_min', 'match_encrypted', 'name_encrypted', 'user_id', 'amount_max', 'date', 'repeat_freq', 'skip', 'automatch', 'active',];
|
||||
|
||||
/**
|
||||
* @return array
|
||||
@@ -20,6 +22,58 @@ class Bill extends Model
|
||||
return ['created_at', 'updated_at', 'date'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMatchAttribute($value)
|
||||
{
|
||||
|
||||
if (intval($this->match_encrypted) == 1) {
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $value;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute($value)
|
||||
{
|
||||
|
||||
if (intval($this->name_encrypted) == 1) {
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $value;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setMatchAttribute($value)
|
||||
{
|
||||
$this->attributes['match'] = Crypt::encrypt($value);
|
||||
$this->attributes['match_encrypted'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setNameAttribute($value)
|
||||
{
|
||||
$this->attributes['name'] = Crypt::encrypt($value);
|
||||
$this->attributes['name_encrypted'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Crypt;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
@@ -31,6 +32,23 @@ class Budget extends Model
|
||||
return ['created_at', 'updated_at', 'deleted_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute($value)
|
||||
{
|
||||
|
||||
if (intval($this->encrypted) == 1) {
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $value;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||
*/
|
||||
@@ -39,6 +57,15 @@ class Budget extends Model
|
||||
return $this->hasManyThrough('FireflyIII\Models\LimitRepetition', 'FireflyIII\Models\BudgetLimit', 'budget_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setNameAttribute($value)
|
||||
{
|
||||
$this->attributes['name'] = Crypt::encrypt($value);
|
||||
$this->attributes['encrypted'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
use Crypt;
|
||||
/**
|
||||
* Class Category
|
||||
*
|
||||
@@ -38,4 +38,29 @@ class Category extends Model
|
||||
return $this->belongsTo('FireflyIII\User');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setNameAttribute($value)
|
||||
{
|
||||
$this->attributes['name'] = Crypt::encrypt($value);
|
||||
$this->attributes['encrypted'] = true;
|
||||
}
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute($value)
|
||||
{
|
||||
|
||||
if (intval($this->encrypted) == 1) {
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $value;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class Component extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['user_id', 'name','class'];
|
||||
protected $fillable = ['user_id', 'name', 'class'];
|
||||
|
||||
/**
|
||||
* @return array
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App;
|
||||
use Log;
|
||||
use Crypt;
|
||||
/**
|
||||
* Class PiggyBank
|
||||
*
|
||||
@@ -16,8 +13,7 @@ class PiggyBank extends Model
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable
|
||||
= ['repeats', 'name', 'account_id', 'rep_every', 'rep_times', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder', 'remind_me',
|
||||
'rep_length'];
|
||||
= ['name', 'account_id', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder', 'remind_me'];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
@@ -38,15 +34,10 @@ class PiggyBank extends Model
|
||||
return $this->currentRep;
|
||||
}
|
||||
// repeating piggy banks are no longer supported.
|
||||
if (intval($this->repeats) === 0) {
|
||||
$rep = $this->piggyBankRepetitions()->first(['piggy_bank_repetitions.*']);
|
||||
$this->currentRep = $rep;
|
||||
$rep = $this->piggyBankRepetitions()->first(['piggy_bank_repetitions.*']);
|
||||
$this->currentRep = $rep;
|
||||
|
||||
return $rep;
|
||||
} else {
|
||||
Log::error('Tried to work with a piggy bank with a repeats=1 value! (id is '.$this->id.')');
|
||||
//App::abort(500);
|
||||
}
|
||||
return $rep;
|
||||
|
||||
|
||||
}
|
||||
@@ -92,4 +83,29 @@ class PiggyBank extends Model
|
||||
{
|
||||
return $this->morphMany('FireflyIII\Models\Reminder', 'remindersable');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setNameAttribute($value)
|
||||
{
|
||||
$this->attributes['name'] = Crypt::encrypt($value);
|
||||
$this->attributes['encrypted'] = true;
|
||||
}
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute($value)
|
||||
{
|
||||
|
||||
if (intval($this->encrypted) == 1) {
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $value;
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class PiggyBankRepetition
|
||||
*
|
||||
@@ -27,27 +28,6 @@ class PiggyBankRepetition extends Model
|
||||
return $this->belongsTo('FireflyIII\Models\PiggyBank');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeRelevantOnDate(EloquentBuilder $query, Carbon $date)
|
||||
{
|
||||
return $query->where(
|
||||
function($q) use ($date) {
|
||||
$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->orWhereNull('targetdate');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param Carbon $start
|
||||
@@ -57,7 +37,30 @@ class PiggyBankRepetition extends Model
|
||||
*/
|
||||
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'));
|
||||
return $query->where('startdate', $start->format('Y-m-d'))->where('targetdate', $target->format('Y-m-d'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeRelevantOnDate(EloquentBuilder $query, Carbon $date)
|
||||
{
|
||||
return $query->where(
|
||||
function (EloquentBuilder $q) use ($date) {
|
||||
$q->where('startdate', '<=', $date->format('Y-m-d 00:00:00'));
|
||||
$q->orWhereNull('startdate');
|
||||
}
|
||||
)
|
||||
->where(
|
||||
function (EloquentBuilder $q) use ($date) {
|
||||
|
||||
$q->where('targetdate', '>=', $date->format('Y-m-d 00:00:00'));
|
||||
$q->orWhereNull('targetdate');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
use Crypt;
|
||||
/**
|
||||
* Class Reminder
|
||||
*
|
||||
@@ -40,6 +40,9 @@ class Reminder extends Model
|
||||
*/
|
||||
public function getMetadataAttribute($value)
|
||||
{
|
||||
if (intval($this->encrypted) == 1) {
|
||||
return json_decode(Crypt::decrypt($value));
|
||||
}
|
||||
return json_decode($value);
|
||||
}
|
||||
|
||||
@@ -86,7 +89,8 @@ class Reminder extends Model
|
||||
*/
|
||||
public function setMetadataAttribute($value)
|
||||
{
|
||||
$this->attributes['metadata'] = json_encode($value);
|
||||
$this->attributes['encrypted'] = true;
|
||||
$this->attributes['metadata'] = Crypt::encrypt(json_encode($value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Carbon\Carbon;
|
||||
/**
|
||||
* Class Transaction
|
||||
*
|
||||
@@ -30,6 +31,28 @@ class Transaction extends Model
|
||||
return $this->belongsTo('FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeAfter(EloquentBuilder $query, Carbon $date)
|
||||
{
|
||||
return $query->where('transaction_journals.date', '>=', $date->format('Y-m-d 00:00:00'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeBefore(EloquentBuilder $query, Carbon $date)
|
||||
{
|
||||
return $query->where('transaction_journals.date', '<=', $date->format('Y-m-d 00:00:00'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php namespace FireflyIII\Providers;
|
||||
|
||||
use App;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
@@ -14,7 +12,7 @@ use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Log;
|
||||
|
||||
use Reminder;
|
||||
/**
|
||||
* Class EventServiceProvider
|
||||
*
|
||||
@@ -30,7 +28,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
*/
|
||||
protected $listen
|
||||
= [
|
||||
'FireflyIII\Events\JournalSaved' => [
|
||||
'FireflyIII\Events\JournalSaved' => [
|
||||
'FireflyIII\Handlers\Events\RescanJournal',
|
||||
'FireflyIII\Handlers\Events\UpdateJournalConnection',
|
||||
|
||||
@@ -62,6 +60,14 @@ class EventServiceProvider extends ServiceProvider
|
||||
);
|
||||
|
||||
|
||||
PiggyBank::deleting(function(PiggyBank $piggyBank) {
|
||||
$reminders = $piggyBank->reminders()->get();
|
||||
/** @var Reminder $reminder */
|
||||
foreach($reminders as $reminder) {
|
||||
$reminder->delete();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Account::deleted(
|
||||
function (Account $account) {
|
||||
|
||||
@@ -62,6 +62,7 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
$this->app->bind('FireflyIII\Repositories\Journal\JournalRepositoryInterface', 'FireflyIII\Repositories\Journal\JournalRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Bill\BillRepositoryInterface', 'FireflyIII\Repositories\Bill\BillRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', 'FireflyIII\Repositories\PiggyBank\PiggyBankRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', 'FireflyIII\Repositories\Currency\CurrencyRepository');
|
||||
$this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
|
||||
|
||||
|
||||
@@ -71,4 +72,4 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php namespace FireflyIII\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Router;
|
||||
|
||||
/**
|
||||
@@ -32,22 +31,6 @@ class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
parent::boot($router);
|
||||
|
||||
$router->before(
|
||||
function (Request $request) {
|
||||
|
||||
// put IP in session if not already there.
|
||||
|
||||
$reminders = [];
|
||||
|
||||
if ($request->user()) {
|
||||
//Filter::setSessionDateRange();
|
||||
//Reminders::updateReminders();
|
||||
//Steam::removeEmptyBudgetLimits();
|
||||
//$reminders = Reminders::getReminders();
|
||||
}
|
||||
// View::share('reminders', $reminders);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,4 +25,4 @@ class TestingServiceProvider extends ServiceProvider
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
@@ -29,11 +30,13 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countAssetAccounts()
|
||||
public function countAccounts(array $types)
|
||||
{
|
||||
return Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->count();
|
||||
return Auth::user()->accounts()->accountTypeIn($types)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,6 +51,42 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
* @param int $page
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAccounts(array $types, $page)
|
||||
{
|
||||
$query = Auth::user()->accounts()->with(
|
||||
['accountmeta' => function (HasMany $query) {
|
||||
$query->where('name', 'accountRole');
|
||||
}]
|
||||
)->accountTypeIn($types)->orderBy('accounts.name', 'ASC');
|
||||
|
||||
if ($page == -1) {
|
||||
return $query->get(['accounts.*']);
|
||||
} else {
|
||||
$size = 50;
|
||||
$offset = ($page - 1) * $size;
|
||||
|
||||
return $query->take($size)->offset($offset)->get(['accounts.*']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Transaction
|
||||
*/
|
||||
public function getFirstTransaction(TransactionJournal $journal, Account $account)
|
||||
{
|
||||
|
||||
return $journal->transactions()->where('account_id', $account->id)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Preference $preference
|
||||
*
|
||||
@@ -106,9 +145,9 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
->withRelevantData()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->where('transactions.account_id', $account->id)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','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()));
|
||||
@@ -118,9 +157,24 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
return $paginator;
|
||||
|
||||
//return Paginator::make($items, $count, 50);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function getLastActivity(Account $account)
|
||||
{
|
||||
$lastTransaction = $account->transactions()->leftJoin(
|
||||
'transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
)->orderBy('transaction_journals.date', 'DESC')->first(['transactions.*', 'transaction_journals.date']);
|
||||
if ($lastTransaction) {
|
||||
return $lastTransaction->transactionjournal->date;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,8 +189,8 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
->where('account_meta.name', 'accountRole')
|
||||
->where('account_meta.data', '"savingAsset"')
|
||||
->get(['accounts.*']);
|
||||
$start = clone Session::get('start');
|
||||
$end = clone Session::get('end');
|
||||
$start = clone Session::get('start', new Carbon);
|
||||
$end = clone Session::get('end', new Carbon);
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($start, $end) {
|
||||
@@ -172,7 +226,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function leftOnAccount(Account $account)
|
||||
{
|
||||
$balance = \Steam::balance($account);
|
||||
$balance = \Steam::balance($account, null, true);
|
||||
/** @var PiggyBank $p */
|
||||
foreach ($account->piggybanks()->get() as $p) {
|
||||
$balance -= $p->currentRelevantRep()->currentamount;
|
||||
@@ -202,21 +256,22 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
$newAccount = $this->_store($data);
|
||||
$this->_storeMetadata($newAccount, $data);
|
||||
$newAccount = $this->storeAccount($data);
|
||||
$this->storeMetadata($newAccount, $data);
|
||||
|
||||
|
||||
// continue with the opposing account:
|
||||
if ($data['openingBalance'] != 0) {
|
||||
$type = $data['openingBalance'] < 0 ? 'expense' : 'revenue';
|
||||
$opposingData = [
|
||||
'user' => $data['user'],
|
||||
'accountType' => $type,
|
||||
'name' => $data['name'] . ' initial balance',
|
||||
'active' => false,
|
||||
'user' => $data['user'],
|
||||
'accountType' => $type,
|
||||
'virtual_balance' => $data['virtualBalance'],
|
||||
'name' => $data['name'] . ' initial balance',
|
||||
'active' => false,
|
||||
];
|
||||
$opposing = $this->_store($opposingData);
|
||||
$this->_storeInitialBalance($newAccount, $opposing, $data);
|
||||
$opposing = $this->storeAccount($opposingData);
|
||||
$this->storeInitialBalance($newAccount, $opposing, $data);
|
||||
|
||||
}
|
||||
|
||||
@@ -231,12 +286,13 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
public function update(Account $account, array $data)
|
||||
{
|
||||
// update the account:
|
||||
$account->name = $data['name'];
|
||||
$account->active = $data['active'] == '1' ? true : false;
|
||||
$account->name = $data['name'];
|
||||
$account->active = $data['active'] == '1' ? true : false;
|
||||
$account->virtual_balance = $data['virtualBalance'];
|
||||
$account->save();
|
||||
|
||||
// update meta data:
|
||||
$this->_updateMetadata($account, $data);
|
||||
$this->updateMetadata($account, $data);
|
||||
|
||||
$openingBalance = $this->openingBalanceTransaction($account);
|
||||
|
||||
@@ -245,7 +301,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
// if opening balance, do an update:
|
||||
if ($openingBalance) {
|
||||
// update existing opening balance.
|
||||
$this->_updateInitialBalance($account, $openingBalance, $data);
|
||||
$this->updateInitialBalance($account, $openingBalance, $data);
|
||||
} else {
|
||||
// create new opening balance.
|
||||
$type = $data['openingBalance'] < 0 ? 'expense' : 'revenue';
|
||||
@@ -255,8 +311,8 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
'name' => $data['name'] . ' initial balance',
|
||||
'active' => false,
|
||||
];
|
||||
$opposing = $this->_store($opposingData);
|
||||
$this->_storeInitialBalance($account, $opposing, $data);
|
||||
$opposing = $this->storeAccount($opposingData);
|
||||
$this->storeInitialBalance($account, $opposing, $data);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -275,7 +331,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
protected function _store(array $data)
|
||||
protected function storeAccount(array $data)
|
||||
{
|
||||
$type = Config::get('firefly.accountTypeByIdentifier.' . $data['accountType']);
|
||||
$accountType = AccountType::whereType($type)->first();
|
||||
@@ -307,19 +363,23 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
protected function _storeMetadata(Account $account, array $data)
|
||||
protected function storeMetadata(Account $account, array $data)
|
||||
{
|
||||
$metaData = new AccountMeta(
|
||||
[
|
||||
'account_id' => $account->id,
|
||||
'name' => 'accountRole',
|
||||
'data' => $data['accountRole']
|
||||
]
|
||||
);
|
||||
if (!$metaData->isValid()) {
|
||||
App::abort(500);
|
||||
$validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType'];
|
||||
foreach ($validFields as $field) {
|
||||
if (isset($data[$field])) {
|
||||
$metaData = new AccountMeta(
|
||||
[
|
||||
'account_id' => $account->id,
|
||||
'name' => $field,
|
||||
'data' => $data[$field]
|
||||
]
|
||||
);
|
||||
$metaData->save();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
$metaData->save();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -329,7 +389,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
protected function _storeInitialBalance(Account $account, Account $opposing, array $data)
|
||||
protected function storeInitialBalance(Account $account, Account $opposing, array $data)
|
||||
{
|
||||
$type = $data['openingBalance'] < 0 ? 'Withdrawal' : 'Deposit';
|
||||
$transactionType = TransactionType::whereType($type)->first();
|
||||
@@ -398,32 +458,30 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
protected function _updateMetadata(Account $account, array $data)
|
||||
protected function updateMetadata(Account $account, array $data)
|
||||
{
|
||||
$metaEntries = $account->accountMeta()->get();
|
||||
$validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType'];
|
||||
$updated = false;
|
||||
|
||||
/** @var AccountMeta $entry */
|
||||
foreach ($metaEntries as $entry) {
|
||||
if ($entry->name == 'accountRole') {
|
||||
$entry->data = $data['accountRole'];
|
||||
$updated = true;
|
||||
foreach ($validFields as $field) {
|
||||
$entry = $account->accountMeta()->where('name', $field)->first();
|
||||
|
||||
// update if new data is present:
|
||||
if ($entry && isset($data[$field])) {
|
||||
$entry->data = $data[$field];
|
||||
$entry->save();
|
||||
}
|
||||
}
|
||||
|
||||
if ($updated === false) {
|
||||
$metaData = new AccountMeta(
|
||||
[
|
||||
'account_id' => $account->id,
|
||||
'name' => 'accountRole',
|
||||
'data' => $data['accountRole']
|
||||
]
|
||||
);
|
||||
if (!$metaData->isValid()) {
|
||||
App::abort(500);
|
||||
// no entry but data present?
|
||||
if (!$entry && isset($data[$field])) {
|
||||
$metaData = new AccountMeta(
|
||||
[
|
||||
'account_id' => $account->id,
|
||||
'name' => $field,
|
||||
'data' => $data[$field]
|
||||
]
|
||||
);
|
||||
$metaData->save();
|
||||
}
|
||||
$metaData->save();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -435,7 +493,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
protected function _updateInitialBalance(Account $account, TransactionJournal $journal, array $data)
|
||||
protected function updateInitialBalance(Account $account, TransactionJournal $journal, array $data)
|
||||
{
|
||||
$journal->date = $data['openingBalanceDate'];
|
||||
|
||||
@@ -453,4 +511,4 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
return $journal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace FireflyIII\Repositories\Account;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Preference;
|
||||
use Illuminate\Support\Collection;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface AccountRepositoryInterface
|
||||
*
|
||||
@@ -14,6 +16,13 @@ use Carbon\Carbon;
|
||||
*/
|
||||
interface AccountRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param array $types
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countAccounts(array $types);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
@@ -22,9 +31,20 @@ interface AccountRepositoryInterface
|
||||
public function destroy(Account $account);
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @param array $types
|
||||
* @param int $page
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function countAssetAccounts();
|
||||
public function getAccounts(array $types, $page);
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Transaction
|
||||
*/
|
||||
public function getFirstTransaction(TransactionJournal $journal, Account $account);
|
||||
|
||||
/**
|
||||
* @param Preference $preference
|
||||
@@ -50,6 +70,27 @@ interface AccountRepositoryInterface
|
||||
*/
|
||||
public function getJournals(Account $account, $page);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function getLastActivity(Account $account);
|
||||
|
||||
/**
|
||||
* Get savings accounts and the balance difference in the period.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getSavingsAccounts();
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function leftOnAccount(Account $account);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
@@ -71,18 +112,4 @@ interface AccountRepositoryInterface
|
||||
* @return Account
|
||||
*/
|
||||
public function update(Account $account, array $data);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function leftOnAccount(Account $account);
|
||||
|
||||
/**
|
||||
* Get savings accounts and the balance difference in the period.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getSavingsAccounts();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
namespace FireflyIII\Repositories\Bill;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Navigation;
|
||||
|
||||
@@ -15,6 +18,62 @@ use Navigation;
|
||||
*/
|
||||
class BillRepository implements BillRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function destroy(Bill $bill)
|
||||
{
|
||||
return $bill->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBills()
|
||||
{
|
||||
return Auth::user()->bills()->orderBy('name', 'ASC')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournals(Bill $bill)
|
||||
{
|
||||
return $bill->transactionjournals()->withRelevantData()
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getPossiblyRelatedJournals(Bill $bill)
|
||||
{
|
||||
$set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)->get(
|
||||
['transaction_journal_id']
|
||||
);
|
||||
$ids = [];
|
||||
|
||||
/** @var Transaction $entry */
|
||||
foreach ($set as $entry) {
|
||||
$ids[] = intval($entry->transaction_journal_id);
|
||||
}
|
||||
$journals = new Collection;
|
||||
if (count($ids) > 0) {
|
||||
$journals = Auth::user()->transactionjournals()->whereIn('id', $ids)->get();
|
||||
}
|
||||
|
||||
return $journals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Every bill repeats itself weekly, monthly or yearly (or whatever). This method takes a date-range (usually the view-range of Firefly itself)
|
||||
* and returns date ranges that fall within the given range; those ranges are the bills expected. When a bill is due on the 14th of the month and
|
||||
@@ -51,16 +110,26 @@ class BillRepository implements BillRepositoryInterface
|
||||
foreach ($billStarts as $dateEntry) {
|
||||
if ($dateEntry['end'] > $start && $dateEntry['start'] < $end) {
|
||||
// count transactions for bill in this range (not relevant yet!):
|
||||
// $count = $bill->transactionjournals()->before($dateEntry['end'])->after($dateEntry['start'])->count();
|
||||
// if ($count == 0) {
|
||||
$validRanges[] = $dateEntry;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return $validRanges;
|
||||
// echo $bill->name;
|
||||
// var_dump($validRanges);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function lastFoundMatch(Bill $bill)
|
||||
{
|
||||
$last = $bill->transactionjournals()->orderBy('date', 'DESC')->first();
|
||||
if ($last) {
|
||||
return $last->date;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,13 +5,61 @@ namespace FireflyIII\Repositories\Bill;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface BillRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Bill
|
||||
*/
|
||||
interface BillRepositoryInterface {
|
||||
interface BillRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function destroy(Bill $bill);
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBills();
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getPossiblyRelatedJournals(Bill $bill);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournals(Bill $bill);
|
||||
|
||||
/**
|
||||
* Every bill repeats itself weekly, monthly or yearly (or whatever). This method takes a date-range (usually the view-range of Firefly itself)
|
||||
* and returns date ranges that fall within the given range; those ranges are the bills expected. When a bill is due on the 14th of the month and
|
||||
* you give 1st and the 31st of that month as argument, you'll get one response, matching the range of your bill.
|
||||
*
|
||||
* @param Bill $bill
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRanges(Bill $bill, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function lastFoundMatch(Bill $bill);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
@@ -21,17 +69,12 @@ interface BillRepositoryInterface {
|
||||
public function nextExpectedMatch(Bill $bill);
|
||||
|
||||
/**
|
||||
* Every bill repeats itself weekly, monthly or yearly (or whatever). This method takes a date-range (usually the view-range of Firefly itself)
|
||||
* and returns date ranges that fall within the given range; those ranges are the bills expected. When a bill is due on the 14th of the month and
|
||||
* you give 1st and the 31st of that month as argument, you'll get one response, matching the range of your bill.
|
||||
* @param Bill $bill
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @param Bill $bill
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
* @return bool
|
||||
*/
|
||||
public function getRanges(Bill $bill, Carbon $start, Carbon $end);
|
||||
public function scan(Bill $bill, TransactionJournal $journal);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
@@ -48,12 +91,4 @@ interface BillRepositoryInterface {
|
||||
*/
|
||||
public function update(Bill $bill, array $data);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function scan(Bill $bill, TransactionJournal $journal);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace FireflyIII\Repositories\Budget;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class BudgetRepository
|
||||
@@ -16,6 +18,31 @@ use Illuminate\Pagination\LengthAwarePaginator;
|
||||
class BudgetRepository implements BudgetRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function cleanupBudgets()
|
||||
{
|
||||
$limits = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')->get(['budget_limits.*']);
|
||||
|
||||
// loop budget limits:
|
||||
$found = [];
|
||||
/** @var BudgetLimit $limit */
|
||||
foreach ($limits as $limit) {
|
||||
$key = $limit->budget_id . '-' . $limit->startdate;
|
||||
if (isset($found[$key])) {
|
||||
$limit->delete();
|
||||
} else {
|
||||
$found[$key] = true;
|
||||
}
|
||||
unset($key);
|
||||
}
|
||||
|
||||
// delete limits with amount 0:
|
||||
BudgetLimit::where('amount', 0)->delete();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
@@ -28,6 +55,33 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getActiveBudgets()
|
||||
{
|
||||
return Auth::user()->budgets()->where('active', 1)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return LimitRepetition|null
|
||||
*/
|
||||
public function getCurrentRepetition(Budget $budget, Carbon $date)
|
||||
{
|
||||
return $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getInactiveBudgets()
|
||||
{
|
||||
return Auth::user()->budgets()->where('active', 1)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the transaction journals for a limit, possibly limited by a limit repetition.
|
||||
*
|
||||
@@ -43,9 +97,9 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
|
||||
|
||||
$setQuery = $budget->transactionJournals()->withRelevantData()->take($take)->offset($offset)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order','ASC')
|
||||
->orderBy('transaction_journals.id','DESC');
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC');
|
||||
$countQuery = $budget->transactionJournals();
|
||||
|
||||
|
||||
@@ -57,9 +111,30 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
|
||||
$set = $setQuery->get(['transaction_journals.*']);
|
||||
$count = $countQuery->count();
|
||||
|
||||
return new LengthAwarePaginator($set, $count, $take, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getWithoutBudget(Carbon $start, Carbon $end)
|
||||
{
|
||||
return Auth::user()
|
||||
->transactionjournals()
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('budget_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->get(['transaction_journals.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
@@ -103,7 +178,8 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
public function update(Budget $budget, array $data)
|
||||
{
|
||||
// update the account:
|
||||
$budget->name = $data['name'];
|
||||
$budget->name = $data['name'];
|
||||
$budget->active = $data['active'];
|
||||
$budget->save();
|
||||
|
||||
return $budget;
|
||||
@@ -118,10 +194,12 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
*/
|
||||
public function updateLimitAmount(Budget $budget, Carbon $date, $amount)
|
||||
{
|
||||
// there should be a budget limit for this startdate:
|
||||
/** @var BudgetLimit $limit */
|
||||
$limit = $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']);
|
||||
$limit = $budget->budgetlimits()->where('budget_limits.startdate', $date)->first(['budget_limits.*']);
|
||||
|
||||
if (!$limit) {
|
||||
// create one!
|
||||
// if not, create one!
|
||||
$limit = new BudgetLimit;
|
||||
$limit->budget()->associate($budget);
|
||||
$limit->startdate = $date;
|
||||
@@ -129,6 +207,10 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
$limit->repeat_freq = 'monthly';
|
||||
$limit->repeats = 0;
|
||||
$limit->save();
|
||||
|
||||
// likewise, there should be a limit repetition to match the end date
|
||||
// (which is always the end of the month) but that is caught by an event.
|
||||
|
||||
} else {
|
||||
if ($amount > 0) {
|
||||
$limit->amount = $amount;
|
||||
@@ -142,4 +224,14 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBudgetLimits(Budget $budget)
|
||||
{
|
||||
return $budget->budgetLimits()->orderBy('startdate', 'DESC')->get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace FireflyIII\Repositories\Budget;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface BudgetRepositoryInterface
|
||||
@@ -20,6 +21,21 @@ interface BudgetRepositoryInterface
|
||||
*/
|
||||
public function destroy(Budget $budget);
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getActiveBudgets();
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getInactiveBudgets();
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function cleanupBudgets();
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
@@ -28,6 +44,29 @@ interface BudgetRepositoryInterface
|
||||
*/
|
||||
public function spentInMonth(Budget $budget, Carbon $date);
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getWithoutBudget(Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBudgetLimits(Budget $budget);
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return LimitRepetition|null
|
||||
*/
|
||||
public function getCurrentRepetition(Budget $budget, Carbon $date);
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
@@ -63,4 +102,4 @@ interface BudgetRepositoryInterface
|
||||
*/
|
||||
public function getJournals(Budget $budget, LimitRepetition $repetition = null, $take = 50);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
namespace FireflyIII\Repositories\Category;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Category;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class CategoryRepository
|
||||
@@ -12,6 +15,17 @@ use FireflyIII\Models\Category;
|
||||
class CategoryRepository implements CategoryRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countJournals(Category $category)
|
||||
{
|
||||
return $category->transactionJournals()->count();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
@@ -24,6 +38,72 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getCategories()
|
||||
{
|
||||
return Auth::user()->categories()->orderBy('name', 'ASC')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param int $page
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournals(Category $category, $page)
|
||||
{
|
||||
$offset = $page > 0 ? $page * 50 : 0;
|
||||
|
||||
return $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.*']
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function getLatestActivity(Category $category)
|
||||
{
|
||||
$latest = $category->transactionjournals()
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->first();
|
||||
if ($latest) {
|
||||
return $latest->date;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getWithoutCategory(Carbon $start, Carbon $end)
|
||||
{
|
||||
return Auth::user()
|
||||
->transactionjournals()
|
||||
->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('category_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->get(['transaction_journals.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
@@ -57,5 +137,4 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
namespace FireflyIII\Repositories\Category;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Category;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface CategoryRepositoryInterface
|
||||
@@ -11,6 +13,13 @@ use FireflyIII\Models\Category;
|
||||
*/
|
||||
interface CategoryRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countJournals(Category $category);
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
@@ -18,6 +27,34 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function destroy(Category $category);
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getCategories();
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param int $page
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournals(Category $category, $page);
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function getLatestActivity(Category $category);
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getWithoutCategory(Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
@@ -33,4 +70,4 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function update(Category $category, array $data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
84
app/Repositories/Currency/CurrencyRepository.php
Normal file
84
app/Repositories/Currency/CurrencyRepository.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Currency;
|
||||
|
||||
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class CurrencyRepository
|
||||
*
|
||||
* @package FireflyIII\Repositories\Currency
|
||||
*/
|
||||
class CurrencyRepository implements CurrencyRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countJournals(TransactionCurrency $currency)
|
||||
{
|
||||
return $currency->transactionJournals()->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return TransactionCurrency::get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Preference $preference
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function getCurrencyByPreference(Preference $preference)
|
||||
{
|
||||
$preferred = TransactionCurrency::whereCode($preference->data)->first();
|
||||
if (is_null($preferred)) {
|
||||
$preferred = TransactionCurrency::first();
|
||||
}
|
||||
|
||||
return $preferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
$currency = TransactionCurrency::create(
|
||||
[
|
||||
'name' => $data['name'],
|
||||
'code' => $data['code'],
|
||||
'symbol' => $data['symbol'],
|
||||
]
|
||||
);
|
||||
|
||||
return $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function update(TransactionCurrency $currency, array $data)
|
||||
{
|
||||
$currency->code = $data['code'];
|
||||
$currency->symbol = $data['symbol'];
|
||||
$currency->name = $data['name'];
|
||||
$currency->save();
|
||||
|
||||
return $currency;
|
||||
}
|
||||
}
|
||||
52
app/Repositories/Currency/CurrencyRepositoryInterface.php
Normal file
52
app/Repositories/Currency/CurrencyRepositoryInterface.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Currency;
|
||||
|
||||
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface CurrencyRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Currency
|
||||
*/
|
||||
interface CurrencyRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countJournals(TransactionCurrency $currency);
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function get();
|
||||
|
||||
/**
|
||||
* @param Preference $preference
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function getCurrencyByPreference(Preference $preference);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function store(array $data);
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionCurrency
|
||||
*/
|
||||
public function update(TransactionCurrency $currency, array $data);
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace FireflyIII\Repositories\Journal;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
@@ -21,6 +22,16 @@ use Log;
|
||||
class JournalRepository implements JournalRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Get users first transaction journal
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
return Auth::user()->transactionjournals()->orderBy('date', 'ASC')->first(['transaction_journals.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the account_id, which is the asset account that paid for the transaction.
|
||||
@@ -140,41 +151,7 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
}
|
||||
|
||||
// store accounts (depends on type)
|
||||
switch ($transactionType->type) {
|
||||
case 'Withdrawal':
|
||||
|
||||
$from = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['expense_account']) > 0) {
|
||||
$toType = AccountType::where('type', 'Expense account')->first();
|
||||
$to = Account::firstOrCreate(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => $data['expense_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$to = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Deposit':
|
||||
$to = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['revenue_account']) > 0) {
|
||||
$fromType = AccountType::where('type', 'Revenue account')->first();
|
||||
$from = Account::firstOrCreate(
|
||||
['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => $data['revenue_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$from = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'Transfer':
|
||||
$from = Account::find($data['account_from_id']);
|
||||
$to = Account::find($data['account_to_id']);
|
||||
break;
|
||||
}
|
||||
list($from, $to) = $this->storeAccounts($transactionType, $data);
|
||||
|
||||
// store accompanying transactions.
|
||||
Transaction::create( // first transaction.
|
||||
@@ -199,7 +176,6 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $data
|
||||
@@ -229,41 +205,7 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
}
|
||||
|
||||
// store accounts (depends on type)
|
||||
switch ($journal->transactionType->type) {
|
||||
case 'Withdrawal':
|
||||
|
||||
$from = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['expense_account']) > 0) {
|
||||
$toType = AccountType::where('type', 'Expense account')->first();
|
||||
$to = Account::firstOrCreate(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => $data['expense_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$to = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Deposit':
|
||||
$to = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['revenue_account']) > 0) {
|
||||
$fromType = AccountType::where('type', 'Revenue account')->first();
|
||||
$from = Account::firstOrCreate(
|
||||
['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => $data['revenue_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$from = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'Transfer':
|
||||
$from = Account::find($data['account_from_id']);
|
||||
$to = Account::find($data['account_to_id']);
|
||||
break;
|
||||
}
|
||||
list($from, $to) = $this->storeAccounts($journal->transactionType, $data);
|
||||
|
||||
// update the from and to transaction.
|
||||
/** @var Transaction $transaction */
|
||||
@@ -275,7 +217,7 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
$transaction->save();
|
||||
}
|
||||
if (floatval($transaction->amount) > 0) {
|
||||
$transaction->amount = $data['amount'];
|
||||
$transaction->amount = $data['amount'];
|
||||
$transaction->account_id = $to->id;
|
||||
$transaction->save();
|
||||
}
|
||||
@@ -287,4 +229,65 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
return $journal;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @param TransactionType $type
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function storeAccounts(TransactionType $type, array $data)
|
||||
{
|
||||
$from = null;
|
||||
$to = null;
|
||||
switch ($type->type) {
|
||||
case 'Withdrawal':
|
||||
|
||||
$from = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['expense_account']) > 0) {
|
||||
$toType = AccountType::where('type', 'Expense account')->first();
|
||||
$to = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => $data['expense_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$to = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Deposit':
|
||||
$to = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['revenue_account']) > 0) {
|
||||
$fromType = AccountType::where('type', 'Revenue account')->first();
|
||||
$from = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => $data['revenue_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$from = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'Transfer':
|
||||
$from = Account::find($data['account_from_id']);
|
||||
$to = Account::find($data['account_to_id']);
|
||||
break;
|
||||
}
|
||||
if (is_null($to->id)) {
|
||||
Log::error('"to"-account is null, so we cannot continue!');
|
||||
App::abort(500, '"to"-account is null, so we cannot continue!');
|
||||
}
|
||||
if (is_null($from->id)) {
|
||||
Log::error('"from"-account is null, so we cannot continue!');
|
||||
App::abort(500, '"from"-account is null, so we cannot continue!');
|
||||
}
|
||||
|
||||
return [$from, $to];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace FireflyIII\Repositories\Journal;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@@ -44,4 +45,10 @@ interface JournalRepositoryInterface
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(TransactionJournal $journal, array $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users first transaction journal
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function first();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ use Auth;
|
||||
use DB;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Reminder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Navigation;
|
||||
|
||||
@@ -98,7 +97,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
->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]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +111,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
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.*']);
|
||||
->where('piggy_banks.id', $id)->first(['piggy_banks.*']);
|
||||
if ($piggyBank) {
|
||||
$piggyBank->order = $order;
|
||||
$piggyBank->save();
|
||||
@@ -155,13 +153,10 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
$piggyBank->targetdate = $data['targetdate'];
|
||||
$piggyBank->reminder = $data['reminder'];
|
||||
$piggyBank->startdate = $data['startdate'];
|
||||
$piggyBank->rep_length = isset($data['rep_length']) ? $data['rep_length'] : null;
|
||||
$piggyBank->rep_every = isset($data['rep_every']) ? $data['rep_every'] : null;
|
||||
$piggyBank->rep_times = isset($data['rep_times']) ? $data['rep_times'] : null;
|
||||
$piggyBank->remind_me = isset($data['remind_me']) && $data['remind_me'] == '1' ? 1 : 0;
|
||||
|
||||
$piggyBank->save();
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Reminder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Carbon\Carbon;
|
||||
|
||||
/**
|
||||
* Interface PiggyBankRepositoryInterface
|
||||
@@ -39,6 +37,7 @@ interface PiggyBankRepositoryInterface
|
||||
|
||||
/**
|
||||
* Set all piggy banks to order 0.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reset();
|
||||
@@ -55,7 +54,6 @@ interface PiggyBankRepositoryInterface
|
||||
public function setOrder($id, $order);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
@@ -70,4 +68,4 @@ interface PiggyBankRepositoryInterface
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function update(PiggyBank $piggyBank, array $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
use FireflyIII\Models\Reminder;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Reminder;
|
||||
|
||||
/**
|
||||
* Class PiggyBankPart
|
||||
|
||||
@@ -6,6 +6,7 @@ use Cache;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences as Prefs;
|
||||
|
||||
/**
|
||||
@@ -134,6 +135,14 @@ class Amount
|
||||
return $this->formatWithSymbol($symbol, $amount, $coloured);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAllCurrencies()
|
||||
{
|
||||
return TransactionCurrency::orderBy('code', 'ASC')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@@ -166,4 +175,4 @@ class Amount
|
||||
|
||||
return $currency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class ExpandedForm
|
||||
$options['step'] = 'any';
|
||||
$options['min'] = '0.01';
|
||||
$defaultCurrency = isset($options['currency']) ? $options['currency'] : Amt::getDefaultCurrency();
|
||||
$currencies = TransactionCurrency::orderBy('code', 'ASC')->get();
|
||||
$currencies = Amt::getAllCurrencies();
|
||||
$html = View::make('form.amount', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
@@ -53,18 +53,22 @@ class ExpandedForm
|
||||
return $options['label'];
|
||||
}
|
||||
$labels = [
|
||||
'amount_min' => 'Amount (min)',
|
||||
'amount_max' => 'Amount (max)',
|
||||
'match' => 'Matches on',
|
||||
'repeat_freq' => 'Repetition',
|
||||
'account_from_id' => 'Account from',
|
||||
'account_to_id' => 'Account to',
|
||||
'account_id' => 'Asset account',
|
||||
'budget_id' => 'Budget',
|
||||
'openingBalance' => 'Opening balance',
|
||||
'accountRole' => 'Account role',
|
||||
'openingBalanceDate' => 'Opening balance date',
|
||||
'piggy_bank_id' => 'Piggy bank'];
|
||||
'amount_min' => 'Amount (min)',
|
||||
'amount_max' => 'Amount (max)',
|
||||
'match' => 'Matches on',
|
||||
'repeat_freq' => 'Repetition',
|
||||
'account_from_id' => 'Account from',
|
||||
'account_to_id' => 'Account to',
|
||||
'account_id' => 'Asset account',
|
||||
'budget_id' => 'Budget',
|
||||
'openingBalance' => 'Opening balance',
|
||||
'virtualBalance' => 'Virtual balance',
|
||||
'targetamount' => 'Target amount',
|
||||
'accountRole' => 'Account role',
|
||||
'openingBalanceDate' => 'Opening balance date',
|
||||
'ccType' => 'Credit card payment plan',
|
||||
'ccMonthlyPaymentDate' => 'Credit card monthly payment date',
|
||||
'piggy_bank_id' => 'Piggy bank'];
|
||||
|
||||
|
||||
return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name));
|
||||
@@ -143,7 +147,7 @@ class ExpandedForm
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$options['step'] = 'any';
|
||||
$defaultCurrency = isset($options['currency']) ? $options['currency'] : Amt::getDefaultCurrency();
|
||||
$currencies = TransactionCurrency::orderBy('code', 'ASC')->get();
|
||||
$currencies = Amt::getAllCurrencies();
|
||||
$html = View::make('form.balance', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
@@ -190,6 +194,24 @@ class ExpandedForm
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function month($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$html = View::make('form.month', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
@@ -314,4 +336,4 @@ class ExpandedForm
|
||||
return $html;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ class Amount extends Facade
|
||||
return 'amount';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ class ExpandedForm extends Facade
|
||||
return 'expandedform';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ class Navigation extends Facade
|
||||
return 'navigation';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ class Preferences extends Facade
|
||||
return 'preferences';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ class Steam extends Facade
|
||||
return 'steam';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,6 +344,48 @@ class Navigation
|
||||
throw new FireflyException('Cannot do startOfPeriod for $repeat_freq ' . $repeatFreq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param $repeatFreq
|
||||
* @param int $subtract
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function subtractPeriod(Carbon $theDate, $repeatFreq, $subtract = 1)
|
||||
{
|
||||
$date = clone $theDate;
|
||||
|
||||
$functionMap = [
|
||||
'daily' => 'subDays',
|
||||
'week' => 'subWeeks',
|
||||
'weekly' => 'subWeeks',
|
||||
'month' => 'subMonths',
|
||||
'monthly' => 'subMonths',
|
||||
'year' => 'subYears',
|
||||
'yearly' => 'subYears',
|
||||
];
|
||||
$modifierMap = [
|
||||
'quarter' => 3,
|
||||
'quarterly' => 3,
|
||||
'half-year' => 6,
|
||||
];
|
||||
if (isset($functionMap[$repeatFreq])) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$date->$function($subtract);
|
||||
|
||||
return $date;
|
||||
}
|
||||
if (isset($modifierMap[$repeatFreq])) {
|
||||
$subtract = $subtract * $modifierMap[$repeatFreq];
|
||||
$date->subMonths($subtract);
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
throw new FireflyException('Cannot do subtractPeriod for $repeat_freq ' . $repeatFreq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $range
|
||||
* @param Carbon $start
|
||||
@@ -414,47 +456,5 @@ class Navigation
|
||||
throw new FireflyException('updateStartDate cannot handle $range ' . $range);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param $repeatFreq
|
||||
* @param int $subtract
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function subtractPeriod(Carbon $theDate, $repeatFreq, $subtract = 1)
|
||||
{
|
||||
$date = clone $theDate;
|
||||
|
||||
$functionMap = [
|
||||
'daily' => 'subDays',
|
||||
'week' => 'subWeeks',
|
||||
'weekly' => 'subWeeks',
|
||||
'month' => 'subMonths',
|
||||
'monthly' => 'subMonths',
|
||||
'year' => 'subYears',
|
||||
'yearly' => 'subYears',
|
||||
];
|
||||
$modifierMap = [
|
||||
'quarter' => 3,
|
||||
'quarterly' => 3,
|
||||
'half-year' => 6,
|
||||
];
|
||||
if (isset($functionMap[$repeatFreq])) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$date->$function($subtract);
|
||||
|
||||
return $date;
|
||||
}
|
||||
if (isset($modifierMap[$repeatFreq])) {
|
||||
$subtract = $subtract * $modifierMap[$repeatFreq];
|
||||
$date->subMonths($subtract);
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
throw new FireflyException('Cannot do subtractPeriod for $repeat_freq ' . $repeatFreq);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class Preferences
|
||||
* @param $name
|
||||
* @param null $default
|
||||
*
|
||||
* @return null|\Preference
|
||||
* @return null|Preference
|
||||
*/
|
||||
public function get($name, $default = null)
|
||||
{
|
||||
@@ -37,7 +37,7 @@ class Preferences
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @return \Preference
|
||||
* @return Preference
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
@@ -55,4 +55,4 @@ class Preferences
|
||||
return $pref;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,8 +112,8 @@ class Search implements SearchInterface
|
||||
)->get();
|
||||
|
||||
// encrypted
|
||||
$all = Auth::user()->transactionjournals()->withRelevantData()->where('encrypted', 1)->get();
|
||||
$set = $all->filter(
|
||||
$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);
|
||||
|
||||
@@ -9,7 +9,8 @@ use Illuminate\Support\Collection;
|
||||
*
|
||||
* @package FireflyIII\Support\Search
|
||||
*/
|
||||
interface SearchInterface {
|
||||
interface SearchInterface
|
||||
{
|
||||
/**
|
||||
* @param array $words
|
||||
*
|
||||
@@ -45,4 +46,4 @@ interface SearchInterface {
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchTransactions(array $words);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,11 @@ class Steam
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $date
|
||||
* @param bool $ignoreVirtualBalance
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function balance(Account $account, Carbon $date = null)
|
||||
public function balance(Account $account, Carbon $date = null, $ignoreVirtualBalance = false)
|
||||
{
|
||||
$date = is_null($date) ? Carbon::now() : $date;
|
||||
|
||||
@@ -47,6 +48,9 @@ class Steam
|
||||
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
|
||||
)->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount')
|
||||
);
|
||||
if (!$ignoreVirtualBalance) {
|
||||
$balance += floatval($account->virtual_balance);
|
||||
}
|
||||
|
||||
return $balance;
|
||||
}
|
||||
@@ -100,11 +104,13 @@ class Steam
|
||||
if (isset($array[$id])) {
|
||||
$array[$id]['amount'] += floatval($entry->amount);
|
||||
$array[$id]['spent'] += floatval($entry->spent);
|
||||
$array[$id]['encrypted'] = intval($entry->encrypted);
|
||||
} else {
|
||||
$array[$id] = [
|
||||
'amount' => floatval($entry->amount),
|
||||
'spent' => floatval($entry->spent),
|
||||
'name' => $entry->name
|
||||
'amount' => floatval($entry->amount),
|
||||
'spent' => floatval($entry->spent),
|
||||
'encrypted' => intval($entry->encrypted),
|
||||
'name' => $entry->name
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -198,4 +204,4 @@ class Steam
|
||||
return $array;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,14 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
return $this->hasManyThrough('FireflyIII\Models\PiggyBank', 'FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||
*/
|
||||
public function transactions()
|
||||
{
|
||||
return $this->hasManyThrough('FireflyIII\Models\Transaction', 'FireflyIII\Models\TransactionJournal');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
|
||||
@@ -5,10 +5,13 @@ namespace FireflyIII\Validation;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use Crypt;
|
||||
use DB;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Input;
|
||||
use Log;
|
||||
use Navigation;
|
||||
|
||||
/**
|
||||
@@ -28,6 +31,7 @@ class FireflyValidator extends Validator
|
||||
*/
|
||||
public function validateBelongsToUser($attribute, $value, $parameters)
|
||||
{
|
||||
|
||||
$count = DB::table($parameters[0])->where('user_id', Auth::user()->id)->where('id', $value)->count();
|
||||
if ($count == 1) {
|
||||
return true;
|
||||
@@ -79,44 +83,62 @@ class FireflyValidator extends Validator
|
||||
*/
|
||||
public function validateUniqueAccountForUser($attribute, $value, $parameters)
|
||||
{
|
||||
// get account type from data, we must have this:
|
||||
$validTypes = array_keys(Config::get('firefly.subTitlesByIdentifier'));
|
||||
$type = null;
|
||||
|
||||
|
||||
$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();
|
||||
/**
|
||||
* Switch on different cases on which this method can respond:
|
||||
*/
|
||||
$hasWhat = isset($this->data['what']);
|
||||
$hasAccountTypeId = isset($this->data['account_type_id']) && isset($this->data['name']);
|
||||
$hasAccountId = isset($this->data['id']);
|
||||
$ignoreId = 0;
|
||||
|
||||
|
||||
if ($hasWhat) {
|
||||
$search = Config::get('firefly.accountTypeByIdentifier.' . $this->data['what']);
|
||||
$type = AccountType::whereType($search)->first();
|
||||
// this field can be used to find the exact type, and continue.
|
||||
}
|
||||
|
||||
if (is_null($dbType)) {
|
||||
if ($hasAccountTypeId) {
|
||||
$type = AccountType::find($this->data['account_type_id']);
|
||||
}
|
||||
|
||||
if ($hasAccountId) {
|
||||
/** @var Account $account */
|
||||
$account = Account::find($this->data['id']);
|
||||
$ignoreId = intval($this->data['id']);
|
||||
$type = AccountType::find($account->account_type_id);
|
||||
unset($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to decrypt data just in case:
|
||||
*/
|
||||
try {
|
||||
$value = Crypt::decrypt($value);
|
||||
} catch (DecryptException $e) {
|
||||
}
|
||||
|
||||
|
||||
if (is_null($type)) {
|
||||
Log::error('Could not determine type of account to validate.');
|
||||
|
||||
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;
|
||||
// get all accounts with this type, and find the name.
|
||||
$userId = Auth::check() ? Auth::user()->id : 0;
|
||||
$set = Account::where('account_type_id', $type->id)->where('id', '!=', $ignoreId)->where('user_id', $userId)->get();
|
||||
/** @var Account $entry */
|
||||
foreach ($set as $entry) {
|
||||
if ($entry->name == $value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@@ -143,6 +165,46 @@ class FireflyValidator extends Validator
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an object and its unicity. Checks for encryption / encrypted values as well.
|
||||
*
|
||||
* parameter 0: the table
|
||||
* parameter 1: the field
|
||||
* parameter 2: the encrypted / not encrypted boolean. Defaults to "encrypted".
|
||||
* parameter 3: an id to ignore (when editing)
|
||||
*
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
* @param $parameters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateUniqueObjectForUser($attribute, $value, $parameters)
|
||||
{
|
||||
$table = $parameters[0];
|
||||
$field = $parameters[1];
|
||||
$encrypted = isset($parameters[2]) ? $parameters[2] : 'encrypted';
|
||||
$exclude = isset($parameters[3]) ? $parameters[3] : null;
|
||||
|
||||
$query = DB::table($table)->where('user_id', Auth::user()->id);
|
||||
|
||||
if (!is_null($exclude)) {
|
||||
$query->where('id', '!=', $exclude);
|
||||
}
|
||||
|
||||
|
||||
$set = $query->get();
|
||||
foreach ($set as $entry) {
|
||||
$isEncrypted = intval($entry->$encrypted) == 1 ? true : false;
|
||||
$checkValue = $isEncrypted ? Crypt::decrypt($entry->$field) : $entry->$field;
|
||||
if ($checkValue == $value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
@@ -152,18 +214,24 @@ class FireflyValidator extends Validator
|
||||
*/
|
||||
public function validateUniquePiggyBankForUser($attribute, $value, $parameters)
|
||||
{
|
||||
$query = DB::table($parameters[0])->where('piggy_banks.'.$parameters[1], $value);
|
||||
$exclude = isset($parameters[0]) ? $parameters[0] : null;
|
||||
$query = DB::table('piggy_banks');
|
||||
$query->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id');
|
||||
$query->where('accounts.user_id', Auth::user()->id);
|
||||
if (isset($paramers[2])) {
|
||||
$query->where('piggy_banks.id', '!=', $parameters[2]);
|
||||
if (!is_null($exclude)) {
|
||||
$query->where('piggy_banks.id', '!=', $exclude);
|
||||
}
|
||||
$count = $query->count();
|
||||
if ($count == 0) {
|
||||
return true;
|
||||
$set = $query->get(['piggy_banks.*']);
|
||||
|
||||
foreach($set as $entry) {
|
||||
$isEncrypted = intval($entry->encrypted) == 1 ? true : false;
|
||||
$checkValue = $isEncrypted ? Crypt::decrypt($entry->name) : $entry->name;
|
||||
if($checkValue == $value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,8 @@
|
||||
|
|
||||
*/
|
||||
|
||||
use FireflyIII\Validation\FireflyValidator;
|
||||
|
||||
$app = new Illuminate\Foundation\Application(
|
||||
realpath(__DIR__.'/../')
|
||||
realpath(__DIR__ . '/../')
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -29,18 +27,18 @@ $app = new Illuminate\Foundation\Application(
|
||||
*/
|
||||
|
||||
$app->singleton(
|
||||
'Illuminate\Contracts\Http\Kernel',
|
||||
'FireflyIII\Http\Kernel'
|
||||
'Illuminate\Contracts\Http\Kernel',
|
||||
'FireflyIII\Http\Kernel'
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
'Illuminate\Contracts\Console\Kernel',
|
||||
'FireflyIII\Console\Kernel'
|
||||
'Illuminate\Contracts\Console\Kernel',
|
||||
'FireflyIII\Console\Kernel'
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
'Illuminate\Contracts\Debug\ExceptionHandler',
|
||||
'FireflyIII\Exceptions\Handler'
|
||||
'Illuminate\Contracts\Debug\ExceptionHandler',
|
||||
'FireflyIII\Exceptions\Handler'
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
"require": {
|
||||
"laravel/framework": "5.0.*",
|
||||
"davejamesmiller/laravel-breadcrumbs": "~3.0",
|
||||
"grumpydictator/gchart": "dev-master",
|
||||
"watson/validating": "dev-master",
|
||||
"grumpydictator/gchart": "~1",
|
||||
"watson/validating": "~1.0",
|
||||
"doctrine/dbal": "~2.5",
|
||||
"illuminate/html": "~5.0",
|
||||
"league/commonmark": "0.7.*"
|
||||
@@ -33,7 +33,11 @@
|
||||
"barryvdh/laravel-ide-helper": "~2.0",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"phpspec/phpspec": "~2.1",
|
||||
"satooshi/php-coveralls": "0.6.1"
|
||||
"satooshi/php-coveralls": "0.6.1",
|
||||
"mockery/mockery": "0.9.*",
|
||||
"league/factory-muffin": "~2.1"
|
||||
|
||||
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
|
||||
483
composer.lock
generated
483
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "34e0c28c0f8f4c04b545b2cbb0f2f24b",
|
||||
"hash": "0d43c4c85607c5cdc901cde2d18b75d5",
|
||||
"packages": [
|
||||
{
|
||||
"name": "classpreloader/classpreloader",
|
||||
@@ -412,16 +412,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/common",
|
||||
"version": "v2.4.2",
|
||||
"version": "v2.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/common.git",
|
||||
"reference": "5db6ab40e4c531f14dad4ca96a394dfce5d4255b"
|
||||
"reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/common/zipball/5db6ab40e4c531f14dad4ca96a394dfce5d4255b",
|
||||
"reference": "5db6ab40e4c531f14dad4ca96a394dfce5d4255b",
|
||||
"url": "https://api.github.com/repos/doctrine/common/zipball/cd8daf2501e10c63dced7b8b9b905844316ae9d3",
|
||||
"reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -438,7 +438,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4.x-dev"
|
||||
"dev-master": "2.6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -451,17 +451,6 @@
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/",
|
||||
"role": "Creator"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com",
|
||||
"homepage": "http://www.instaclick.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
@@ -470,11 +459,17 @@
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "https://github.com/schmittjoh",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
"email": "schmittjoh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Common Library for Doctrine projects",
|
||||
@@ -486,7 +481,7 @@
|
||||
"persistence",
|
||||
"spl"
|
||||
],
|
||||
"time": "2014-05-21 19:28:51"
|
||||
"time": "2015-04-02 19:55:44"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
@@ -682,7 +677,7 @@
|
||||
},
|
||||
{
|
||||
"name": "grumpydictator/gchart",
|
||||
"version": "dev-master",
|
||||
"version": "1.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JC5/gchart.git",
|
||||
@@ -950,16 +945,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v5.0.22",
|
||||
"version": "v5.0.26",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "388289de68ba912746bd1adb20a8b1cd0f846ea1"
|
||||
"reference": "8e53c33e144f94032cc6ecbfee0be2a96ed63be0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/388289de68ba912746bd1adb20a8b1cd0f846ea1",
|
||||
"reference": "388289de68ba912746bd1adb20a8b1cd0f846ea1",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/8e53c33e144f94032cc6ecbfee0be2a96ed63be0",
|
||||
"reference": "8e53c33e144f94032cc6ecbfee0be2a96ed63be0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1072,7 +1067,7 @@
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2015-03-27 14:49:51"
|
||||
"time": "2015-04-03 02:58:05"
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
@@ -1135,16 +1130,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "51cd7cd7ee0defbaafc6ec0d3620110a5d71e11a"
|
||||
"reference": "3c2400a99ccc3be6884d40361890010449c6b447"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/51cd7cd7ee0defbaafc6ec0d3620110a5d71e11a",
|
||||
"reference": "51cd7cd7ee0defbaafc6ec0d3620110a5d71e11a",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3c2400a99ccc3be6884d40361890010449c6b447",
|
||||
"reference": "3c2400a99ccc3be6884d40361890010449c6b447",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1154,7 +1149,7 @@
|
||||
"ext-fileinfo": "*",
|
||||
"league/phpunit-coverage-listener": "~1.1",
|
||||
"mockery/mockery": "~0.9",
|
||||
"phpspec/phpspec": "~2.0.0",
|
||||
"phpspec/phpspec": "~2.0",
|
||||
"phpspec/prophecy-phpunit": "~1.0",
|
||||
"phpunit/phpunit": "~4.1",
|
||||
"predis/predis": "~1.0",
|
||||
@@ -1214,7 +1209,7 @@
|
||||
"sftp",
|
||||
"storage"
|
||||
],
|
||||
"time": "2015-03-10 11:04:14"
|
||||
"time": "2015-03-29 14:01:43"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
@@ -1588,17 +1583,17 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Console",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Console.git",
|
||||
"reference": "53f86497ccd01677e22435cfb7262599450a90d1"
|
||||
"reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/53f86497ccd01677e22435cfb7262599450a90d1",
|
||||
"reference": "53f86497ccd01677e22435cfb7262599450a90d1",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/5b91dc4ed5eb08553f57f6df04c4730a73992667",
|
||||
"reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1642,21 +1637,21 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-13 17:37:22"
|
||||
"time": "2015-03-30 15:54:10"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Debug",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Debug.git",
|
||||
"reference": "5c1570dea188ade0c6c5e874c2f0a6570587aa1c"
|
||||
"reference": "d49a46a20a8f0544aedac54466750ad787d3d3e3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Debug/zipball/5c1570dea188ade0c6c5e874c2f0a6570587aa1c",
|
||||
"reference": "5c1570dea188ade0c6c5e874c2f0a6570587aa1c",
|
||||
"url": "https://api.github.com/repos/symfony/Debug/zipball/d49a46a20a8f0544aedac54466750ad787d3d3e3",
|
||||
"reference": "d49a46a20a8f0544aedac54466750ad787d3d3e3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1703,11 +1698,11 @@
|
||||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-13 17:37:22"
|
||||
"time": "2015-03-22 16:55:57"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/EventDispatcher",
|
||||
"source": {
|
||||
"type": "git",
|
||||
@@ -1766,17 +1761,17 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Filesystem",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Filesystem.git",
|
||||
"reference": "fdc5f151bc2db066b51870d5bea3773d915ced0b"
|
||||
"reference": "4983964b3693e4f13449cb3800c64a9112c301b4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/fdc5f151bc2db066b51870d5bea3773d915ced0b",
|
||||
"reference": "fdc5f151bc2db066b51870d5bea3773d915ced0b",
|
||||
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/4983964b3693e4f13449cb3800c64a9112c301b4",
|
||||
"reference": "4983964b3693e4f13449cb3800c64a9112c301b4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1812,21 +1807,21 @@
|
||||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-12 10:28:44"
|
||||
"time": "2015-03-22 16:55:57"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Finder",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Finder.git",
|
||||
"reference": "bebc7479c566fa4f14b9bcef9e32e719eabec74e"
|
||||
"reference": "5dbe2e73a580618f5b4880fda93406eed25de251"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Finder/zipball/bebc7479c566fa4f14b9bcef9e32e719eabec74e",
|
||||
"reference": "bebc7479c566fa4f14b9bcef9e32e719eabec74e",
|
||||
"url": "https://api.github.com/repos/symfony/Finder/zipball/5dbe2e73a580618f5b4880fda93406eed25de251",
|
||||
"reference": "5dbe2e73a580618f5b4880fda93406eed25de251",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1862,21 +1857,21 @@
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-12 10:28:44"
|
||||
"time": "2015-03-30 15:54:10"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/HttpFoundation",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/HttpFoundation.git",
|
||||
"reference": "d527885e37b55ec0e3dc6f4b70566d0f9b2f2388"
|
||||
"reference": "8a6337233f08f7520de97f4ffd6f00e947d892f9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/d527885e37b55ec0e3dc6f4b70566d0f9b2f2388",
|
||||
"reference": "d527885e37b55ec0e3dc6f4b70566d0f9b2f2388",
|
||||
"url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/8a6337233f08f7520de97f4ffd6f00e947d892f9",
|
||||
"reference": "8a6337233f08f7520de97f4ffd6f00e947d892f9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1916,21 +1911,21 @@
|
||||
],
|
||||
"description": "Symfony HttpFoundation Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-13 17:37:22"
|
||||
"time": "2015-04-01 16:50:12"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/HttpKernel",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/HttpKernel.git",
|
||||
"reference": "6f7b2d3ba8bf02cf77edb399696e85ef24a888a4"
|
||||
"reference": "3829cacfe21eaf3f73604a62d79183d1f6e792c4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/6f7b2d3ba8bf02cf77edb399696e85ef24a888a4",
|
||||
"reference": "6f7b2d3ba8bf02cf77edb399696e85ef24a888a4",
|
||||
"url": "https://api.github.com/repos/symfony/HttpKernel/zipball/3829cacfe21eaf3f73604a62d79183d1f6e792c4",
|
||||
"reference": "3829cacfe21eaf3f73604a62d79183d1f6e792c4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1994,21 +1989,21 @@
|
||||
],
|
||||
"description": "Symfony HttpKernel Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-17 14:58:46"
|
||||
"time": "2015-04-01 16:55:26"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Process",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Process.git",
|
||||
"reference": "4d717f34f3d1d6ab30fbe79f7132960a27f4a0dc"
|
||||
"reference": "a8bebaec1a9dc6cde53e0250e32917579b0be552"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Process/zipball/4d717f34f3d1d6ab30fbe79f7132960a27f4a0dc",
|
||||
"reference": "4d717f34f3d1d6ab30fbe79f7132960a27f4a0dc",
|
||||
"url": "https://api.github.com/repos/symfony/Process/zipball/a8bebaec1a9dc6cde53e0250e32917579b0be552",
|
||||
"reference": "a8bebaec1a9dc6cde53e0250e32917579b0be552",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2044,21 +2039,21 @@
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-12 10:28:44"
|
||||
"time": "2015-03-30 15:54:10"
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Routing",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Routing.git",
|
||||
"reference": "a7f3eb540e5c553c3c95993c6fc2e7edb2f3b9d2"
|
||||
"reference": "4e173a645b63ff60a124f3741b4f15feebd908fa"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Routing/zipball/a7f3eb540e5c553c3c95993c6fc2e7edb2f3b9d2",
|
||||
"reference": "a7f3eb540e5c553c3c95993c6fc2e7edb2f3b9d2",
|
||||
"url": "https://api.github.com/repos/symfony/Routing/zipball/4e173a645b63ff60a124f3741b4f15feebd908fa",
|
||||
"reference": "4e173a645b63ff60a124f3741b4f15feebd908fa",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2113,21 +2108,21 @@
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"time": "2015-03-13 17:37:22"
|
||||
"time": "2015-03-30 15:54:10"
|
||||
},
|
||||
{
|
||||
"name": "symfony/security-core",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Security/Core",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/security-core.git",
|
||||
"reference": "889290a5c00d3f174cc73ce13a11a0a6406939e9"
|
||||
"reference": "d25c17db741f58c0f615e52006a47f6fb23cd9b3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/security-core/zipball/889290a5c00d3f174cc73ce13a11a0a6406939e9",
|
||||
"reference": "889290a5c00d3f174cc73ce13a11a0a6406939e9",
|
||||
"url": "https://api.github.com/repos/symfony/security-core/zipball/d25c17db741f58c0f615e52006a47f6fb23cd9b3",
|
||||
"reference": "d25c17db741f58c0f615e52006a47f6fb23cd9b3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2177,21 +2172,21 @@
|
||||
],
|
||||
"description": "Symfony Security Component - Core Library",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-13 17:37:22"
|
||||
"time": "2015-03-30 15:54:10"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Translation",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Translation.git",
|
||||
"reference": "043db5f1eef9598d1bc1d75b93304984c003d7d9"
|
||||
"reference": "bd939f05cdaca128f4ddbae1b447d6f0203b60af"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Translation/zipball/043db5f1eef9598d1bc1d75b93304984c003d7d9",
|
||||
"reference": "043db5f1eef9598d1bc1d75b93304984c003d7d9",
|
||||
"url": "https://api.github.com/repos/symfony/Translation/zipball/bd939f05cdaca128f4ddbae1b447d6f0203b60af",
|
||||
"reference": "bd939f05cdaca128f4ddbae1b447d6f0203b60af",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2236,21 +2231,21 @@
|
||||
],
|
||||
"description": "Symfony Translation Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-14 11:42:25"
|
||||
"time": "2015-03-30 15:54:10"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/VarDumper",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "61ee6c848fd2c623e13f59df48833f8b8bad7fda"
|
||||
"reference": "aafae00236e147568832de3c65ccb94cfc836278"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/61ee6c848fd2c623e13f59df48833f8b8bad7fda",
|
||||
"reference": "61ee6c848fd2c623e13f59df48833f8b8bad7fda",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/aafae00236e147568832de3c65ccb94cfc836278",
|
||||
"reference": "aafae00236e147568832de3c65ccb94cfc836278",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2296,7 +2291,7 @@
|
||||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"time": "2015-03-06 16:45:31"
|
||||
"time": "2015-03-31 08:12:29"
|
||||
},
|
||||
{
|
||||
"name": "vlucas/phpdotenv",
|
||||
@@ -2351,7 +2346,7 @@
|
||||
},
|
||||
{
|
||||
"name": "watson/validating",
|
||||
"version": "dev-master",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dwightwatson/validating.git",
|
||||
@@ -2577,6 +2572,54 @@
|
||||
],
|
||||
"time": "2014-10-13 12:58:55"
|
||||
},
|
||||
{
|
||||
"name": "fzaninotto/faker",
|
||||
"version": "v1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fzaninotto/Faker.git",
|
||||
"reference": "010c7efedd88bf31141a02719f51fb44c732d5a0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fzaninotto/Faker/zipball/010c7efedd88bf31141a02719f51fb44c732d5a0",
|
||||
"reference": "010c7efedd88bf31141a02719f51fb44c732d5a0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"squizlabs/php_codesniffer": "~1.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": []
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Faker": "src/",
|
||||
"Faker\\PHPUnit": "test/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "François Zaninotto"
|
||||
}
|
||||
],
|
||||
"description": "Faker is a PHP library that generates fake data for you.",
|
||||
"keywords": [
|
||||
"data",
|
||||
"faker",
|
||||
"fixtures"
|
||||
],
|
||||
"time": "2014-06-04 14:43:02"
|
||||
},
|
||||
{
|
||||
"name": "guzzle/guzzle",
|
||||
"version": "v3.9.3",
|
||||
@@ -2672,6 +2715,112 @@
|
||||
],
|
||||
"time": "2015-03-18 18:23:50"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest/hamcrest-php",
|
||||
"version": "v1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hamcrest/hamcrest-php.git",
|
||||
"reference": "ac50c470531243944f977b8de75be0b684a9cb51"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/ac50c470531243944f977b8de75be0b684a9cb51",
|
||||
"reference": "ac50c470531243944f977b8de75be0b684a9cb51",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"replace": {
|
||||
"cordoval/hamcrest-php": "*",
|
||||
"davedevelopment/hamcrest-php": "*",
|
||||
"kodova/hamcrest-php": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/php-file-iterator": "1.3.3",
|
||||
"satooshi/php-coveralls": "dev-master"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"hamcrest"
|
||||
],
|
||||
"files": [
|
||||
"hamcrest/Hamcrest.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD"
|
||||
],
|
||||
"description": "This is the PHP port of Hamcrest Matchers",
|
||||
"keywords": [
|
||||
"test"
|
||||
],
|
||||
"time": "2015-01-20 19:34:09"
|
||||
},
|
||||
{
|
||||
"name": "league/factory-muffin",
|
||||
"version": "v2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/factory-muffin.git",
|
||||
"reference": "91f0adcdac6b5f7bf2277ac2c90f94352afe65de"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/factory-muffin/zipball/91f0adcdac6b5f7bf2277ac2c90f94352afe65de",
|
||||
"reference": "91f0adcdac6b5f7bf2277ac2c90f94352afe65de",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"fzaninotto/faker": "1.4.*",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"replace": {
|
||||
"zizaco/factory-muff": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/database": "~4.1",
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/database": "Factory Muffin works well with eloquent models."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\FactoryMuffin\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "graham@mineuk.com"
|
||||
},
|
||||
{
|
||||
"name": "Zizaco Zizuini",
|
||||
"email": "zizaco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Scott Robertson",
|
||||
"email": "scottymeuk@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "The goal of this package is to enable the rapid creation of objects for the purpose of testing.",
|
||||
"homepage": "http://factory-muffin.thephpleague.com/",
|
||||
"keywords": [
|
||||
"factory",
|
||||
"laravel",
|
||||
"testing"
|
||||
],
|
||||
"time": "2014-09-18 18:29:06"
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
"version": "v1.10.4",
|
||||
@@ -2728,6 +2877,71 @@
|
||||
],
|
||||
"time": "2015-02-05 07:51:20"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
"version": "0.9.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/padraic/mockery.git",
|
||||
"reference": "70bba85e4aabc9449626651f48b9018ede04f86b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/padraic/mockery/zipball/70bba85e4aabc9449626651f48b9018ede04f86b",
|
||||
"reference": "70bba85e4aabc9449626651f48b9018ede04f86b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"hamcrest/hamcrest-php": "~1.1",
|
||||
"lib-pcre": ">=7.0",
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.9.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Mockery": "library/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Pádraic Brady",
|
||||
"email": "padraic.brady@gmail.com",
|
||||
"homepage": "http://blog.astrumfutura.com"
|
||||
},
|
||||
{
|
||||
"name": "Dave Marshall",
|
||||
"email": "dave.marshall@atstsolutions.co.uk",
|
||||
"homepage": "http://davedevelopment.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.",
|
||||
"homepage": "http://github.com/padraic/mockery",
|
||||
"keywords": [
|
||||
"BDD",
|
||||
"TDD",
|
||||
"library",
|
||||
"mock",
|
||||
"mock objects",
|
||||
"mockery",
|
||||
"stub",
|
||||
"test",
|
||||
"test double",
|
||||
"testing"
|
||||
],
|
||||
"time": "2015-04-02 19:54:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
"version": "2.0.4",
|
||||
@@ -2889,21 +3103,22 @@
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.3.1",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9"
|
||||
"reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9",
|
||||
"reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5",
|
||||
"reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "~1.0,>=1.0.2",
|
||||
"phpdocumentor/reflection-docblock": "~2.0"
|
||||
"doctrine/instantiator": "^1.0.2",
|
||||
"phpdocumentor/reflection-docblock": "~2.0",
|
||||
"sebastian/comparator": "~1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "~2.0"
|
||||
@@ -2911,7 +3126,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2.x-dev"
|
||||
"dev-master": "1.4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2935,7 +3150,7 @@
|
||||
}
|
||||
],
|
||||
"description": "Highly opinionated mocking framework for PHP 5.3+",
|
||||
"homepage": "http://phpspec.org",
|
||||
"homepage": "https://github.com/phpspec/prophecy",
|
||||
"keywords": [
|
||||
"Double",
|
||||
"Dummy",
|
||||
@@ -2944,7 +3159,7 @@
|
||||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2014-11-17 16:23:49"
|
||||
"time": "2015-03-27 19:31:25"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@@ -3192,16 +3407,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "4.5.0",
|
||||
"version": "4.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5"
|
||||
"reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5",
|
||||
"reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d6429b0995b24a2d9dfe5587ee3a7071c1161af4",
|
||||
"reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3211,8 +3426,8 @@
|
||||
"ext-reflection": "*",
|
||||
"ext-spl": "*",
|
||||
"php": ">=5.3.3",
|
||||
"phpspec/prophecy": "~1.3.1",
|
||||
"phpunit/php-code-coverage": "~2.0",
|
||||
"phpspec/prophecy": "~1.3,>=1.3.1",
|
||||
"phpunit/php-code-coverage": "~2.0,>=2.0.11",
|
||||
"phpunit/php-file-iterator": "~1.3.2",
|
||||
"phpunit/php-text-template": "~1.2",
|
||||
"phpunit/php-timer": "~1.0.2",
|
||||
@@ -3260,29 +3475,29 @@
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-02-05 15:51:19"
|
||||
"time": "2015-03-29 09:24:05"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
"version": "2.3.0",
|
||||
"version": "2.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
||||
"reference": "c63d2367247365f688544f0d500af90a11a44c65"
|
||||
"reference": "74ffb87f527f24616f72460e54b595f508dccb5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65",
|
||||
"reference": "c63d2367247365f688544f0d500af90a11a44c65",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/74ffb87f527f24616f72460e54b595f508dccb5c",
|
||||
"reference": "74ffb87f527f24616f72460e54b595f508dccb5c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "~1.0,>=1.0.1",
|
||||
"doctrine/instantiator": "~1.0,>=1.0.2",
|
||||
"php": ">=5.3.3",
|
||||
"phpunit/php-text-template": "~1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.3"
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-soap": "*"
|
||||
@@ -3315,7 +3530,7 @@
|
||||
"mock",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2014-10-03 05:12:11"
|
||||
"time": "2015-04-02 05:36:41"
|
||||
},
|
||||
{
|
||||
"name": "satooshi/php-coveralls",
|
||||
@@ -3758,17 +3973,17 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/class-loader",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/ClassLoader",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/ClassLoader.git",
|
||||
"reference": "56bf6fe551ca013471541d866f73a6cc70ece9c5"
|
||||
"reference": "861765b3e5f32979de5bd19ad2577cbb830a29d5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/ClassLoader/zipball/56bf6fe551ca013471541d866f73a6cc70ece9c5",
|
||||
"reference": "56bf6fe551ca013471541d866f73a6cc70ece9c5",
|
||||
"url": "https://api.github.com/repos/symfony/ClassLoader/zipball/861765b3e5f32979de5bd19ad2577cbb830a29d5",
|
||||
"reference": "861765b3e5f32979de5bd19ad2577cbb830a29d5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3805,21 +4020,21 @@
|
||||
],
|
||||
"description": "Symfony ClassLoader Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-13 17:37:22"
|
||||
"time": "2015-03-27 10:19:51"
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Config",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Config.git",
|
||||
"reference": "7a47189c7667ca69bcaafd19ef8a8941db449a2c"
|
||||
"reference": "d91be01336605db8da21b79bc771e46a7276d1bc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Config/zipball/7a47189c7667ca69bcaafd19ef8a8941db449a2c",
|
||||
"reference": "7a47189c7667ca69bcaafd19ef8a8941db449a2c",
|
||||
"url": "https://api.github.com/repos/symfony/Config/zipball/d91be01336605db8da21b79bc771e46a7276d1bc",
|
||||
"reference": "d91be01336605db8da21b79bc771e46a7276d1bc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3856,21 +4071,21 @@
|
||||
],
|
||||
"description": "Symfony Config Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-12 10:28:44"
|
||||
"time": "2015-03-30 15:54:10"
|
||||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Stopwatch",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Stopwatch.git",
|
||||
"reference": "ba4e774f71e2ce3e3f65cabac4031b9029972af5"
|
||||
"reference": "5f196e84b5640424a166d2ce9cca161ce1e9d912"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/ba4e774f71e2ce3e3f65cabac4031b9029972af5",
|
||||
"reference": "ba4e774f71e2ce3e3f65cabac4031b9029972af5",
|
||||
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/5f196e84b5640424a166d2ce9cca161ce1e9d912",
|
||||
"reference": "5f196e84b5640424a166d2ce9cca161ce1e9d912",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3906,21 +4121,21 @@
|
||||
],
|
||||
"description": "Symfony Stopwatch Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-02-24 11:52:21"
|
||||
"time": "2015-03-22 16:55:57"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.6.5",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Yaml",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Yaml.git",
|
||||
"reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d"
|
||||
"reference": "174f009ed36379a801109955fc5a71a49fe62dd4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/0cd8e72071e46e15fc072270ae39ea1b66b10a9d",
|
||||
"reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/174f009ed36379a801109955fc5a71a49fe62dd4",
|
||||
"reference": "174f009ed36379a801109955fc5a71a49fe62dd4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3956,14 +4171,12 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-12 10:28:44"
|
||||
"time": "2015-03-30 15:54:10"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"grumpydictator/gchart": 20,
|
||||
"watson/validating": 20,
|
||||
"barryvdh/laravel-debugbar": 0
|
||||
},
|
||||
"prefer-stable": false,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user