From db1c27d833e6c4d4c7992afbeea30115b4c16842 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 22 Jun 2018 18:42:23 +0200 Subject: [PATCH] First attempt at job to create transactions for recurring transactions. --- app/Console/Kernel.php | 43 ++- app/Factory/TransactionJournalFactory.php | 4 +- .../Controllers/Recurring/EditController.php | 6 +- .../Controllers/Recurring/IndexController.php | 2 +- app/Jobs/CreateRecurringTransactions.php | 321 ++++++++++++++++++ .../Recurring/RecurringRepository.php | 112 +++++- .../RecurringRepositoryInterface.php | 37 +- app/Support/ExpandedForm.php | 11 +- composer.lock | 50 +-- public/js/ff/recurring/edit.js | 15 +- readme.md | 6 +- resources/lang/en_US/firefly.php | 66 ++-- resources/views/form/options.twig | 2 +- resources/views/recurring/edit.twig | 2 +- resources/views/recurring/index.twig | 5 +- resources/views/recurring/show.twig | 97 +++--- 16 files changed, 646 insertions(+), 133 deletions(-) create mode 100644 app/Jobs/CreateRecurringTransactions.php diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 3f24caad90..d919e8e1a4 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -24,8 +24,13 @@ declare(strict_types=1); namespace FireflyIII\Console; +use Carbon\Carbon; +use FireflyIII\Jobs\CreateRecurringTransactions; +use FireflyIII\Models\RecurrenceRepetition; +use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; +use Log; /** * File to make sure commnds work. @@ -58,7 +63,43 @@ class Kernel extends ConsoleKernel * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - protected function schedule(Schedule $schedule) + protected function schedule(Schedule $schedule): void { + $schedule->call( + function () { + // run for the entirety of 2018, just to see what happens + $start = new Carbon('2018-01-01'); + $end = new Carbon('2018-12-31'); + while ($start <= $end) { + Log::info(sprintf('Now at %s', $start->format('D Y-m-d'))); + $job = new CreateRecurringTransactions(clone $start); + $job->handle(); + $start->addDay(); + } + + } + )->everyMinute(); + + //$schedule->job(new CreateRecurringTransactions(new Carbon))->everyMinute(); + + //$schedule->job(new CreateRecurringTransactions(new Carbon))->everyMinute(); + + + // $schedule->call( + // function () { + // // command to do something + // Log::debug('Schedule creation of transactions yaay!'); + // } + // )->daily(); + // + // $schedule->call( + // function () { + // // command to do something + // Log::debug('Every minute!'); + // } + // )->everyMinute() + // ->emailOutputTo('thege'); + + } } diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php index d27b438f1c..e81c50c087 100644 --- a/app/Factory/TransactionJournalFactory.php +++ b/app/Factory/TransactionJournalFactory.php @@ -26,7 +26,6 @@ namespace FireflyIII\Factory; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\TransactionJournal; -use FireflyIII\Models\TransactionType; use FireflyIII\Services\Internal\Support\JournalServiceTrait; use FireflyIII\Services\Internal\Support\TransactionTypeTrait; use FireflyIII\User; @@ -100,7 +99,8 @@ class TransactionJournalFactory // store date meta fields (if present): $fields = ['sepa-cc', 'sepa-ct-op', 'sepa-ct-id', 'sepa-db', 'sepa-country', 'sepa-ep', 'sepa-ci', 'interest_date', 'book_date', 'process_date', - 'due_date', 'payment_date', 'invoice_date', 'internal_reference', 'bunq_payment_id', 'importHash', 'importHashV2', 'external_id']; + 'due_date', 'recurrence_id', 'payment_date', 'invoice_date', 'internal_reference', 'bunq_payment_id', 'importHash', 'importHashV2', + 'external_id']; foreach ($fields as $field) { $this->storeMeta($journal, $data, $field); diff --git a/app/Http/Controllers/Recurring/EditController.php b/app/Http/Controllers/Recurring/EditController.php index 803ed91e62..1107e93505 100644 --- a/app/Http/Controllers/Recurring/EditController.php +++ b/app/Http/Controllers/Recurring/EditController.php @@ -76,6 +76,8 @@ class EditController extends Controller */ public function edit(Request $request, Recurrence $recurrence) { + + // use transformer: $transformer = new RecurrenceTransformer(new ParameterBag); $array = $transformer->transform($recurrence); @@ -86,6 +88,7 @@ class EditController extends Controller // todo handle old repetition type as well. + /** @var RecurrenceRepetition $repetition */ $repetition = $recurrence->recurrenceRepetitions()->first(); $currentRepetitionType = $repetition->repetition_type; @@ -116,13 +119,12 @@ class EditController extends Controller // code to handle active-checkboxes $hasOldInput = null !== $request->old('_token'); + // $hasOldInput = false; $preFilled = [ 'transaction_type' => strtolower($recurrence->transactionType->type), 'active' => $hasOldInput ? (bool)$request->old('active') : $recurrence->active, 'apply_rules' => $hasOldInput ? (bool)$request->old('apply_rules') : $recurrence->apply_rules, ]; - $request->flash('preFilled', $preFilled); - return view('recurring.edit', compact('recurrence', 'array', 'budgets', 'preFilled', 'currentRepetitionType', 'repetitionEnd', 'repetitionEnds')); } diff --git a/app/Http/Controllers/Recurring/IndexController.php b/app/Http/Controllers/Recurring/IndexController.php index 1457ab4adc..b7e2884a58 100644 --- a/app/Http/Controllers/Recurring/IndexController.php +++ b/app/Http/Controllers/Recurring/IndexController.php @@ -159,7 +159,7 @@ class IndexController extends Controller { $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page'); $pageSize = (int)app('preferences')->get('listPageSize', 50)->data; - $collection = $this->recurring->getActive(); + $collection = $this->recurring->get(); // TODO: split collection into pages diff --git a/app/Jobs/CreateRecurringTransactions.php b/app/Jobs/CreateRecurringTransactions.php new file mode 100644 index 0000000000..c40ca144b0 --- /dev/null +++ b/app/Jobs/CreateRecurringTransactions.php @@ -0,0 +1,321 @@ +startOfDay(); + $this->date = $date; + $this->repository = app(RecurringRepositoryInterface::class); + $this->journalRepository = app(JournalRepositoryInterface::class); + } + + /** + * Execute the job. + * + * TODO check number of repetitions. + * + * @throws \FireflyIII\Exceptions\FireflyException + */ + public function handle(): void + { + Log::debug('Now at start of CreateRecurringTransactions() job.'); + $recurrences = $this->repository->getAll(); + Log::debug(sprintf('Count of collection is %d', $recurrences->count())); + + /** @var Collection $filtered */ + $filtered = $recurrences->filter( + function (Recurrence $recurrence) { + return $this->validRecurrence($recurrence); + + } + ); + Log::debug(sprintf('Left after filtering is %d', $filtered->count())); + /** @var Recurrence $recurrence */ + foreach ($filtered as $recurrence) { + $this->repository->setUser($recurrence->user); + $this->journalRepository->setUser($recurrence->user); + Log::debug(sprintf('Now at recurrence #%d', $recurrence->id)); + $this->handleRepetitions($recurrence); + Log::debug(sprintf('Done with recurrence #%c', $recurrence->id)); + } + Log::debug('Done with handle()'); + } + + /** + * Return recurring transaction is active. + * + * @param Recurrence $recurrence + * + * @return bool + */ + private function active(Recurrence $recurrence): bool + { + return $recurrence->active; + } + + /** + * @param array $occurrences + * + * @return array + */ + private function debugArray(array $occurrences): array + { + $return = []; + foreach ($occurrences as $entry) { + $return[] = $entry->format('Y-m-d'); + } + + return $return; + } + + /** + * @param Recurrence $recurrence + * + * @return Carbon + */ + private function getStartDate(Recurrence $recurrence): Carbon + { + $startDate = clone $recurrence->first_date; + if (null !== $recurrence->latest_date && $recurrence->latest_date->gte($startDate)) { + $startDate = clone $recurrence->latest_date; + // jump to a day later. + $startDate->addDay(); + + } + + return $startDate; + } + + /** + * @param Recurrence $recurrence + * + * @return array + */ + private function getTransactionData(Recurrence $recurrence): array + { + $transactions = $recurrence->recurrenceTransactions()->get(); + $return = []; + /** @var RecurrenceTransaction $transaction */ + foreach ($transactions as $index => $transaction) { + $single = [ + 'currency_id' => $transaction->transaction_currency_id, + 'currency_code' => null, + 'description' => null, + 'amount' => $transaction->amount, + 'budget_id' => $this->repository->getBudget($transaction), + 'budget_name' => null, + 'category_id' => null, + 'category_name' => $this->repository->getCategory($transaction), + 'source_id' => $transaction->source_account_id, + 'source_name' => null, + 'destination_id' => $transaction->destination_account_id, + 'destination_name' => null, + 'foreign_currency_id' => $transaction->foreign_currency_id, + 'foreign_currency_code' => null, + 'foreign_amount' => $transaction->foreign_amount, + 'reconciled' => false, + 'identifier' => $index, + ]; + $return[] = $single; + } + + return $return; + } + + /** + * @param Recurrence $recurrence + * @param array $occurrences + * + * @throws \FireflyIII\Exceptions\FireflyException + */ + private function handleOccurrences(Recurrence $recurrence, array $occurrences): void + { + /** @var Carbon $date */ + foreach ($occurrences as $date) { + Log::debug(sprintf('Now at date %s.', $date->format('Y-m-d'))); + if ($date->ne($this->date)) { + Log::debug(sprintf('%s is not not today (%s)', $date->format('Y-m-d'), $this->date->format('Y-m-d'))); + + continue; + } + Log::debug(sprintf('%s IS today (%s)', $date->format('Y-m-d'), $this->date->format('Y-m-d'))); + + // create transaction array and send to factory. + $array = [ + 'type' => $recurrence->transactionType->type, + 'date' => $date, + 'tags' => $this->repository->getTags($recurrence), + 'user' => $recurrence->user_id, + 'notes' => trans('firefly.created_from_recurrence', ['id' => $recurrence->id, 'title' => $recurrence->title]), + + // journal data: + 'description' => $recurrence->recurrenceTransactions()->first()->description, + 'piggy_bank_id' => null, + 'piggy_bank_name' => null, + 'bill_id' => null, + 'bill_name' => null, + 'recurrence_id' => $recurrence->id, + + // transaction data: + 'transactions' => $this->getTransactionData($recurrence), + ]; + $journal = $this->journalRepository->store($array); + Log::info(sprintf('Created new journal #%d', $journal->id)); + // update recurring thing: + $recurrence->latest_date = $date; + $recurrence->save(); + } + } + + /** + * Separate method that will loop all repetitions and do something with it: + * + * @param Recurrence $recurrence + * + * @throws \FireflyIII\Exceptions\FireflyException + */ + private function handleRepetitions(Recurrence $recurrence): void + { + /** @var RecurrenceRepetition $repetition */ + foreach ($recurrence->recurrenceRepetitions as $repetition) { + Log::debug( + sprintf( + 'Now repeating %s with value "%s", skips every %d time(s)', $repetition->repetition_type, $repetition->repetition_moment, + $repetition->repetition_skip + ) + ); + + // start looping from $startDate to today perhaps we have a hit? + $occurrences = $this->repository->getOccurrencesInRange($repetition, $recurrence->first_date, $this->date); + Log::debug( + sprintf( + 'Calculated %d occurrences between %s and %s', \count($occurrences), $recurrence->first_date->format('Y-m-d'), $this->date->format('Y-m-d') + ), $this->debugArray($occurrences) + ); + + $this->handleOccurrences($recurrence, $occurrences); + } + } + + /** + * @param Recurrence $recurrence + * + * @return bool + */ + private function hasFiredToday(Recurrence $recurrence): bool + { + return null !== $recurrence->latest_date && $recurrence->latest_date->eq($this->date); + } + + /** + * @param $recurrence + * + * @return bool + */ + private function hasNotStartedYet(Recurrence $recurrence): bool + { + $startDate = $this->getStartDate($recurrence); + + return $startDate->gt($this->date); + } + + /** + * Return true if the $repeat_until date is in the past. + * + * @param Recurrence $recurrence + * + * @return bool + */ + private function repeatUntilHasPassed(Recurrence $recurrence): bool + { + // date has passed + return null !== $recurrence->repeat_until && $recurrence->repeat_until->lt($this->date); + } + + /** + * @param Recurrence $recurrence + * + * @return bool + */ + private function validRecurrence(Recurrence $recurrence): bool + { + // is not active. + if (!$this->active($recurrence)) { + Log::info(sprintf('Recurrence #%d is not active. Skipped.', $recurrence->id)); + + return false; + } + + // is no longer running + if ($this->repeatUntilHasPassed($recurrence)) { + Log::info( + sprintf( + 'Recurrence #%d was set to run until %s, and today\'s date is %s. Skipped.', + $recurrence->id, + $recurrence->repeat_until->format('Y-m-d'), + $this->date->format('Y-m-d') + ) + ); + + return false; + } + + // first_date is in the future + if ($this->hasNotStartedYet($recurrence)) { + Log::info( + sprintf( + 'Recurrence #%d is set to run on %s, and today\'s date is %s. Skipped.', + $recurrence->id, + $recurrence->first_date->format('Y-m-d'), + $this->date->format('Y-m-d') + ) + ); + + return false; + } + + // already fired today (with success): + if ($this->hasFiredToday($recurrence)) { + Log::info(sprintf('Recurrence #%d has already fired today. Skipped.', $recurrence->id)); + + return false; + } + + return true; + + } +} diff --git a/app/Repositories/Recurring/RecurringRepository.php b/app/Repositories/Recurring/RecurringRepository.php index 3dccd78f6e..01aa7ca230 100644 --- a/app/Repositories/Recurring/RecurringRepository.php +++ b/app/Repositories/Recurring/RecurringRepository.php @@ -29,11 +29,14 @@ use FireflyIII\Factory\RecurrenceFactory; use FireflyIII\Models\Note; use FireflyIII\Models\Preference; use FireflyIII\Models\Recurrence; +use FireflyIII\Models\RecurrenceMeta; use FireflyIII\Models\RecurrenceRepetition; +use FireflyIII\Models\RecurrenceTransaction; +use FireflyIII\Models\RecurrenceTransactionMeta; use FireflyIII\Services\Internal\Update\RecurrenceUpdateService; use FireflyIII\User; use Illuminate\Support\Collection; - +use Log; /** * @@ -49,11 +52,68 @@ class RecurringRepository implements RecurringRepositoryInterface * * @return Collection */ - public function getActive(): Collection + public function get(): Collection { - return $this->user->recurrences()->with(['TransactionCurrency', 'TransactionType', 'RecurrenceRepetitions', 'RecurrenceTransactions'])->where( - 'active', 1 - )->get(); + return $this->user->recurrences() + ->with(['TransactionCurrency', 'TransactionType', 'RecurrenceRepetitions', 'RecurrenceTransactions']) + ->orderBy('active', 'DESC') + ->orderBy('title', 'ASC') + ->get(); + } + + /** + * Get ALL recurring transactions. + * + * @return Collection + */ + public function getAll(): Collection + { + // grab ALL recurring transactions: + return Recurrence + ::with(['TransactionCurrency', 'TransactionType', 'RecurrenceRepetitions', 'RecurrenceTransactions']) + ->orderBy('active', 'DESC') + ->orderBy('title', 'ASC') + ->get(); + } + + /** + * Get the budget ID from a recurring transaction transaction. + * + * @param RecurrenceTransaction $recurrenceTransaction + * + * @return null|int + */ + public function getBudget(RecurrenceTransaction $recurrenceTransaction): ?int + { + $return = 0; + /** @var RecurrenceTransactionMeta $meta */ + foreach ($recurrenceTransaction->recurrenceTransactionMeta as $meta) { + if ($meta->name === 'budget_id') { + $return = (int)$meta->value; + } + } + + return $return === 0 ? null : $return; + } + + /** + * Get the category from a recurring transaction transaction. + * + * @param RecurrenceTransaction $recurrenceTransaction + * + * @return null|string + */ + public function getCategory(RecurrenceTransaction $recurrenceTransaction): ?string + { + $return = ''; + /** @var RecurrenceTransactionMeta $meta */ + foreach ($recurrenceTransaction->recurrenceTransactionMeta as $meta) { + if ($meta->name === 'category_name') { + $return = (string)$meta->value; + } + } + + return $return === '' ? null : $return; } /** @@ -92,6 +152,7 @@ class RecurringRepository implements RecurringRepositoryInterface $mutator->startOfDay(); $skipMod = $repetition->repetition_skip + 1; $attempts = 0; + Log::debug(sprintf('Calculating occurrences for rep type "%s"', $repetition->repetition_type)); switch ($repetition->repetition_type) { default: throw new FireflyException( @@ -120,7 +181,7 @@ class RecurringRepository implements RecurringRepositoryInterface $dayDifference = $dayOfWeek - $mutator->dayOfWeekIso; $mutator->addDays($dayDifference); while ($mutator <= $end) { - if ($attempts % $skipMod === 0) { + if ($attempts % $skipMod === 0 && $start->lte($mutator) && $end->gte($mutator)) { $return[] = clone $mutator; } $attempts++; @@ -129,19 +190,31 @@ class RecurringRepository implements RecurringRepositoryInterface break; case 'monthly': $dayOfMonth = (int)$repetition->repetition_moment; + Log::debug(sprintf('Day of month in repetition is %d', $dayOfMonth)); + Log::debug(sprintf('Start is %s.', $start->format('Y-m-d'))); + Log::debug(sprintf('End is %s.', $end->format('Y-m-d'))); if ($mutator->day > $dayOfMonth) { + Log::debug('Add a month.'); // day has passed already, add a month. $mutator->addMonth(); } - + Log::debug(sprintf('Start is now %s.', $mutator->format('Y-m-d'))); + Log::debug('Start loop.'); while ($mutator < $end) { + Log::debug(sprintf('Mutator is now %s.', $mutator->format('Y-m-d'))); $domCorrected = min($dayOfMonth, $mutator->daysInMonth); + Log::debug(sprintf('DoM corrected is %d', $domCorrected)); $mutator->day = $domCorrected; - if ($attempts % $skipMod === 0) { + Log::debug(sprintf('Mutator is now %s.', $mutator->format('Y-m-d'))); + Log::debug(sprintf('$attempts %% $skipMod === 0 is %s', var_export($attempts % $skipMod === 0, true))); + Log::debug(sprintf('$start->lte($mutator) is %s', var_export($start->lte($mutator), true))); + Log::debug(sprintf('$end->gte($mutator) is %s', var_export($end->gte($mutator), true))); + if ($attempts % $skipMod === 0 && $start->lte($mutator) && $end->gte($mutator)) { + Log::debug(sprintf('ADD %s to return!', $mutator->format('Y-m-d'))); $return[] = clone $mutator; } $attempts++; - $mutator->endOfMonth()->addDay(); + $mutator->endOfMonth()->startOfDay()->addDay(); } break; case 'ndom': @@ -180,6 +253,26 @@ class RecurringRepository implements RecurringRepositoryInterface return $return; } + /** + * Get the tags from the recurring transaction. + * + * @param Recurrence $recurrence + * + * @return array + */ + public function getTags(Recurrence $recurrence): array + { + $tags = []; + /** @var RecurrenceMeta $meta */ + foreach ($recurrence->recurrenceMeta as $meta) { + if ($meta->name === 'tags' && '' !== $meta->value) { + $tags = explode(',', $meta->value); + } + } + + return $tags; + } + /** * Calculate the next X iterations starting on the date given in $date. * @@ -377,6 +470,7 @@ class RecurringRepository implements RecurringRepositoryInterface * @param array $data * * @return Recurrence + * @throws FireflyException */ public function update(Recurrence $recurrence, array $data): Recurrence { diff --git a/app/Repositories/Recurring/RecurringRepositoryInterface.php b/app/Repositories/Recurring/RecurringRepositoryInterface.php index 53f9b63517..0f1776a085 100644 --- a/app/Repositories/Recurring/RecurringRepositoryInterface.php +++ b/app/Repositories/Recurring/RecurringRepositoryInterface.php @@ -27,6 +27,7 @@ use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Recurrence; use FireflyIII\Models\RecurrenceRepetition; +use FireflyIII\Models\RecurrenceTransaction; use FireflyIII\User; use Illuminate\Support\Collection; @@ -43,7 +44,31 @@ interface RecurringRepositoryInterface * * @return Collection */ - public function getActive(): Collection; + public function get(): Collection; + + /** + * Get ALL recurring transactions. + * @return Collection + */ + public function getAll(): Collection; + + /** + * Get the category from a recurring transaction transaction. + * + * @param RecurrenceTransaction $recurrenceTransaction + * + * @return null|string + */ + public function getCategory(RecurrenceTransaction $recurrenceTransaction): ?string; + + /** + * Get the budget ID from a recurring transaction transaction. + * + * @param RecurrenceTransaction $recurrenceTransaction + * + * @return null|int + */ + public function getBudget(RecurrenceTransaction $recurrenceTransaction): ?int; /** * Get the notes. @@ -67,6 +92,15 @@ interface RecurringRepositoryInterface */ public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array; + /** + * Get the tags from the recurring transaction. + * + * @param Recurrence $recurrence + * + * @return array + */ + public function getTags(Recurrence $recurrence): array; + /** * Calculate the next X iterations starting on the date given in $date. * Returns an array of Carbon objects. @@ -98,6 +132,7 @@ interface RecurringRepositoryInterface /** * Store a new recurring transaction. + *\ * * @param array $data * diff --git a/app/Support/ExpandedForm.php b/app/Support/ExpandedForm.php index d111940c02..a5c5ee8a3f 100644 --- a/app/Support/ExpandedForm.php +++ b/app/Support/ExpandedForm.php @@ -515,16 +515,7 @@ class ExpandedForm */ public function optionsList(string $type, string $name): string { - $previousValue = null; - - try { - $previousValue = request()->old('post_submit_action'); - } catch (RuntimeException $e) { - // don't care - } - - $previousValue = $previousValue ?? 'store'; - $html = view('form.options', compact('type', 'name', 'previousValue'))->render(); + $html = view('form.options', compact('type', 'name'))->render(); return $html; } diff --git a/composer.lock b/composer.lock index 09497bc119..ca02e5a1b9 100644 --- a/composer.lock +++ b/composer.lock @@ -1150,16 +1150,16 @@ }, { "name": "laravel/framework", - "version": "v5.6.24", + "version": "v5.6.25", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "56290edeb0d8051826d40b4cbd8ed3c30348b2b5" + "reference": "a15efe4fbcd6b38ea76edc5c8939ffde4f4c7b7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/56290edeb0d8051826d40b4cbd8ed3c30348b2b5", - "reference": "56290edeb0d8051826d40b4cbd8ed3c30348b2b5", + "url": "https://api.github.com/repos/laravel/framework/zipball/a15efe4fbcd6b38ea76edc5c8939ffde4f4c7b7f", + "reference": "a15efe4fbcd6b38ea76edc5c8939ffde4f4c7b7f", "shasum": "" }, "require": { @@ -1285,7 +1285,7 @@ "framework", "laravel" ], - "time": "2018-06-04T14:51:03+00:00" + "time": "2018-06-12T14:39:24+00:00" }, { "name": "laravel/passport", @@ -4457,16 +4457,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.8.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6" + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/478465659fd987669df0bd8a9bf22a8710e5f1b6", - "reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", "shasum": "" }, "require": { @@ -4501,7 +4501,7 @@ "object", "object graph" ], - "time": "2018-05-29T17:25:09+00:00" + "time": "2018-06-11T23:09:50+00:00" }, { "name": "phar-io/manifest", @@ -4968,16 +4968,16 @@ }, { "name": "phpunit/php-file-iterator", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "e20525b0c2945c7c317fff95660698cb3d2a53bc" + "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/e20525b0c2945c7c317fff95660698cb3d2a53bc", - "reference": "e20525b0c2945c7c317fff95660698cb3d2a53bc", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c", + "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c", "shasum": "" }, "require": { @@ -5011,7 +5011,7 @@ "filesystem", "iterator" ], - "time": "2018-05-28T12:13:49+00:00" + "time": "2018-06-11T11:44:00+00:00" }, { "name": "phpunit/php-text-template", @@ -5450,16 +5450,16 @@ }, { "name": "sebastian/comparator", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5" + "reference": "591a30922f54656695e59b1f39501aec513403da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ed5fd2281113729f1ebcc64d101ad66028aeb3d5", - "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/591a30922f54656695e59b1f39501aec513403da", + "reference": "591a30922f54656695e59b1f39501aec513403da", "shasum": "" }, "require": { @@ -5510,20 +5510,20 @@ "compare", "equality" ], - "time": "2018-04-18T13:33:00+00:00" + "time": "2018-06-14T15:05:28+00:00" }, { "name": "sebastian/diff", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8" + "reference": "366541b989927187c4ca70490a35615d3fef2dce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8", - "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", + "reference": "366541b989927187c4ca70490a35615d3fef2dce", "shasum": "" }, "require": { @@ -5566,7 +5566,7 @@ "unidiff", "unified diff" ], - "time": "2018-02-01T13:45:15+00:00" + "time": "2018-06-10T07:54:39+00:00" }, { "name": "sebastian/environment", diff --git a/public/js/ff/recurring/edit.js b/public/js/ff/recurring/edit.js index 7961af13d0..a2aad13572 100644 --- a/public/js/ff/recurring/edit.js +++ b/public/js/ff/recurring/edit.js @@ -100,11 +100,19 @@ function respondToRepetitionEnd() { } function respondToFirstDateChange() { + // var obj = $('#ffInput_first_date'); var select = $('#ffInput_repetition_type'); var date = obj.val(); select.prop('disabled', true); - $.getJSON(suggestUri, {date: date,past:true}).fail(function () { + + // preselected value: + var preSelected = currentRepetitionType; + if(preSelected === '') { + preSelected = select.val(); + } + + $.getJSON(suggestUri, {date: date,pre_select: preSelected,past:true}).fail(function () { console.error('Could not load repetition suggestions'); alert('Could not load repetition suggestions'); }).done(parseRepetitionSuggestions); @@ -117,8 +125,9 @@ function parseRepetitionSuggestions(data) { var opt; for (var k in data) { if (data.hasOwnProperty(k)) { - opt = $('