mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-15 08:35:00 +00:00
Can now create recurring transactions. #1469
This commit is contained in:
@@ -28,7 +28,6 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\RecurrenceFormRequest;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@@ -40,8 +39,6 @@ class CreateController extends Controller
|
||||
{
|
||||
/** @var BudgetRepositoryInterface */
|
||||
private $budgets;
|
||||
/** @var PiggyBankRepositoryInterface */
|
||||
private $piggyBanks;
|
||||
/** @var RecurringRepositoryInterface */
|
||||
private $recurring;
|
||||
|
||||
@@ -59,9 +56,8 @@ class CreateController extends Controller
|
||||
app('view')->share('title', trans('firefly.recurrences'));
|
||||
app('view')->share('subTitle', trans('firefly.create_new_recurrence'));
|
||||
|
||||
$this->recurring = app(RecurringRepositoryInterface::class);
|
||||
$this->budgets = app(BudgetRepositoryInterface::class);
|
||||
$this->piggyBanks = app(PiggyBankRepositoryInterface::class);
|
||||
$this->recurring = app(RecurringRepositoryInterface::class);
|
||||
$this->budgets = app(BudgetRepositoryInterface::class);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
@@ -75,14 +71,18 @@ class CreateController extends Controller
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
// todo refactor to expandedform method.
|
||||
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgets->getActiveBudgets());
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$piggyBanks = $this->piggyBanks->getPiggyBanksWithAmount();
|
||||
$piggies = app('expandedform')->makeSelectListWithEmpty($piggyBanks);
|
||||
$tomorrow = new Carbon;
|
||||
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgets->getActiveBudgets());
|
||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||
$tomorrow = new Carbon;
|
||||
$oldRepetitionType = $request->old('repetition_type');
|
||||
$tomorrow->addDay();
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (true !== session('recurring.create.fromStore')) {
|
||||
$this->rememberPreviousUri('recurring.create.uri');
|
||||
}
|
||||
$request->session()->forget('recurring.create.fromStore');
|
||||
|
||||
// types of repetitions:
|
||||
$typesOfRepetitions = [
|
||||
'forever' => trans('firefly.repeat_forever'),
|
||||
@@ -99,18 +99,33 @@ class CreateController extends Controller
|
||||
];
|
||||
$request->session()->flash('preFilled', $preFilled);
|
||||
|
||||
return view('recurring.create', compact('tomorrow', 'preFilled', 'piggies', 'typesOfRepetitions', 'defaultCurrency', 'budgets'));
|
||||
return view('recurring.create', compact('tomorrow', 'oldRepetitionType', 'preFilled', 'piggies', 'typesOfRepetitions', 'defaultCurrency', 'budgets'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RecurrenceFormRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws \FireflyIII\Exceptions\FireflyException
|
||||
*/
|
||||
public function store(RecurrenceFormRequest $request)
|
||||
{
|
||||
$data = $request->getAll();
|
||||
$this->recurring->store($data);
|
||||
var_dump($data);
|
||||
exit;
|
||||
$data = $request->getAll();
|
||||
$recurrence = $this->recurring->store($data);
|
||||
|
||||
$request->session()->flash('success', (string)trans('firefly.stored_new_recurrence', ['title' => $recurrence->title]));
|
||||
app('preferences')->mark();
|
||||
|
||||
if (1 === (int)$request->get('create_another')) {
|
||||
// set value so create routine will not overwrite URL:
|
||||
$request->session()->put('recurring.create.fromStore', true);
|
||||
|
||||
return redirect(route('recurring.create'))->withInput();
|
||||
}
|
||||
|
||||
// redirect to previous URL.
|
||||
return redirect($this->getPreviousUri('recurring.create.uri'));
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -26,6 +26,8 @@ namespace FireflyIII\Http\Controllers\Recurring;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceRepetition;
|
||||
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -33,6 +35,9 @@ use FireflyIII\Models\Recurrence;
|
||||
*/
|
||||
class EditController extends Controller
|
||||
{
|
||||
/** @var RecurringRepositoryInterface */
|
||||
private $recurring;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -56,10 +61,23 @@ class EditController extends Controller
|
||||
|
||||
/**
|
||||
* @param Recurrence $recurrence
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
*/
|
||||
public function edit(Recurrence $recurrence) {
|
||||
public function edit(Recurrence $recurrence)
|
||||
{
|
||||
// get recurrence type:
|
||||
// todo move to repository
|
||||
/** @var RecurrenceRepetition $repetition */
|
||||
$repetition = $recurrence->recurrenceRepetitions()->first();
|
||||
$currentRepetitionType = $repetition->repetition_type;
|
||||
if ('' !== $repetition->repetition_moment) {
|
||||
$currentRepetitionType .= ',' . $repetition->repetition_moment;
|
||||
}
|
||||
|
||||
return view('recurring.edit', compact('recurrence'));
|
||||
// todo handle old repetition type as well.
|
||||
|
||||
return view('recurring.edit', compact('recurrence','currentRepetitionType'));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -71,7 +71,7 @@ class IndexController extends Controller
|
||||
* @throws FireflyException
|
||||
* @return JsonResponse
|
||||
*/
|
||||
function events(RecurringRepositoryInterface $repository, Request $request): JsonResponse
|
||||
function events(Request $request): JsonResponse
|
||||
{
|
||||
$return = [];
|
||||
$start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
|
||||
@@ -118,14 +118,14 @@ class IndexController extends Controller
|
||||
throw new FireflyException(sprintf('Cannot generate events for type that ends at "%s".', $endsAt));
|
||||
case 'forever':
|
||||
// simply generate up until $end. No change from default behavior.
|
||||
$occurrences = $repository->getOccurrencesInRange($repetition, $actualStart, $actualEnd);
|
||||
$occurrences = $this->recurring->getOccurrencesInRange($repetition, $actualStart, $actualEnd);
|
||||
break;
|
||||
case 'until_date':
|
||||
$actualEnd = $endDate ?? clone $end;
|
||||
$occurrences = $repository->getOccurrencesInRange($repetition, $actualStart, $actualEnd);
|
||||
$occurrences = $this->recurring->getOccurrencesInRange($repetition, $actualStart, $actualEnd);
|
||||
break;
|
||||
case 'times':
|
||||
$occurrences = $repository->getXOccurrences($repetition, $actualStart, $repetitions);
|
||||
$occurrences = $this->recurring->getXOccurrences($repetition, $actualStart, $repetitions);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ class IndexController extends Controller
|
||||
$today = new Carbon;
|
||||
$date = Carbon::createFromFormat('Y-m-d', $request->get('date'));
|
||||
$result = [];
|
||||
if ($date > $today) {
|
||||
if ($date > $today || $request->get('past') === 'true') {
|
||||
$weekly = sprintf('weekly,%s', $date->dayOfWeekIso);
|
||||
$monthly = sprintf('monthly,%s', $date->day);
|
||||
$dayOfWeek = trans(sprintf('config.dow_%s', $date->dayOfWeekIso));
|
||||
|
@@ -50,14 +50,8 @@ class SingleController extends Controller
|
||||
{
|
||||
/** @var AttachmentHelperInterface */
|
||||
private $attachments;
|
||||
|
||||
/** @var BudgetRepositoryInterface */
|
||||
private $budgets;
|
||||
/** @var CurrencyRepositoryInterface */
|
||||
private $currency;
|
||||
/** @var PiggyBankRepositoryInterface */
|
||||
private $piggyBanks;
|
||||
|
||||
/** @var JournalRepositoryInterface */
|
||||
private $repository;
|
||||
|
||||
@@ -77,9 +71,7 @@ class SingleController extends Controller
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
$this->budgets = app(BudgetRepositoryInterface::class);
|
||||
$this->piggyBanks = app(PiggyBankRepositoryInterface::class);
|
||||
$this->attachments = app(AttachmentHelperInterface::class);
|
||||
$this->currency = app(CurrencyRepositoryInterface::class);
|
||||
$this->repository = app(JournalRepositoryInterface::class);
|
||||
|
||||
app('view')->share('title', trans('firefly.transactions'));
|
||||
@@ -101,7 +93,6 @@ class SingleController extends Controller
|
||||
$destination = $this->repository->getJournalDestinationAccounts($journal)->first();
|
||||
$budgetId = $this->repository->getJournalBudgetId($journal);
|
||||
$categoryName = $this->repository->getJournalCategoryName($journal);
|
||||
|
||||
$tags = implode(',', $this->repository->getTags($journal));
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $journal->transactions()->first();
|
||||
@@ -156,8 +147,6 @@ class SingleController extends Controller
|
||||
$what = strtolower($what);
|
||||
$what = $request->old('what') ?? $what;
|
||||
$budgets = ExpandedForm::makeSelectListWithEmpty($this->budgets->getActiveBudgets());
|
||||
$piggyBanks = $this->piggyBanks->getPiggyBanksWithAmount();
|
||||
$piggies = ExpandedForm::makeSelectListWithEmpty($piggyBanks);
|
||||
$preFilled = session()->has('preFilled') ? session('preFilled') : [];
|
||||
$subTitle = trans('form.add_new_' . $what);
|
||||
$subTitleIcon = 'fa-plus';
|
||||
@@ -179,11 +168,9 @@ class SingleController extends Controller
|
||||
}
|
||||
session()->forget('transactions.create.fromStore');
|
||||
|
||||
asort($piggies);
|
||||
|
||||
return view(
|
||||
'transactions.single.create',
|
||||
compact('subTitleIcon', 'budgets', 'what', 'piggies', 'subTitle', 'optionalFields', 'preFilled')
|
||||
compact('subTitleIcon', 'budgets', 'what', 'subTitle', 'optionalFields', 'preFilled')
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -27,6 +27,7 @@ use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Rules\ValidRecurrenceRepetitionType;
|
||||
use FireflyIII\Rules\ValidRecurrenceRepetitionValue;
|
||||
|
||||
/**
|
||||
* Class RecurrenceFormRequest
|
||||
@@ -49,8 +50,8 @@ class RecurrenceFormRequest extends Request
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
$data = $this->all();
|
||||
$return = [
|
||||
$repetitionData = $this->parseRepetitionData();
|
||||
$return = [
|
||||
'recurrence' => [
|
||||
'type' => $this->string('transaction_type'),
|
||||
'title' => $this->string('title'),
|
||||
@@ -81,7 +82,9 @@ class RecurrenceFormRequest extends Request
|
||||
],
|
||||
'repetitions' => [
|
||||
[
|
||||
'skip' => $this->integer('skip'),
|
||||
'type' => $repetitionData['type'],
|
||||
'moment' => $repetitionData['moment'],
|
||||
'skip' => $this->integer('skip'),
|
||||
],
|
||||
],
|
||||
|
||||
@@ -101,6 +104,14 @@ class RecurrenceFormRequest extends Request
|
||||
$return['transactions'][0]['source_account_id'] = $this->integer('source_account_id');
|
||||
$return['transactions'][0]['destination_account_name'] = $this->string('destination_account_name');
|
||||
break;
|
||||
case 'deposit':
|
||||
$return['transactions'][0]['source_account_name'] = $this->string('source_account_name');
|
||||
$return['transactions'][0]['destination_account_id'] = $this->integer('destination_account_id');
|
||||
break;
|
||||
case 'transfer':
|
||||
$return['transactions'][0]['source_account_id'] = $this->integer('source_account_id');
|
||||
$return['transactions'][0]['destination_account_id'] = $this->integer('destination_account_id');
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
@@ -120,7 +131,7 @@ class RecurrenceFormRequest extends Request
|
||||
//'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
|
||||
'title' => 'required|between:1,255',
|
||||
'first_date' => 'required|date|after:' . $today->format('Y-m-d'),
|
||||
'repetition_type' => ['required', new ValidRecurrenceRepetitionType, 'between:1,20'],
|
||||
'repetition_type' => ['required', new ValidRecurrenceRepetitionValue, new ValidRecurrenceRepetitionType, 'between:1,20'],
|
||||
'skip' => 'required|numeric|between:0,31',
|
||||
|
||||
// optional for recurrence:
|
||||
@@ -186,4 +197,38 @@ class RecurrenceFormRequest extends Request
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function parseRepetitionData(): array
|
||||
{
|
||||
$value = $this->string('repetition_type');
|
||||
$return = [
|
||||
'type' => '',
|
||||
'moment' => '',
|
||||
];
|
||||
|
||||
if ($value === 'daily') {
|
||||
$return['type'] = $value;
|
||||
}
|
||||
//monthly,17
|
||||
//ndom,3,7
|
||||
if (\in_array(substr($value, 0, 6), ['yearly', 'weekly'])) {
|
||||
$return['type'] = substr($value, 0, 6);
|
||||
$return['moment'] = substr($value, 7);
|
||||
}
|
||||
if (0 === strpos($value, 'monthly')) {
|
||||
$return['type'] = substr($value, 0, 7);
|
||||
$return['moment'] = substr($value, 8);
|
||||
}
|
||||
if (0 === strpos($value, 'ndom')) {
|
||||
$return['type'] = substr($value, 0, 4);
|
||||
$return['moment'] = substr($value, 5);
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user