diff --git a/app/Helpers/Reminders/ReminderHelper.php b/app/Helpers/Reminders/ReminderHelper.php index 53484378ea..cdf0478ada 100644 --- a/app/Helpers/Reminders/ReminderHelper.php +++ b/app/Helpers/Reminders/ReminderHelper.php @@ -63,6 +63,28 @@ class ReminderHelper implements ReminderHelperInterface } } + /** + * Create all reminders for a piggy bank for a given date. + * + * @param PiggyBank $piggyBank + * + * @return mixed + */ + public function createReminders(PiggyBank $piggyBank, Carbon $date) + { + $ranges = $this->getReminderRanges($piggyBank); + + foreach ($ranges as $range) { + if ($date < $range['end'] && $date > $range['start']) { + // create a reminder here! + $this->createReminder($piggyBank, $range['start'], $range['end']); + // stop looping, we're done. + break; + } + + } + } + /** * This routine will return an array consisting of two dates which indicate the start * and end date for each reminder that this piggy bank will have, if the piggy bank has diff --git a/app/Helpers/Reminders/ReminderHelperInterface.php b/app/Helpers/Reminders/ReminderHelperInterface.php index c3db2dd1d1..18c65b2e47 100644 --- a/app/Helpers/Reminders/ReminderHelperInterface.php +++ b/app/Helpers/Reminders/ReminderHelperInterface.php @@ -4,6 +4,7 @@ namespace FireflyIII\Helpers\Reminders; use Carbon\Carbon; use FireflyIII\Models\PiggyBank; +use FireflyIII\Models\PiggyBankRepetition; use FireflyIII\Models\Reminder; /** @@ -49,4 +50,13 @@ interface ReminderHelperInterface * @return Reminder */ public function createReminder(PiggyBank $piggyBank, Carbon $start, Carbon $end); + + /** + * Create all reminders for a piggy bank for a given date. + * + * @param PiggyBank $piggyBank + * + * @return mixed + */ + public function createReminders(PiggyBank $piggyBank, Carbon $date); } diff --git a/app/Http/Controllers/JsonController.php b/app/Http/Controllers/JsonController.php index c3d198abff..8c4f64e97a 100644 --- a/app/Http/Controllers/JsonController.php +++ b/app/Http/Controllers/JsonController.php @@ -43,14 +43,9 @@ class JsonController extends Controller /** @var Bill $bill */ foreach ($bills as $bill) { - $ranges = $repository->getRanges($bill, $start, $end); - - foreach ($ranges as $range) { - // paid a bill in this range? - $amount += $repository->getJournalsInRange($bill, $range['start'], $range['end'])->sum('amount'); - } + $amount += $repository->billPaymentsInRange($bill, $start, $end); } - unset($ranges, $bill, $range, $bills); + unset($bill, $bills); /** * Find credit card accounts and possibly unpaid credit card bills. diff --git a/app/Http/Middleware/PiggyBanks.php b/app/Http/Middleware/PiggyBanks.php index 190aa00e32..eff3e9aea7 100644 --- a/app/Http/Middleware/PiggyBanks.php +++ b/app/Http/Middleware/PiggyBanks.php @@ -52,16 +52,15 @@ class PiggyBanks ->leftJoin('piggy_bank_repetitions', 'piggy_banks.id', '=', 'piggy_bank_repetitions.piggy_bank_id') ->whereNull('piggy_bank_repetitions.id') ->get(['piggy_banks.id', 'piggy_banks.startdate', 'piggy_banks.targetdate']); - if ($set->count() > 0) { - /** @var PiggyBank $partialPiggy */ - foreach ($set as $partialPiggy) { - $repetition = new PiggyBankRepetition; - $repetition->piggyBank()->associate($partialPiggy); - $repetition->startdate = is_null($partialPiggy->startdate) ? null : $partialPiggy->startdate; - $repetition->targetdate = is_null($partialPiggy->targetdate) ? null : $partialPiggy->targetdate; - $repetition->currentamount = 0; - $repetition->save(); - } + + /** @var PiggyBank $partialPiggy */ + foreach ($set as $partialPiggy) { + $repetition = new PiggyBankRepetition; + $repetition->piggyBank()->associate($partialPiggy); + $repetition->startdate = $partialPiggy->startdate; + $repetition->targetdate = $partialPiggy->targetdate; + $repetition->currentamount = 0; + $repetition->save(); } unset($partialPiggy, $set, $repetition); } diff --git a/app/Http/Middleware/Reminders.php b/app/Http/Middleware/Reminders.php index 55c555aec0..ffd9d7d197 100644 --- a/app/Http/Middleware/Reminders.php +++ b/app/Http/Middleware/Reminders.php @@ -49,32 +49,18 @@ class Reminders if ($this->auth->check() && !$request->isXmlHttpRequest()) { // do reminders stuff. $piggyBanks = $this->auth->user()->piggyBanks()->where('remind_me', 1)->get(); - $today = new Carbon; /** @var \FireflyIII\Helpers\Reminders\ReminderHelperInterface $helper */ $helper = App::make('FireflyIII\Helpers\Reminders\ReminderHelperInterface'); /** @var PiggyBank $piggyBank */ foreach ($piggyBanks as $piggyBank) { - $ranges = $helper->getReminderRanges($piggyBank); - - foreach ($ranges as $range) { - if ($today < $range['end'] && $today > $range['start']) { - // create a reminder here! - $helper->createReminder($piggyBank, $range['start'], $range['end']); - // stop looping, we're done. - break; - } - - } + $helper->createReminders($piggyBank, new Carbon); } // delete invalid reminders - $set = $this->auth->user()->reminders()->leftJoin('piggy_banks', 'piggy_banks.id', '=', 'remindersable_id')->whereNull('piggy_banks.id')->get( - ['reminders.id'] - ); - foreach ($set as $reminder) { - $reminder->delete(); - } - + Reminder::whereUserId($this->auth->user()->id) + ->leftJoin('piggy_banks', 'piggy_banks.id', '=', 'remindersable_id') + ->whereNull('piggy_banks.id') + ->delete(); // get and list active reminders: $reminders = $this->auth->user()->reminders()->today()->get(); diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index 0c3419f7b9..8445cda471 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -22,6 +22,27 @@ use Navigation; */ class BillRepository implements BillRepositoryInterface { + /** + * Returns the sum of all payments connected to this bill between the dates. + * + * @param Bill $bill + * @param Carbon $start + * @param Carbon $end + * + * @return float + */ + public function billPaymentsInRange(Bill $bill, Carbon $start, Carbon $end) + { + $amount = 0; + $journals = $bill->transactionjournals()->before($end)->after($start)->get(); + /** @var TransactionJournal $journal */ + foreach ($journals as $journal) { + $amount += $journal->amount; + } + + return $amount; + } + /** * Create a fake bill to help the chart controller. * diff --git a/app/Repositories/Bill/BillRepositoryInterface.php b/app/Repositories/Bill/BillRepositoryInterface.php index a6d5c5ea1e..4f2b509786 100644 --- a/app/Repositories/Bill/BillRepositoryInterface.php +++ b/app/Repositories/Bill/BillRepositoryInterface.php @@ -15,6 +15,17 @@ use Illuminate\Support\Collection; interface BillRepositoryInterface { + /** + * Returns the sum of all payments connected to this bill between the dates. + * + * @param Bill $bill + * @param Carbon $start + * @param Carbon $end + * + * @return float + */ + public function billPaymentsInRange(Bill $bill, Carbon $start, Carbon $end); + /** * Create a fake bill to help the chart controller. * diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php index 3eea380e07..188853939b 100644 --- a/app/Repositories/Tag/TagRepository.php +++ b/app/Repositories/Tag/TagRepository.php @@ -33,89 +33,22 @@ class TagRepository implements TagRepositoryInterface return false; } - if ($tag->tagMode == 'nothing') { - // save it, no problem: - $journal->tags()->save($tag); - - return true; - } - - /* - * get some withdrawal types: - */ - /** @var TransactionType $withdrawal */ - $withdrawal = TransactionType::whereType('Withdrawal')->first(); - /** @var TransactionType $deposit */ - $deposit = TransactionType::whereType('Deposit')->first(); - /** @var TransactionType $transfer */ - $transfer = TransactionType::whereType('Transfer')->first(); - - $withdrawals = $tag->transactionjournals()->where('transaction_type_id', $withdrawal->id)->count(); - $transfers = $tag->transactionjournals()->where('transaction_type_id', $transfer->id)->count(); - $deposits = $tag->transactionjournals()->where('transaction_type_id', $deposit->id)->count(); - - if ($tag->tagMode == 'balancingAct') { - - // only if this is the only withdrawal. - if ($journal->transaction_type_id == $withdrawal->id && $withdrawals < 1) { + switch ($tag->tagMode) { + case 'nothing': $journal->tags()->save($tag); return true; - } - // and only if this is the only transfer - if ($journal->transaction_type_id == $transfer->id && $transfers < 1) { - $journal->tags()->save($tag); - - return true; - } - - // ignore expense - return false; - } - if ($tag->tagMode == 'advancePayment') { - - // advance payments cannot accept transfers: - if ($journal->transaction_type_id == $transfer->id) { - return false; - } - - // the first transaction to be attached to this - // tag is attached just like that: - if ($withdrawals < 1 && $deposits < 1) { - $journal->tags()->save($tag); - - return true; - } - - // if withdrawal and already has a withdrawal, return false: - if ($journal->transaction_type_id == $withdrawal->id && $withdrawals == 1) { - return false; - } - - // if already has transaction journals, must match ALL asset account id's: - if ($deposits > 0 || $withdrawals == 1) { - $match = true; - /** @var TransactionJournal $check */ - foreach ($tag->transactionjournals as $check) { - if ($check->assetAccount->id != $journal->assetAccount->id) { - $match = false; - } - } - if ($match) { - $journal->tags()->save($tag); - - return true; - } - - } - - return false; + break; + case 'balancingAct': + return $this->connectBalancingAct($journal, $tag); + break; + case 'advancePayment': + return $this->connectAdvancePayment($journal, $tag); + break; } - // @codeCoverageIgnoreStart return false; } - // @codeCoverageIgnoreEnd /** * @param Tag $tag @@ -144,6 +77,7 @@ class TagRepository implements TagRepositoryInterface return $tags; } + // @codeCoverageIgnoreEnd /** * @param array $data @@ -187,4 +121,106 @@ class TagRepository implements TagRepositoryInterface return $tag; } + + /** + * @param TransactionJournal $journal + * @param Tag $tag + * + * @return boolean + */ + protected function connectBalancingAct(TransactionJournal $journal, Tag $tag) + { + /** @var TransactionType $withdrawal */ + $withdrawal = TransactionType::whereType('Withdrawal')->first(); + $withdrawals = $tag->transactionjournals()->where('transaction_type_id', $withdrawal->id)->count(); + /** @var TransactionType $transfer */ + $transfer = TransactionType::whereType('Transfer')->first(); + $transfers = $tag->transactionjournals()->where('transaction_type_id', $transfer->id)->count(); + + + // only if this is the only withdrawal. + if ($journal->transaction_type_id == $withdrawal->id && $withdrawals < 1) { + $journal->tags()->save($tag); + + return true; + } + // and only if this is the only transfer + if ($journal->transaction_type_id == $transfer->id && $transfers < 1) { + $journal->tags()->save($tag); + + return true; + } + + // ignore expense + return false; + + } + + /** + * @param TransactionJournal $journal + * @param Tag $tag + * + * @return boolean + */ + protected function connectAdvancePayment(TransactionJournal $journal, Tag $tag) + { + /** @var TransactionType $transfer */ + $transfer = TransactionType::whereType('Transfer')->first(); + /** @var TransactionType $withdrawal */ + $withdrawal = TransactionType::whereType('Withdrawal')->first(); + /** @var TransactionType $deposit */ + $deposit = TransactionType::whereType('Deposit')->first(); + + $withdrawals = $tag->transactionjournals()->where('transaction_type_id', $withdrawal->id)->count(); + $deposits = $tag->transactionjournals()->where('transaction_type_id', $deposit->id)->count(); + + // advance payments cannot accept transfers: + if ($journal->transaction_type_id == $transfer->id) { + return false; + } + + // the first transaction to be attached to this + // tag is attached just like that: + if ($withdrawals < 1 && $deposits < 1) { + $journal->tags()->save($tag); + + return true; + } + + // if withdrawal and already has a withdrawal, return false: + if ($journal->transaction_type_id == $withdrawal->id && $withdrawals == 1) { + return false; + } + + // if already has transaction journals, must match ALL asset account id's: + if ($deposits > 0 || $withdrawals == 1) { + return $this->matchAll($journal, $tag); + } + + return false; + + } + + /** + * @param TransactionJournal $journal + * @param Tag $tag + * + * @return bool + */ + protected function matchAll(TransactionJournal $journal, Tag $tag) + { + $match = true; + /** @var TransactionJournal $check */ + foreach ($tag->transactionjournals as $check) { + if ($check->assetAccount->id != $journal->assetAccount->id) { + $match = false; + } + } + if ($match) { + $journal->tags()->save($tag); + + return true; + } + return false; + } } diff --git a/app/Support/Twig/General.php b/app/Support/Twig/General.php index d3f3a51cb6..c1bcf09e16 100644 --- a/app/Support/Twig/General.php +++ b/app/Support/Twig/General.php @@ -3,10 +3,12 @@ namespace FireflyIII\Support\Twig; use App; +use Carbon\Carbon; use Config; use FireflyIII\Models\Account; use FireflyIII\Models\Transaction; use Route; +use Session; use Twig_Extension; use Twig_SimpleFilter; use Twig_SimpleFunction; @@ -57,8 +59,9 @@ class General extends Twig_Extension if (is_null($account)) { return 'NULL'; } + $date = Session::get('end', Carbon::now()->endOfMonth()); - return App::make('steam')->balance($account); + return App::make('steam')->balance($account, $date); } );