firefly-iii/app/lib/FireflyIII/Database/PiggyBank/RepeatedExpense.php

308 lines
9.3 KiB
PHP
Raw Normal View History

<?php
2014-12-13 15:11:51 -06:00
namespace FireflyIII\Database\PiggyBank;
use Carbon\Carbon;
use FireflyIII\Collection\PiggyBankPart;
2014-12-13 15:11:51 -06:00
use FireflyIII\Database\CommonDatabaseCalls;
use FireflyIII\Database\CUD;
use FireflyIII\Database\SwitchUser;
use FireflyIII\Exception\NotImplementedException;
2014-12-20 08:00:53 -06:00
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag;
2014-12-06 05:12:55 -06:00
2014-12-13 14:59:02 -06:00
/**
* Class RepeatedExpense
*
* @package FireflyIII\Database
*/
2014-12-15 00:24:01 -06:00
class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggyBankInterface
{
use SwitchUser;
/**
*
*/
public function __construct()
{
$this->setUser(\Auth::user());
}
2014-11-24 03:12:34 -06:00
/**
* 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
2014-12-13 14:59:02 -06:00
*
2014-12-14 13:40:02 -06:00
* @return Collection
2014-11-24 03:12:34 -06:00
*/
public function calculateParts(\PiggyBankRepetition $repetition)
2014-11-24 03:12:34 -06:00
{
/** @var \PiggyBank $piggyBank */
$piggyBank = $repetition->piggyBank()->first();
2014-12-14 13:40:02 -06:00
$bars = new Collection;
$currentStart = clone $repetition->startdate;
2014-11-24 03:12:34 -06:00
if (is_null($piggyBank->reminder)) {
2014-12-14 13:40:02 -06:00
$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));
2014-11-24 03:12:34 -06:00
2014-12-14 13:40:02 -06:00
return $bars;
2014-11-24 03:12:34 -06:00
}
2014-11-24 10:01:37 -06:00
2014-12-14 13:40:02 -06:00
while ($currentStart < $repetition->targetdate) {
$currentTarget = \DateKit::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));
2014-11-24 11:06:21 -06:00
$currentStart = clone $currentTarget;
2014-12-14 13:40:02 -06:00
$currentStart->addDay();
2014-11-24 03:12:34 -06:00
}
2014-12-14 13:40:02 -06:00
$amountPerBar = floatval($piggyBank->targetamount) / $bars->count();
2014-11-24 11:06:21 -06:00
$cumulative = $amountPerBar;
/** @var PiggyBankPart $bar */
foreach ($bars as $index => $bar) {
2014-11-24 11:06:21 -06:00
$bar->setAmountPerBar($amountPerBar);
$bar->setCumulativeAmount($cumulative);
2014-12-14 13:40:02 -06:00
if ($bars->count() - 1 == $index) {
$bar->setCumulativeAmount($piggyBank->targetamount);
}
2014-11-24 11:06:21 -06:00
$cumulative += $amountPerBar;
2014-11-24 03:12:34 -06:00
}
2014-12-14 13:40:02 -06:00
return $bars;
}
2014-11-24 03:12:34 -06:00
2014-12-14 13:40:02 -06:00
/**
* @param array $data
*
* @return PiggyBankPart
2014-12-14 13:40:02 -06:00
*/
public function createPiggyBankPart(array $data)
{
$part = new PiggyBankPart;
2014-12-14 13:40:02 -06:00
$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;
2014-11-24 03:12:34 -06:00
}
/**
2014-12-20 08:00:53 -06:00
* @param Eloquent $model
*
* @return bool
2014-12-13 14:59:02 -06:00
* @throws NotImplementedException
*/
2014-12-20 08:00:53 -06:00
public function destroy(Eloquent $model)
{
// TODO: Implement destroy() method.
throw new NotImplementedException;
}
/**
* @param array $data
*
2014-12-06 05:12:55 -06:00
* @return \Eloquent
*/
public function store(array $data)
{
$data['rep_every'] = intval($data['rep_every']);
$data['reminder_skip'] = intval($data['reminder_skip']);
$data['order'] = intval($data['order']);
$data['remind_me'] = intval($data['remind_me']);
$data['account_id'] = intval($data['account_id']);
if ($data['remind_me'] == 0) {
$data['reminder'] = null;
}
$repeated = new \PiggyBank($data);
$repeated->save();
return $repeated;
}
/**
2014-12-20 08:00:53 -06:00
* @param Eloquent $model
* @param array $data
*
* @return bool
2014-12-13 14:59:02 -06:00
* @throws NotImplementedException
*/
2014-12-20 08:00:53 -06:00
public function update(Eloquent $model, array $data)
{
// TODO: Implement update() method.
throw new NotImplementedException;
}
/**
* Validates an array. Returns an array containing MessageBags
* errors/warnings/successes.
*
*
* ignored because this method will be gone soon.
*
* @param array $model
*
* @return array
*/
public function validate(array $model)
{
$warnings = new MessageBag;
$successes = new MessageBag;
$errors = new MessageBag;
/*
* Name validation:
*/
if (!isset($model['name'])) {
$errors->add('name', 'Name is mandatory');
}
if (isset($model['name']) && strlen($model['name']) == 0) {
$errors->add('name', 'Name is too short');
}
if (isset($model['name']) && strlen($model['name']) > 100) {
$errors->add('name', 'Name is too long');
}
if (intval($model['account_id']) == 0) {
$errors->add('account_id', 'Account is mandatory');
}
if ($model['targetdate'] == '' && isset($model['remind_me']) && intval($model['remind_me']) == 1) {
$errors->add('targetdate', 'Target date is mandatory when setting reminders.');
}
if ($model['targetdate'] != '') {
try {
new Carbon($model['targetdate']);
} catch (\Exception $e) {
$errors->add('targetdate', 'Invalid date.');
}
2014-11-24 03:12:34 -06:00
$diff = Carbon::now()->diff(new Carbon($model['targetdate']));
if ($diff->days > 365) {
$errors->add('targetdate', 'First target date should a a year or less from now.');
}
} else {
$errors->add('targetdate', 'Invalid target date.');
}
if (floatval($model['targetamount']) < 0.01) {
$errors->add('targetamount', 'Amount should be above 0.01.');
}
if (!in_array(ucfirst($model['reminder']), \Config::get('firefly.piggy_bank_periods'))) {
$errors->add('reminder', 'Invalid reminder period (' . $model['reminder'] . ')');
}
if (!in_array(ucfirst($model['rep_length']), \Config::get('firefly.piggy_bank_periods'))) {
$errors->add('rep_length', 'Invalid repeat period (' . $model['rep_length'] . ')');
}
// check period.
if (!$errors->has('reminder') && !$errors->has('targetdate') && isset($model['remind_me']) && intval($model['remind_me']) == 1) {
$today = new Carbon;
$target = new Carbon($model['targetdate']);
switch ($model['reminder']) {
case 'week':
$today->addWeek();
break;
case 'month':
$today->addMonth();
break;
case 'year':
$today->addYear();
break;
}
if ($today > $target) {
$errors->add('reminder', 'Target date is too close to today to set reminders.');
}
}
$validator = \Validator::make($model, \PiggyBank::$rules);
if ($validator->invalid()) {
$errors->merge($errors);
}
// add ok messages.
$list = ['name', 'account_id', 'rep_every', 'rep_times', 'rep_length', 'targetamount', 'targetdate', 'remind_me', 'reminder'];
foreach ($list as $entry) {
if (!$errors->has($entry) && !$warnings->has($entry)) {
$successes->add($entry, 'OK');
}
}
return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes];
}
/**
* Returns an object with id $id.
*
2014-12-19 14:18:42 -06:00
* @param int $objectId
*
2014-12-06 05:12:55 -06:00
* @return \Eloquent
2014-12-13 14:59:02 -06:00
* @throws NotImplementedException
*/
2014-12-19 14:18:42 -06:00
public function find($objectId)
{
// TODO: Implement find() method.
throw new NotImplementedException;
}
/**
* Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
*
* @param $what
*
* @return \AccountType|null
2014-12-13 14:59:02 -06:00
* @throws NotImplementedException
*/
public function findByWhat($what)
{
// TODO: Implement findByWhat() method.
throw new NotImplementedException;
}
/**
* Returns all objects.
*
* @return Collection
*/
public function get()
{
return $this->getUser()->piggyBanks()->where('repeats', 1)->get();
}
/**
* @param array $ids
*
* @return Collection
2014-12-13 14:59:02 -06:00
* @throws NotImplementedException
*/
public function getByIds(array $ids)
{
// TODO: Implement getByIds() method.
throw new NotImplementedException;
}
/**
* @param \Account $account
*
* @return float
2014-12-13 14:59:02 -06:00
* @throws NotImplementedException
*/
public function leftOnAccount(\Account $account)
{
// TODO: Implement leftOnAccount() method.
throw new NotImplementedException;
}
}