Repeated expenses.

This commit is contained in:
James Cole
2015-02-27 11:02:08 +01:00
parent defad3d820
commit fc5c339e27
15 changed files with 877 additions and 34 deletions

View File

@@ -3,6 +3,9 @@
namespace FireflyIII\Repositories\PiggyBank;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankRepetition;
use Illuminate\Support\Collection;
use Navigation;
/**
* Class PiggyBankRepository
@@ -20,18 +23,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
public function store(array $data)
{
$piggyBank = PiggyBank::create(
[
'repeats' => $data['repeats'],
'name' => $data['name'],
'account_id' => $data['account_id'],
'targetamount' => $data['targetamount'],
'startdate' => $data['startdate'],
'targetdate' => $data['targetdate'],
'reminder' => $data['reminder'],
]
);
$piggyBank = PiggyBank::create($data);
return $piggyBank;
}
@@ -44,13 +36,94 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
*/
public function update(PiggyBank $piggyBank, array $data)
{
/**
'rep_length' => $request->get('rep_length'),
'rep_every' => intval($request->get('rep_every')),
'rep_times' => intval($request->get('rep_times')),
'remind_me' => intval($request->get('remind_me')) == 1 ? true : false ,
'reminder' => $request->get('reminder'),
*/
$piggyBank->name = $data['name'];
$piggyBank->account_id = intval($data['account_id']);
$piggyBank->targetamount = floatval($data['targetamount']);
$piggyBank->targetdate = $data['targetdate'];
$piggyBank->reminder = $data['reminder'];
$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'] : null;
$piggyBank->save();
return $piggyBank;
}
/**
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
*
* Based on the piggy bank, the reminder-setting and
* other variables this method tries to divide the piggy bank into equal parts. Each is
* accommodated by a reminder (if everything goes to plan).
*
* @param PiggyBankRepetition $repetition
*
* @return Collection
*/
public function calculateParts(PiggyBankRepetition $repetition)
{
/** @var PiggyBank $piggyBank */
$piggyBank = $repetition->piggyBank()->first();
$bars = new Collection;
$currentStart = clone $repetition->startdate;
if (is_null($piggyBank->reminder)) {
$entry = ['repetition' => $repetition, 'amountPerBar' => floatval($piggyBank->targetamount),
'currentAmount' => floatval($repetition->currentamount), 'cumulativeAmount' => floatval($piggyBank->targetamount),
'startDate' => clone $repetition->startdate, 'targetDate' => clone $repetition->targetdate];
$bars->push($this->createPiggyBankPart($entry));
return $bars;
}
while ($currentStart < $repetition->targetdate) {
$currentTarget = Navigation::endOfX($currentStart, $piggyBank->reminder, $repetition->targetdate);
$entry = ['repetition' => $repetition, 'amountPerBar' => null, 'currentAmount' => floatval($repetition->currentamount),
'cumulativeAmount' => null, 'startDate' => $currentStart, 'targetDate' => $currentTarget];
$bars->push($this->createPiggyBankPart($entry));
$currentStart = clone $currentTarget;
$currentStart->addDay();
}
$amountPerBar = floatval($piggyBank->targetamount) / $bars->count();
$cumulative = $amountPerBar;
/** @var PiggyBankPart $bar */
foreach ($bars as $index => $bar) {
$bar->setAmountPerBar($amountPerBar);
$bar->setCumulativeAmount($cumulative);
if ($bars->count() - 1 == $index) {
$bar->setCumulativeAmount($piggyBank->targetamount);
}
$cumulative += $amountPerBar;
}
return $bars;
}
/**
* @param array $data
*
* @return PiggyBankPart
*/
public function createPiggyBankPart(array $data)
{
$part = new PiggyBankPart;
$part->setRepetition($data['repetition']);
$part->setAmountPerBar($data['amountPerBar']);
$part->setCurrentamount($data['currentAmount']);
$part->setCumulativeAmount($data['cumulativeAmount']);
$part->setStartdate($data['startDate']);
$part->setTargetdate($data['targetDate']);
return $part;
}
}

