mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-29 18:20:01 +00:00
Improve code for recurring transactions.
This commit is contained in:
@@ -25,13 +25,8 @@ namespace FireflyIII\Factory;
|
|||||||
|
|
||||||
|
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\RecurrenceMeta;
|
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
||||||
use FireflyIII\Models\RecurrenceRepetition;
|
|
||||||
use FireflyIII\Models\RecurrenceTransaction;
|
|
||||||
use FireflyIII\Models\RecurrenceTransactionMeta;
|
|
||||||
use FireflyIII\Models\TransactionType;
|
|
||||||
use FireflyIII\Services\Internal\Support\TransactionServiceTrait;
|
use FireflyIII\Services\Internal\Support\TransactionServiceTrait;
|
||||||
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
@@ -41,7 +36,7 @@ use FireflyIII\User;
|
|||||||
*/
|
*/
|
||||||
class RecurrenceFactory
|
class RecurrenceFactory
|
||||||
{
|
{
|
||||||
use TransactionTypeTrait, TransactionServiceTrait;
|
use TransactionTypeTrait, TransactionServiceTrait, RecurringTransactionTrait;
|
||||||
|
|
||||||
/** @var User */
|
/** @var User */
|
||||||
private $user;
|
private $user;
|
||||||
@@ -54,15 +49,16 @@ class RecurrenceFactory
|
|||||||
*/
|
*/
|
||||||
public function create(array $data): Recurrence
|
public function create(array $data): Recurrence
|
||||||
{
|
{
|
||||||
$type = $this->findTransactionType(ucfirst($data['recurrence']['type']));
|
$type = $this->findTransactionType(ucfirst($data['recurrence']['type']));
|
||||||
$recurrence = new Recurrence(
|
$repetitions = (int)$data['recurrence']['repetitions'];
|
||||||
|
$recurrence = new Recurrence(
|
||||||
[
|
[
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'transaction_type_id' => $type->id,
|
'transaction_type_id' => $type->id,
|
||||||
'title' => $data['recurrence']['title'],
|
'title' => $data['recurrence']['title'],
|
||||||
'description' => $data['recurrence']['description'],
|
'description' => $data['recurrence']['description'],
|
||||||
'first_date' => $data['recurrence']['first_date']->format('Y-m-d'),
|
'first_date' => $data['recurrence']['first_date']->format('Y-m-d'),
|
||||||
'repeat_until' => $data['recurrence']['repeat_until'],
|
'repeat_until' => $repetitions > 0 ? null : $data['recurrence']['repeat_until'],
|
||||||
'latest_date' => null,
|
'latest_date' => null,
|
||||||
'repetitions' => $data['recurrence']['repetitions'],
|
'repetitions' => $data['recurrence']['repetitions'],
|
||||||
'apply_rules' => $data['recurrence']['apply_rules'],
|
'apply_rules' => $data['recurrence']['apply_rules'],
|
||||||
@@ -71,105 +67,9 @@ class RecurrenceFactory
|
|||||||
);
|
);
|
||||||
$recurrence->save();
|
$recurrence->save();
|
||||||
|
|
||||||
// create recurrence meta (tags)
|
$this->updateMetaData($recurrence, $data);
|
||||||
if (\count($data['meta']['tags']) > 0) {
|
$this->createRepetitions($recurrence, $data['repetitions'] ?? []);
|
||||||
// todo move to factory
|
$this->createTransactions($recurrence, $data['transactions'] ?? []);
|
||||||
$tags = implode(',', $data['meta']['tags']);
|
|
||||||
if ('' !== $tags) {
|
|
||||||
$metaValue = RecurrenceMeta::create(
|
|
||||||
[
|
|
||||||
'recurrence_id' => $recurrence->id,
|
|
||||||
'name' => 'tags',
|
|
||||||
'value' => $tags,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// create recurrence meta (piggy bank ID):
|
|
||||||
if ($data['meta']['piggy_bank_id'] > 0) {
|
|
||||||
// todo move to factory
|
|
||||||
$metaValue = RecurrenceMeta::create(
|
|
||||||
[
|
|
||||||
'recurrence_id' => $recurrence->id,
|
|
||||||
'name' => 'piggy_bank_id',
|
|
||||||
'value' => $data['meta']['piggy_bank_id'],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// store recurrence repetitions:
|
|
||||||
foreach ($data['repetitions'] as $repArray) {
|
|
||||||
// todo move to factory
|
|
||||||
$repetition = RecurrenceRepetition::create(
|
|
||||||
[
|
|
||||||
'recurrence_id' => $recurrence->id,
|
|
||||||
'repetition_type' => $repArray['type'],
|
|
||||||
'repetition_moment' => $repArray['moment'],
|
|
||||||
'repetition_skip' => $repArray['skip'],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create recurrence transactions
|
|
||||||
foreach ($data['transactions'] as $trArray) {
|
|
||||||
// todo move to factory
|
|
||||||
$source = null;
|
|
||||||
$destination = null;
|
|
||||||
// search source account, depends on type
|
|
||||||
switch ($type->type) {
|
|
||||||
default:
|
|
||||||
throw new FireflyException(sprintf('Cannot create "%s".', $type->type));
|
|
||||||
case TransactionType::WITHDRAWAL:
|
|
||||||
$source = $this->findAccount(AccountType::ASSET, $trArray['source_account_id'], null);
|
|
||||||
$destination = $this->findAccount(AccountType::EXPENSE, null, $trArray['destination_account_name']);
|
|
||||||
break;
|
|
||||||
case TransactionType::DEPOSIT:
|
|
||||||
$source = $this->findAccount(AccountType::REVENUE, null, $trArray['source_account_name']);
|
|
||||||
$destination = $this->findAccount(AccountType::ASSET, $trArray['destination_account_id'], null);
|
|
||||||
break;
|
|
||||||
case TransactionType::TRANSFER:
|
|
||||||
$source = $this->findAccount(AccountType::ASSET, $trArray['source_account_id'], null);
|
|
||||||
$destination = $this->findAccount(AccountType::ASSET, $trArray['destination_account_id'], null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// search destination account
|
|
||||||
|
|
||||||
$transaction = new RecurrenceTransaction(
|
|
||||||
[
|
|
||||||
'recurrence_id' => $recurrence->id,
|
|
||||||
'transaction_currency_id' => $trArray['transaction_currency_id'],
|
|
||||||
'foreign_currency_id' => '' === (string)$trArray['foreign_amount'] ? null : $trArray['foreign_currency_id'],
|
|
||||||
'source_account_id' => $source->id,
|
|
||||||
'destination_account_id' => $destination->id,
|
|
||||||
'amount' => $trArray['amount'],
|
|
||||||
'foreign_amount' => '' === (string)$trArray['foreign_amount'] ? null : (string)$trArray['foreign_amount'],
|
|
||||||
'description' => $trArray['description'],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
$transaction->save();
|
|
||||||
|
|
||||||
// create recurrence transaction meta:
|
|
||||||
// todo move to factory
|
|
||||||
if ($trArray['budget_id'] > 0) {
|
|
||||||
$trMeta = RecurrenceTransactionMeta::create(
|
|
||||||
[
|
|
||||||
'rt_id' => $transaction->id,
|
|
||||||
'name' => 'budget_id',
|
|
||||||
'value' => $trArray['budget_id'],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ('' !== (string)$trArray['category_name']) {
|
|
||||||
$trMeta = RecurrenceTransactionMeta::create(
|
|
||||||
[
|
|
||||||
'rt_id' => $transaction->id,
|
|
||||||
'name' => 'category_name',
|
|
||||||
'value' => $trArray['category_name'],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $recurrence;
|
return $recurrence;
|
||||||
}
|
}
|
||||||
|
@@ -71,7 +71,6 @@ class CreateController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
// todo create expandedform thing.
|
|
||||||
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgets->getActiveBudgets());
|
$budgets = app('expandedform')->makeSelectListWithEmpty($this->budgets->getActiveBudgets());
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||||
$tomorrow = new Carbon;
|
$tomorrow = new Carbon;
|
||||||
@@ -92,11 +91,12 @@ class CreateController extends Controller
|
|||||||
];
|
];
|
||||||
|
|
||||||
// flash some data:
|
// flash some data:
|
||||||
|
$hasOldInput = null !== $request->old('_token');
|
||||||
$preFilled = [
|
$preFilled = [
|
||||||
'first_date' => $tomorrow->format('Y-m-d'),
|
'first_date' => $tomorrow->format('Y-m-d'),
|
||||||
'transaction_type' => 'withdrawal',
|
'transaction_type' => $hasOldInput ? $request->old('transaction_type') : 'withdrawal',
|
||||||
'active' => $request->old('active') ?? true,
|
'active' => $hasOldInput ? (bool)$request->old('active') : true,
|
||||||
'apply_rules' => $request->old('apply_rules') ?? true,
|
'apply_rules' => $hasOldInput ? (bool)$request->old('apply_rules') : true,
|
||||||
];
|
];
|
||||||
$request->session()->flash('preFilled', $preFilled);
|
$request->session()->flash('preFilled', $preFilled);
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@ namespace FireflyIII\Http\Controllers\Recurring;
|
|||||||
|
|
||||||
|
|
||||||
use FireflyIII\Http\Controllers\Controller;
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
|
use FireflyIII\Http\Requests\RecurrenceFormRequest;
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\RecurrenceRepetition;
|
use FireflyIII\Models\RecurrenceRepetition;
|
||||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||||
@@ -91,6 +92,13 @@ class EditController extends Controller
|
|||||||
if ('' !== $repetition->repetition_moment) {
|
if ('' !== $repetition->repetition_moment) {
|
||||||
$currentRepetitionType .= ',' . $repetition->repetition_moment;
|
$currentRepetitionType .= ',' . $repetition->repetition_moment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// put previous url in session if not redirect from store (not "return_to_edit").
|
||||||
|
if (true !== session('recurrences.edit.fromUpdate')) {
|
||||||
|
$this->rememberPreviousUri('recurrences.edit.uri');
|
||||||
|
}
|
||||||
|
$request->session()->forget('recurrences.edit.fromUpdate');
|
||||||
|
|
||||||
// assume repeats forever:
|
// assume repeats forever:
|
||||||
$repetitionEnd = 'forever';
|
$repetitionEnd = 'forever';
|
||||||
// types of repetitions:
|
// types of repetitions:
|
||||||
@@ -112,12 +120,38 @@ class EditController extends Controller
|
|||||||
'transaction_type' => strtolower($recurrence->transactionType->type),
|
'transaction_type' => strtolower($recurrence->transactionType->type),
|
||||||
'active' => $hasOldInput ? (bool)$request->old('active') : $recurrence->active,
|
'active' => $hasOldInput ? (bool)$request->old('active') : $recurrence->active,
|
||||||
'apply_rules' => $hasOldInput ? (bool)$request->old('apply_rules') : $recurrence->apply_rules,
|
'apply_rules' => $hasOldInput ? (bool)$request->old('apply_rules') : $recurrence->apply_rules,
|
||||||
|
|
||||||
];
|
];
|
||||||
$request->flash('preFilled', $preFilled);
|
$request->flash('preFilled', $preFilled);
|
||||||
|
|
||||||
|
|
||||||
return view('recurring.edit', compact('recurrence', 'array', 'budgets', 'preFilled', 'currentRepetitionType', 'repetitionEnd', 'repetitionEnds'));
|
return view('recurring.edit', compact('recurrence', 'array', 'budgets', 'preFilled', 'currentRepetitionType', 'repetitionEnd', 'repetitionEnds'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param RecurrenceFormRequest $request
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||||
|
* @throws \FireflyIII\Exceptions\FireflyException
|
||||||
|
*/
|
||||||
|
public function update(RecurrenceFormRequest $request, Recurrence $recurrence)
|
||||||
|
{
|
||||||
|
$data = $request->getAll();
|
||||||
|
$this->recurring->update($recurrence, $data);
|
||||||
|
|
||||||
|
$request->session()->flash('success', (string)trans('firefly.updated_recurrence', ['title' => $recurrence->title]));
|
||||||
|
app('preferences')->mark();
|
||||||
|
|
||||||
|
if (1 === (int)$request->get('return_to_edit')) {
|
||||||
|
// set value so edit routine will not overwrite URL:
|
||||||
|
$request->session()->put('recurrences.edit.fromUpdate', true);
|
||||||
|
|
||||||
|
return redirect(route('recurring.edit', [$recurrence->id]))->withInput(['return_to_edit' => 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// redirect to previous URL.
|
||||||
|
return redirect($this->getPreviousUri('recurrences.edit.uri'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@@ -33,7 +33,6 @@ use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
|
|||||||
use FireflyIII\Transformers\RecurrenceTransformer;
|
use FireflyIII\Transformers\RecurrenceTransformer;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Response;
|
|
||||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,7 +85,7 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
// if $firstDate is beyond $end, simply return an empty array.
|
// if $firstDate is beyond $end, simply return an empty array.
|
||||||
if ($firstDate->gt($end)) {
|
if ($firstDate->gt($end)) {
|
||||||
return Response::json([]);
|
return response()->json([]);
|
||||||
}
|
}
|
||||||
// if $firstDate is beyond start, use that one:
|
// if $firstDate is beyond start, use that one:
|
||||||
$actualStart = clone $firstDate;
|
$actualStart = clone $firstDate;
|
||||||
@@ -146,7 +145,7 @@ class IndexController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response::json($return);
|
return response()->json($return);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -168,10 +167,11 @@ class IndexController extends Controller
|
|||||||
$recurring = [];
|
$recurring = [];
|
||||||
/** @var Recurrence $recurrence */
|
/** @var Recurrence $recurrence */
|
||||||
foreach ($collection as $recurrence) {
|
foreach ($collection as $recurrence) {
|
||||||
$array = $transformer->transform($recurrence);
|
$array = $transformer->transform($recurrence);
|
||||||
$array['first_date'] = new Carbon($array['first_date']);
|
$array['first_date'] = new Carbon($array['first_date']);
|
||||||
$array['latest_date'] = null === $array['latest_date'] ? null : new Carbon($array['latest_date']);
|
$array['repeat_until'] = null === $array['repeat_until'] ? null : new Carbon($array['repeat_until']);
|
||||||
$recurring[] = $array;
|
$array['latest_date'] = null === $array['latest_date'] ? null : new Carbon($array['latest_date']);
|
||||||
|
$recurring[] = $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('recurring.index', compact('recurring', 'page', 'pageSize'));
|
return view('recurring.index', compact('recurring', 'page', 'pageSize'));
|
||||||
@@ -207,10 +207,11 @@ class IndexController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function suggest(Request $request): JsonResponse
|
public function suggest(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
$today = new Carbon;
|
$today = new Carbon;
|
||||||
$date = Carbon::createFromFormat('Y-m-d', $request->get('date'));
|
$date = Carbon::createFromFormat('Y-m-d', $request->get('date'));
|
||||||
$result = [];
|
$preSelected = (string)$request->get('pre_select');
|
||||||
if ($date > $today || $request->get('past') === 'true') {
|
$result = [];
|
||||||
|
if ($date > $today || (string)$request->get('past') === 'true') {
|
||||||
$weekly = sprintf('weekly,%s', $date->dayOfWeekIso);
|
$weekly = sprintf('weekly,%s', $date->dayOfWeekIso);
|
||||||
$monthly = sprintf('monthly,%s', $date->day);
|
$monthly = sprintf('monthly,%s', $date->day);
|
||||||
$dayOfWeek = trans(sprintf('config.dow_%s', $date->dayOfWeekIso));
|
$dayOfWeek = trans(sprintf('config.dow_%s', $date->dayOfWeekIso));
|
||||||
@@ -218,16 +219,16 @@ class IndexController extends Controller
|
|||||||
$yearly = sprintf('yearly,%s', $date->format('Y-m-d'));
|
$yearly = sprintf('yearly,%s', $date->format('Y-m-d'));
|
||||||
$yearlyDate = $date->formatLocalized(trans('config.month_and_day_no_year'));
|
$yearlyDate = $date->formatLocalized(trans('config.month_and_day_no_year'));
|
||||||
$result = [
|
$result = [
|
||||||
'daily' => trans('firefly.recurring_daily'),
|
'daily' => ['label' => trans('firefly.recurring_daily'), 'selected' => 0 === strpos($preSelected, 'daily')],
|
||||||
$weekly => trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek]),
|
$weekly => ['label' => trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek]), 'selected' => 0 === strpos($preSelected, 'weekly')],
|
||||||
$monthly => trans('firefly.recurring_monthly', ['dayOfMonth' => $date->day]),
|
$monthly => ['label' => trans('firefly.recurring_monthly', ['dayOfMonth' => $date->day]), 'selected' => 0 === strpos($preSelected, 'monthly')],
|
||||||
$ndom => trans('firefly.recurring_ndom', ['weekday' => $dayOfWeek, 'dayOfMonth' => $date->weekOfMonth]),
|
$ndom => ['label' => trans('firefly.recurring_ndom', ['weekday' => $dayOfWeek, 'dayOfMonth' => $date->weekOfMonth]),'selected' => 0 === strpos($preSelected, 'ndom')],
|
||||||
$yearly => trans('firefly.recurring_yearly', ['date' => $yearlyDate]),
|
$yearly => ['label' => trans('firefly.recurring_yearly', ['date' => $yearlyDate]),'selected' => 0 === strpos($preSelected, 'yearly')],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return Response::json($result);
|
return response()->json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@@ -25,6 +25,7 @@ namespace FireflyIII\Http\Requests;
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
use FireflyIII\Rules\ValidRecurrenceRepetitionType;
|
use FireflyIII\Rules\ValidRecurrenceRepetitionType;
|
||||||
use FireflyIII\Rules\ValidRecurrenceRepetitionValue;
|
use FireflyIII\Rules\ValidRecurrenceRepetitionValue;
|
||||||
@@ -53,14 +54,15 @@ class RecurrenceFormRequest extends Request
|
|||||||
$repetitionData = $this->parseRepetitionData();
|
$repetitionData = $this->parseRepetitionData();
|
||||||
$return = [
|
$return = [
|
||||||
'recurrence' => [
|
'recurrence' => [
|
||||||
'type' => $this->string('transaction_type'),
|
'type' => $this->string('transaction_type'),
|
||||||
'title' => $this->string('title'),
|
'title' => $this->string('title'),
|
||||||
'description' => $this->string('recurring_description'),
|
'description' => $this->string('recurring_description'),
|
||||||
'first_date' => $this->date('first_date'),
|
'first_date' => $this->date('first_date'),
|
||||||
'repeat_until' => $this->date('repeat_until'),
|
'repeat_until' => $this->date('repeat_until'),
|
||||||
'repetitions' => $this->integer('repetitions'),
|
'repetitions' => $this->integer('repetitions'),
|
||||||
'apply_rules' => $this->boolean('apply_rules'),
|
'apply_rules' => $this->boolean('apply_rules'),
|
||||||
'active' => $this->boolean('active'),
|
'active' => $this->boolean('active'),
|
||||||
|
'repetition_end' => $this->string('repetition_end'),
|
||||||
],
|
],
|
||||||
'transactions' => [
|
'transactions' => [
|
||||||
[
|
[
|
||||||
@@ -77,7 +79,7 @@ class RecurrenceFormRequest extends Request
|
|||||||
],
|
],
|
||||||
'meta' => [
|
'meta' => [
|
||||||
// tags and piggy bank ID.
|
// tags and piggy bank ID.
|
||||||
'tags' => explode(',', $this->string('tags')),
|
'tags' => '' !== $this->string('tags') ? explode(',', $this->string('tags')): [],
|
||||||
'piggy_bank_id' => $this->integer('piggy_bank_id'),
|
'piggy_bank_id' => $this->integer('piggy_bank_id'),
|
||||||
],
|
],
|
||||||
'repetitions' => [
|
'repetitions' => [
|
||||||
@@ -128,8 +130,7 @@ class RecurrenceFormRequest extends Request
|
|||||||
$tomorrow->addDay();
|
$tomorrow->addDay();
|
||||||
$rules = [
|
$rules = [
|
||||||
// mandatory info for recurrence.
|
// mandatory info for recurrence.
|
||||||
//'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
|
'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
|
||||||
'title' => 'required|between:1,255',
|
|
||||||
'first_date' => 'required|date|after:' . $today->format('Y-m-d'),
|
'first_date' => 'required|date|after:' . $today->format('Y-m-d'),
|
||||||
'repetition_type' => ['required', new ValidRecurrenceRepetitionValue, new ValidRecurrenceRepetitionType, 'between:1,20'],
|
'repetition_type' => ['required', new ValidRecurrenceRepetitionValue, new ValidRecurrenceRepetitionType, 'between:1,20'],
|
||||||
'skip' => 'required|numeric|between:0,31',
|
'skip' => 'required|numeric|between:0,31',
|
||||||
@@ -196,6 +197,15 @@ class RecurrenceFormRequest extends Request
|
|||||||
throw new FireflyException(sprintf('Cannot handle transaction type of type "%s"', $this->string('transaction_type'))); // @codeCoverageIgnore
|
throw new FireflyException(sprintf('Cannot handle transaction type of type "%s"', $this->string('transaction_type'))); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update some rules in case the user is editing a post:
|
||||||
|
/** @var Recurrence $recurrence */
|
||||||
|
$recurrence = $this->route()->parameter('recurrence');
|
||||||
|
if ($recurrence instanceof Recurrence) {
|
||||||
|
$rules['id'] = 'required|numeric|exists:recurrences,id';
|
||||||
|
$rules['title'] = 'required|between:1,255|uniqueObjectForUser:recurrences,title,' . $recurrence->id;
|
||||||
|
$rules['first_date'] = 'required|date';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property \FireflyIII\Models\Account $sourceAccount
|
* @property \FireflyIII\Models\Account $sourceAccount
|
||||||
* @property \FireflyIII\Models\Account $destinationAccount
|
* @property \FireflyIII\Models\Account $destinationAccount
|
||||||
* @property \Illuminate\Support\Collection $recurrenceTransactionMeta
|
* @property \Illuminate\Support\Collection $recurrenceTransactionMeta
|
||||||
|
* @property int $id
|
||||||
*/
|
*/
|
||||||
class RecurrenceTransaction extends Model
|
class RecurrenceTransaction extends Model
|
||||||
{
|
{
|
||||||
|
@@ -30,6 +30,7 @@ use FireflyIII\Models\Note;
|
|||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\RecurrenceRepetition;
|
use FireflyIII\Models\RecurrenceRepetition;
|
||||||
|
use FireflyIII\Services\Internal\Update\RecurrenceUpdateService;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
@@ -368,4 +369,20 @@ class RecurringRepository implements RecurringRepositoryInterface
|
|||||||
|
|
||||||
return $factory->create($data);
|
return $factory->create($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a recurring transaction.
|
||||||
|
*
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return Recurrence
|
||||||
|
*/
|
||||||
|
public function update(Recurrence $recurrence, array $data): Recurrence
|
||||||
|
{
|
||||||
|
/** @var RecurrenceUpdateService $service */
|
||||||
|
$service = app(RecurrenceUpdateService::class);
|
||||||
|
|
||||||
|
return $service->update($recurrence, $data);
|
||||||
|
}
|
||||||
}
|
}
|
@@ -97,6 +97,8 @@ interface RecurringRepositoryInterface
|
|||||||
public function setUser(User $user): void;
|
public function setUser(User $user): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Store a new recurring transaction.
|
||||||
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
@@ -104,4 +106,14 @@ interface RecurringRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function store(array $data): Recurrence;
|
public function store(array $data): Recurrence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a recurring transaction.
|
||||||
|
*
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return Recurrence
|
||||||
|
*/
|
||||||
|
public function update(Recurrence $recurrence, array $data): Recurrence;
|
||||||
|
|
||||||
}
|
}
|
190
app/Services/Internal/Support/RecurringTransactionTrait.php
Normal file
190
app/Services/Internal/Support/RecurringTransactionTrait.php
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RecurringTransactionTrait.php
|
||||||
|
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III.
|
||||||
|
*
|
||||||
|
* Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Firefly III is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Services\Internal\Support;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Models\AccountType;
|
||||||
|
use FireflyIII\Models\Recurrence;
|
||||||
|
use FireflyIII\Models\RecurrenceMeta;
|
||||||
|
use FireflyIII\Models\RecurrenceRepetition;
|
||||||
|
use FireflyIII\Models\RecurrenceTransaction;
|
||||||
|
use FireflyIII\Models\RecurrenceTransactionMeta;
|
||||||
|
use FireflyIII\Models\TransactionType;
|
||||||
|
use Log;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trait RecurringTransactionTrait
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Services\Internal\Support
|
||||||
|
*/
|
||||||
|
trait RecurringTransactionTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
* @param array $repetitions
|
||||||
|
*/
|
||||||
|
public function createRepetitions(Recurrence $recurrence, array $repetitions): void
|
||||||
|
{
|
||||||
|
/** @var array $array */
|
||||||
|
foreach ($repetitions as $array) {
|
||||||
|
RecurrenceRepetition::create(
|
||||||
|
[
|
||||||
|
'recurrence_id' => $recurrence->id,
|
||||||
|
'repetition_type' => $array['type'],
|
||||||
|
'repetition_moment' => $array['moment'],
|
||||||
|
'repetition_skip' => $array['skip'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
* @param array $transactions
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
public function createTransactions(Recurrence $recurrence, array $transactions): void
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach ($transactions as $array) {
|
||||||
|
$source = null;
|
||||||
|
$destination = null;
|
||||||
|
switch ($recurrence->transactionType->type) {
|
||||||
|
default:
|
||||||
|
throw new FireflyException(sprintf('Cannot create "%s".', $recurrence->transactionType->type));
|
||||||
|
case TransactionType::WITHDRAWAL:
|
||||||
|
$source = $this->findAccount(AccountType::ASSET, $array['source_account_id'], null);
|
||||||
|
$destination = $this->findAccount(AccountType::EXPENSE, null, $array['destination_account_name']);
|
||||||
|
break;
|
||||||
|
case TransactionType::DEPOSIT:
|
||||||
|
$source = $this->findAccount(AccountType::REVENUE, null, $array['source_account_name']);
|
||||||
|
$destination = $this->findAccount(AccountType::ASSET, $array['destination_account_id'], null);
|
||||||
|
break;
|
||||||
|
case TransactionType::TRANSFER:
|
||||||
|
$source = $this->findAccount(AccountType::ASSET, $array['source_account_id'], null);
|
||||||
|
$destination = $this->findAccount(AccountType::ASSET, $array['destination_account_id'], null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$transaction = new RecurrenceTransaction(
|
||||||
|
[
|
||||||
|
'recurrence_id' => $recurrence->id,
|
||||||
|
'transaction_currency_id' => $array['transaction_currency_id'],
|
||||||
|
'foreign_currency_id' => '' === (string)$array['foreign_amount'] ? null : $array['foreign_currency_id'],
|
||||||
|
'source_account_id' => $source->id,
|
||||||
|
'destination_account_id' => $destination->id,
|
||||||
|
'amount' => $array['amount'],
|
||||||
|
'foreign_amount' => '' === (string)$array['foreign_amount'] ? null : (string)$array['foreign_amount'],
|
||||||
|
'description' => $array['description'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$transaction->save();
|
||||||
|
|
||||||
|
// create recurrence transaction meta:
|
||||||
|
if ($array['budget_id'] > 0) {
|
||||||
|
RecurrenceTransactionMeta::create(
|
||||||
|
[
|
||||||
|
'rt_id' => $transaction->id,
|
||||||
|
'name' => 'budget_id',
|
||||||
|
'value' => $array['budget_id'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ('' !== (string)$array['category_name']) {
|
||||||
|
RecurrenceTransactionMeta::create(
|
||||||
|
[
|
||||||
|
'rt_id' => $transaction->id,
|
||||||
|
'name' => 'category_name',
|
||||||
|
'value' => $array['category_name'],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
*/
|
||||||
|
public function deleteRepetitions(Recurrence $recurrence): void
|
||||||
|
{
|
||||||
|
$recurrence->recurrenceRepetitions()->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
*/
|
||||||
|
public function deleteTransactions(Recurrence $recurrence): void
|
||||||
|
{
|
||||||
|
/** @var RecurrenceTransaction $transaction */
|
||||||
|
foreach ($recurrence->recurrenceTransactions as $transaction) {
|
||||||
|
$transaction->recurrenceTransactionMeta()->delete();
|
||||||
|
try {
|
||||||
|
$transaction->delete();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::debug($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
* @param array $data
|
||||||
|
*/
|
||||||
|
public function updateMetaData(Recurrence $recurrence, array $data): void
|
||||||
|
{
|
||||||
|
// only two special meta fields right now. Let's just hard code them.
|
||||||
|
$piggyId = (int)($data['meta']['piggy_bank_id'] ?? 0.0);
|
||||||
|
if ($piggyId > 0) {
|
||||||
|
/** @var RecurrenceMeta $entry */
|
||||||
|
$entry = $recurrence->recurrenceMeta()->where('name', 'piggy_bank_id')->first();
|
||||||
|
if (null === $entry) {
|
||||||
|
$entry = RecurrenceMeta::create(['recurrence_id' => $recurrence->id, 'name' => 'piggy_bank_id', 'value' => $piggyId]);
|
||||||
|
}
|
||||||
|
$entry->value = $piggyId;
|
||||||
|
$entry->save();
|
||||||
|
}
|
||||||
|
if ($piggyId === 0) {
|
||||||
|
// delete if present
|
||||||
|
$recurrence->recurrenceMeta()->where('name', 'piggy_bank_id')->delete();
|
||||||
|
}
|
||||||
|
$tags = $data['meta']['tags'] ?? [];
|
||||||
|
if (\count($tags) > 0) {
|
||||||
|
/** @var RecurrenceMeta $entry */
|
||||||
|
$entry = $recurrence->recurrenceMeta()->where('name', 'tags')->first();
|
||||||
|
if (null === $entry) {
|
||||||
|
$entry = RecurrenceMeta::create(['recurrence_id' => $recurrence->id, 'name' => 'tags', 'value' => implode(',', $tags)]);
|
||||||
|
}
|
||||||
|
$entry->value = implode(',', $tags);
|
||||||
|
$entry->save();
|
||||||
|
}
|
||||||
|
if (\count($tags) === 0) {
|
||||||
|
// delete if present
|
||||||
|
$recurrence->recurrenceMeta()->where('name', 'tags')->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
app/Services/Internal/Update/RecurrenceUpdateService.php
Normal file
89
app/Services/Internal/Update/RecurrenceUpdateService.php
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* RecurrenceUpdateService.php
|
||||||
|
* Copyright (c) 2018 thegrumpydictator@gmail.com
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III.
|
||||||
|
*
|
||||||
|
* Firefly III is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Firefly III is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Services\Internal\Update;
|
||||||
|
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Models\Recurrence;
|
||||||
|
use FireflyIII\Models\RecurrenceMeta;
|
||||||
|
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
||||||
|
use FireflyIII\Services\Internal\Support\TransactionServiceTrait;
|
||||||
|
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
||||||
|
use FireflyIII\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RecurrenceUpdateService
|
||||||
|
*/
|
||||||
|
class RecurrenceUpdateService
|
||||||
|
{
|
||||||
|
use TransactionTypeTrait, TransactionServiceTrait, RecurringTransactionTrait;
|
||||||
|
|
||||||
|
/** @var User */
|
||||||
|
private $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a recurrence.
|
||||||
|
*
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return Recurrence
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
public function update(Recurrence $recurrence, array $data): Recurrence
|
||||||
|
{
|
||||||
|
// is expected by TransactionServiceTrait
|
||||||
|
$this->user = $recurrence->user;
|
||||||
|
$transactionType = $this->findTransactionType(ucfirst($data['recurrence']['type']));
|
||||||
|
// update basic fields first:
|
||||||
|
$recurrence->transaction_type_id = $transactionType->id;
|
||||||
|
$recurrence->title = $data['recurrence']['title'] ?? $recurrence->title;
|
||||||
|
$recurrence->description = $data['recurrence']['description'] ?? $recurrence->description;
|
||||||
|
$recurrence->first_date = $data['recurrence']['first_date'] ?? $recurrence->first_date;
|
||||||
|
$recurrence->repeat_until = $data['recurrence']['repeat_until'] ?? $recurrence->repeat_until;
|
||||||
|
$recurrence->repetitions = $data['recurrence']['repetitions'] ?? $recurrence->repetitions;
|
||||||
|
$recurrence->apply_rules = $data['recurrence']['apply_rules'] ?? $recurrence->apply_rules;
|
||||||
|
$recurrence->active = $data['recurrence']['active'] ?? $recurrence->active;
|
||||||
|
|
||||||
|
if (\in_array($data['recurrence']['repetition_end'], ['forever ', 'until_date'])) {
|
||||||
|
$recurrence->repetitions = 0;
|
||||||
|
}
|
||||||
|
if (\in_array($data['recurrence']['repetition_end'], ['forever ', 'times'])) {
|
||||||
|
$recurrence->repeat_until = null;
|
||||||
|
}
|
||||||
|
$recurrence->save();
|
||||||
|
|
||||||
|
// update all meta data:
|
||||||
|
$this->updateMetaData($recurrence, $data);
|
||||||
|
|
||||||
|
// update all repetitions
|
||||||
|
$this->deleteRepetitions($recurrence);
|
||||||
|
$this->createRepetitions($recurrence, $data['repetitions'] ?? []);
|
||||||
|
|
||||||
|
// update all transactions (and associated meta-data);
|
||||||
|
$this->deleteTransactions($recurrence);
|
||||||
|
$this->createTransactions($recurrence, $data['transactions'] ?? []);
|
||||||
|
|
||||||
|
return $recurrence;
|
||||||
|
}
|
||||||
|
}
|
14
public/js/ff/recurring/create.js
vendored
14
public/js/ff/recurring/create.js
vendored
@@ -104,7 +104,14 @@ function respondToFirstDateChange() {
|
|||||||
var select = $('#ffInput_repetition_type');
|
var select = $('#ffInput_repetition_type');
|
||||||
var date = obj.val();
|
var date = obj.val();
|
||||||
select.prop('disabled', true);
|
select.prop('disabled', true);
|
||||||
$.getJSON(suggestUri, {date: date}).fail(function () {
|
|
||||||
|
// preselected value:
|
||||||
|
var preSelected = oldRepetitionType;
|
||||||
|
if(preSelected === '') {
|
||||||
|
preSelected = select.val();
|
||||||
|
}
|
||||||
|
|
||||||
|
$.getJSON(suggestUri, {date: date,pre_select: preSelected}).fail(function () {
|
||||||
console.error('Could not load repetition suggestions');
|
console.error('Could not load repetition suggestions');
|
||||||
alert('Could not load repetition suggestions');
|
alert('Could not load repetition suggestions');
|
||||||
}).done(parseRepetitionSuggestions);
|
}).done(parseRepetitionSuggestions);
|
||||||
@@ -117,8 +124,9 @@ function parseRepetitionSuggestions(data) {
|
|||||||
var opt;
|
var opt;
|
||||||
for (var k in data) {
|
for (var k in data) {
|
||||||
if (data.hasOwnProperty(k)) {
|
if (data.hasOwnProperty(k)) {
|
||||||
opt = $('<option>').val(k).attr('label', data[k]).text(data[k]);
|
console.log('label: ' + data[k].label + ', selected: ' + data[k].selected);
|
||||||
if(k === oldRepetitionType) {
|
opt = $('<option>').val(k).attr('label', data[k].label).text(data[k].label);
|
||||||
|
if(data[k].selected) {
|
||||||
opt.attr('selected','selected');
|
opt.attr('selected','selected');
|
||||||
}
|
}
|
||||||
select.append(opt);
|
select.append(opt);
|
||||||
|
@@ -1247,4 +1247,9 @@ return [
|
|||||||
'store_new_recurrence' => 'Store recurring transaction',
|
'store_new_recurrence' => 'Store recurring transaction',
|
||||||
'stored_new_recurrence' => 'Recurring transaction ":title" stored successfully.',
|
'stored_new_recurrence' => 'Recurring transaction ":title" stored successfully.',
|
||||||
'edit_recurrence' => 'Edit recurring transaction ":title"',
|
'edit_recurrence' => 'Edit recurring transaction ":title"',
|
||||||
|
'recurring_repeats_until' => 'Repeats until :date',
|
||||||
|
'recurring_repeats_forever' => 'Repeats forever',
|
||||||
|
'recurring_repeats_x_times' => 'Repeats :count time(s)',
|
||||||
|
'update_recurrence' => 'Update recurring transaction',
|
||||||
|
'updated_recurrence' => 'Updated recurring transaction ":title"',
|
||||||
];
|
];
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<form action="{{ route('recurring.update') }}" method="post" id="store" class="form-horizontal">
|
{{ Form.model(recurrence, {'class' : 'form-horizontal','enctype': 'multipart/form-data','id' : 'update','url' : route('recurring.update', recurrence.id)}) }}
|
||||||
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||||
{# row with recurrence information #}
|
{# row with recurrence information #}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
<h3 class="box-title">{{ 'mandatory_for_recurring'|_ }}</h3>
|
<h3 class="box-title">{{ 'mandatory_for_recurring'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
{{ ExpandedForm.text('title',array.title) }}
|
<input type="hidden" name="id" value="{{ array.id }}" />
|
||||||
|
{{ ExpandedForm.text('title') }}
|
||||||
{{ ExpandedForm.date('first_date',array.first_date, {helpText: trans('firefly.help_first_date_no_past')}) }}
|
{{ ExpandedForm.date('first_date',array.first_date, {helpText: trans('firefly.help_first_date_no_past')}) }}
|
||||||
{{ ExpandedForm.select('repetition_type', [], null, {helpText: trans('firefly.change_date_other_options')}) }}
|
{{ ExpandedForm.select('repetition_type', [], null, {helpText: trans('firefly.change_date_other_options')}) }}
|
||||||
{{ ExpandedForm.number('skip', array.recurrence_repetitions[0].repetition_skip) }}
|
{{ ExpandedForm.number('skip', array.recurrence_repetitions[0].repetition_skip) }}
|
||||||
@@ -48,9 +49,8 @@
|
|||||||
{{ ExpandedForm.textarea('recurring_description',array.description) }}
|
{{ ExpandedForm.textarea('recurring_description',array.description) }}
|
||||||
|
|
||||||
{# only correct way to do active checkbox #}
|
{# only correct way to do active checkbox #}
|
||||||
{{ ExpandedForm.checkbox('active', 1) }}
|
{{ ExpandedForm.checkbox('active', 1, preFilled.active) }}
|
||||||
|
{{ ExpandedForm.checkbox('apply_rules', 1, preFilled.apply_rules) }}
|
||||||
{{ ExpandedForm.checkbox('apply_rules',1) }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,11 +162,11 @@
|
|||||||
<h3 class="box-title">{{ 'options'|_ }}</h3>
|
<h3 class="box-title">{{ 'options'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
{{ ExpandedForm.optionsList('create','recurrence') }}
|
{{ ExpandedForm.optionsList('update','recurrence') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
<button type="submit" class="btn pull-right btn-success">
|
<button type="submit" class="btn pull-right btn-success">
|
||||||
{{ ('store_new_recurrence')|_ }}
|
{{ ('update_recurrence')|_ }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -94,6 +94,17 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
<p>
|
||||||
|
{% if null == rt.repeat_until and rt.repetitions == 0 %}
|
||||||
|
{{ 'recurring_repeats_forever'|_ }}
|
||||||
|
{% endif %}
|
||||||
|
{% if null != rt.repeat_until and rt.repetitions == 0 %}
|
||||||
|
{{ trans('firefly.recurring_repeats_until', {date: rt.repeat_until.formatLocalized(monthAndDayFormat)}) }}
|
||||||
|
{% endif %}
|
||||||
|
{% if null == rt.repeat_until and rt.repetitions != 0 %}
|
||||||
|
{{ trans('firefly.recurring_repeats_x_times', {count: rt.repetitions}) }}
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@@ -625,7 +625,7 @@ Route::group(
|
|||||||
Route::get('delete/{recurrence}', ['uses' => 'DeleteController@delete', 'as' => 'delete']);
|
Route::get('delete/{recurrence}', ['uses' => 'DeleteController@delete', 'as' => 'delete']);
|
||||||
|
|
||||||
Route::post('store', ['uses' => 'CreateController@store', 'as' => 'store']);
|
Route::post('store', ['uses' => 'CreateController@store', 'as' => 'store']);
|
||||||
Route::post('update', ['uses' => 'EditController@update', 'as' => 'update']);
|
Route::post('update/{recurrence}', ['uses' => 'EditController@update', 'as' => 'update']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user