View File

@@ -3,6 +3,8 @@
namespace FireflyIII\Repositories\PiggyBank;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankRepetition;
use Illuminate\Support\Collection;
/**
* Interface PiggyBankRepositoryInterface
@@ -26,4 +28,24 @@ interface PiggyBankRepositoryInterface {
* @return PiggyBank
*/
public function update(PiggyBank $piggyBank, array $data);
/**
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
*
* Based on the piggy bank, the reminder-setting and
* other variables this method tries to divide the piggy bank into equal parts. Each is
* accommodated by a reminder (if everything goes to plan).
*
* @param PiggyBankRepetition $repetition
*
* @return Collection
*/
public function calculateParts(PiggyBankRepetition $repetition);
/**
* @param array $data
*
* @return PiggyBankPart
*/
public function createPiggyBankPart(array $data);
}

View File

@@ -0,0 +1,181 @@
<?php
namespace FireflyIII\Repositories\PiggyBank;
use FireflyIII\Models\Reminder;
use FireflyIII\Models\PiggyBankRepetition;
use Carbon\Carbon;
/**
* Class PiggyBankPart
*
* @package FireflyIII\Collection
*/
class PiggyBankPart
{
/** @var float */
public $amountPerBar;
/** @var float */
public $cumulativeAmount;
/** @var float */
public $currentamount;
/** @var Reminder */
public $reminder;
/** @var PiggyBankRepetition */
public $repetition;
/** @var Carbon */
public $startdate;
/** @var Carbon */
public $targetdate;
/**
* @return Reminder
*/
public function getReminder()
{
if (is_null($this->reminder)) {
$this->reminder = $this->repetition->piggyBank->reminders()->where('startdate', $this->getStartdate()->format('Y-m-d'))->where(
'enddate', $this->getTargetdate()->format('Y-m-d')
)->first();
}
return $this->reminder;
}
/**
* @param Reminder $reminder
*/
public function setReminder($reminder)
{
$this->reminder = $reminder;
}
/**
* @return Carbon
*/
public function getStartdate()
{
return $this->startdate;
}
/**
* @param Carbon $startdate
*/
public function setStartdate($startdate)
{
$this->startdate = $startdate;
}
/**
* @return Carbon
*/
public function getTargetdate()
{
return $this->targetdate;
}
/**
* @param Carbon $targetdate
*/
public function setTargetdate($targetdate)
{
$this->targetdate = $targetdate;
}
/**
* @return PiggyBankRepetition
*/
public function getRepetition()
{
return $this->repetition;
}
/**
* @param PiggyBankRepetition $repetition
*/
public function setRepetition($repetition)
{
$this->repetition = $repetition;
}
/**
* @return bool
*/
public function hasReminder()
{
return !is_null($this->reminder);
}
/**
* @return float|int
*/
public function percentage()
{
if ($this->getCurrentamount() < $this->getCumulativeAmount()) {
$pct = 0;
// calculate halfway point?
if ($this->getCumulativeAmount() - $this->getCurrentamount() < $this->getAmountPerBar()) {
$left = $this->getCurrentamount() % $this->getAmountPerBar();
$pct = round($left / $this->getAmountPerBar() * 100);
}
return $pct;
} else {
return 100;
}
}
/**
* @return float
*/
public function getCurrentamount()
{
return $this->currentamount;
}
/**
* @param float $currentamount
*/
public function setCurrentamount($currentamount)
{
$this->currentamount = $currentamount;
}
/**
* @return float
*/
public function getCumulativeAmount()
{
return $this->cumulativeAmount;
}
/**
* @param float $cumulativeAmount
*/
public function setCumulativeAmount($cumulativeAmount)
{
$this->cumulativeAmount = $cumulativeAmount;
}
/**
* @return float
*/
public function getAmountPerBar()
{
return $this->amountPerBar;
}
/**
* @param float $amountPerBar
*/
public function setAmountPerBar($amountPerBar)
{
$this->amountPerBar = $amountPerBar;
}
}