mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Extra content to fix recurrences.
This commit is contained in:
parent
8d84dfb3aa
commit
1783f0beb1
@ -80,6 +80,7 @@ class RecurrenceFactory
|
|||||||
$description = '';
|
$description = '';
|
||||||
$applyRules = true;
|
$applyRules = true;
|
||||||
$active = true;
|
$active = true;
|
||||||
|
$repeatUntilString = null;
|
||||||
if (array_key_exists('first_date', $data['recurrence'])) {
|
if (array_key_exists('first_date', $data['recurrence'])) {
|
||||||
/** @var Carbon $firstDate */
|
/** @var Carbon $firstDate */
|
||||||
$firstDate = $data['recurrence']['first_date'];
|
$firstDate = $data['recurrence']['first_date'];
|
||||||
@ -102,8 +103,8 @@ class RecurrenceFactory
|
|||||||
if (array_key_exists('active', $data['recurrence'])) {
|
if (array_key_exists('active', $data['recurrence'])) {
|
||||||
$active = $data['recurrence']['active'];
|
$active = $data['recurrence']['active'];
|
||||||
}
|
}
|
||||||
if ($repetitions > 0 && null === $repeatUntil) {
|
if (null !== $repeatUntil) {
|
||||||
$repeatUntil = Carbon::create()->addyear();
|
$repeatUntilString = $repeatUntil->format('Y-m-d');
|
||||||
}
|
}
|
||||||
|
|
||||||
$recurrence = new Recurrence(
|
$recurrence = new Recurrence(
|
||||||
@ -113,7 +114,7 @@ class RecurrenceFactory
|
|||||||
'title' => $title,
|
'title' => $title,
|
||||||
'description' => $description,
|
'description' => $description,
|
||||||
'first_date' => $firstDate ? $firstDate->format('Y-m-d') : null,
|
'first_date' => $firstDate ? $firstDate->format('Y-m-d') : null,
|
||||||
'repeat_until' => $repetitions > 0 ? null : $repeatUntil->format('Y-m-d'),
|
'repeat_until' => $repetitions > 0 ? null : $repeatUntilString,
|
||||||
'latest_date' => null,
|
'latest_date' => null,
|
||||||
'repetitions' => $repetitions,
|
'repetitions' => $repetitions,
|
||||||
'apply_rules' => $applyRules,
|
'apply_rules' => $applyRules,
|
||||||
|
@ -25,6 +25,7 @@ namespace FireflyIII\Http\Requests;
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
|
use FireflyIII\Factory\CategoryFactory;
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
use FireflyIII\Rules\ValidRecurrenceRepetitionType;
|
use FireflyIII\Rules\ValidRecurrenceRepetitionType;
|
||||||
@ -123,6 +124,19 @@ class RecurrenceFormRequest extends FormRequest
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// replace category name with a new category:
|
||||||
|
$factory = app(CategoryFactory::class);
|
||||||
|
$factory->setUser(auth()->user());
|
||||||
|
foreach($return['transactions'] as $index => $transaction) {
|
||||||
|
$categoryName =$transaction['category_name'] ??null;
|
||||||
|
if(null !== $categoryName) {
|
||||||
|
$category = $factory->findOrCreate(null, $categoryName);
|
||||||
|
if(null !== $category) {
|
||||||
|
$return['transactions'][$index]['category_id'] = $category->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,9 @@ trait RecurringTransactionTrait
|
|||||||
if (!$validator->validateDestination($destination->id, null, null)) {
|
if (!$validator->validateDestination($destination->id, null, null)) {
|
||||||
throw new FireflyException(sprintf('Destination invalid: %s', $validator->destError)); // @codeCoverageIgnore
|
throw new FireflyException(sprintf('Destination invalid: %s', $validator->destError)); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
if(array_key_exists('foreign_amount', $array) && '' === (string)$array['foreign_amount']) {
|
||||||
|
unset($array['foreign_amount']);
|
||||||
|
}
|
||||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
||||||
$transaction = new RecurrenceTransaction(
|
$transaction = new RecurrenceTransaction(
|
||||||
[
|
[
|
||||||
|
@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Models\Note;
|
use FireflyIII\Models\Note;
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\RecurrenceRepetition;
|
use FireflyIII\Models\RecurrenceRepetition;
|
||||||
|
use FireflyIII\Models\RecurrenceTransaction;
|
||||||
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
||||||
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
@ -103,15 +104,73 @@ class RecurrenceUpdateService
|
|||||||
// update all transactions:
|
// update all transactions:
|
||||||
|
|
||||||
|
|
||||||
// // update all transactions (and associated meta-data)
|
// update all transactions (and associated meta-data)
|
||||||
// if (array_key_exists('transactions', $data)) {
|
if (array_key_exists('transactions', $data)) {
|
||||||
// $this->deleteTransactions($recurrence);
|
$this->updateTransactions($recurrence, $data['transactions'] ?? []);
|
||||||
// $this->createTransactions($recurrence, $data['transactions'] ?? []);
|
// $this->deleteTransactions($recurrence);
|
||||||
// }
|
// $this->createTransactions($recurrence, $data['transactions'] ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
return $recurrence;
|
return $recurrence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO this method is way too complex.
|
||||||
|
*
|
||||||
|
* @param Recurrence $recurrence
|
||||||
|
* @param array $transactions
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
*/
|
||||||
|
private function updateTransactions(Recurrence $recurrence, array $transactions): void
|
||||||
|
{
|
||||||
|
$originalCount = $recurrence->recurrenceTransactions()->count();
|
||||||
|
if (0 === count($transactions)) {
|
||||||
|
// wont drop transactions, rather avoid.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// user added or removed repetitions, delete all and recreate:
|
||||||
|
if ($originalCount !== count($transactions)) {
|
||||||
|
Log::debug('Del + recreate');
|
||||||
|
$this->deleteTransactions($recurrence);
|
||||||
|
$this->createTransactions($recurrence, $transactions);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// loop all and try to match them:
|
||||||
|
if ($originalCount === count($transactions)) {
|
||||||
|
Log::debug('Loop and find');
|
||||||
|
foreach ($transactions as $current) {
|
||||||
|
$match = $this->matchTransaction($recurrence, $current);
|
||||||
|
if (null === $match) {
|
||||||
|
throw new FireflyException('Cannot match recurring transaction to existing transaction. Not sure what to do. Break.');
|
||||||
|
}
|
||||||
|
// TODO find currency
|
||||||
|
// TODO find foreign currency
|
||||||
|
|
||||||
|
// update fields
|
||||||
|
$fields = [
|
||||||
|
'source_id' => 'source_id',
|
||||||
|
'destination_id' => 'destination_id',
|
||||||
|
'amount' => 'amount',
|
||||||
|
'foreign_amount' => 'foreign_amount',
|
||||||
|
'description' => 'description',
|
||||||
|
];
|
||||||
|
foreach ($fields as $field => $column) {
|
||||||
|
if (array_key_exists($field, $current)) {
|
||||||
|
$match->$column = $current[$field];
|
||||||
|
$match->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update meta data
|
||||||
|
// budget_id
|
||||||
|
// category_id
|
||||||
|
// tags
|
||||||
|
// piggy_bank_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Recurrence $recurrence
|
* @param Recurrence $recurrence
|
||||||
* @param string $text
|
* @param string $text
|
||||||
@ -172,7 +231,7 @@ class RecurrenceUpdateService
|
|||||||
'moment' => 'repetition_moment',
|
'moment' => 'repetition_moment',
|
||||||
'skip' => 'repetition_skip',
|
'skip' => 'repetition_skip',
|
||||||
'weekend' => 'weekend',
|
'weekend' => 'weekend',
|
||||||
];
|
];
|
||||||
foreach ($fields as $field => $column) {
|
foreach ($fields as $field => $column) {
|
||||||
if (array_key_exists($field, $current)) {
|
if (array_key_exists($field, $current)) {
|
||||||
$match->$column = $current[$field];
|
$match->$column = $current[$field];
|
||||||
@ -193,6 +252,7 @@ class RecurrenceUpdateService
|
|||||||
$originalCount = $recurrence->recurrenceRepetitions()->count();
|
$originalCount = $recurrence->recurrenceRepetitions()->count();
|
||||||
if (1 === $originalCount) {
|
if (1 === $originalCount) {
|
||||||
Log::debug('Return the first one');
|
Log::debug('Return the first one');
|
||||||
|
|
||||||
return $recurrence->recurrenceRepetitions()->first();
|
return $recurrence->recurrenceRepetitions()->first();
|
||||||
}
|
}
|
||||||
// find it:
|
// find it:
|
||||||
@ -211,4 +271,38 @@ class RecurrenceUpdateService
|
|||||||
|
|
||||||
return $query->first();
|
return $query->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return RecurrenceTransaction|null
|
||||||
|
*/
|
||||||
|
private function matchTransaction(Recurrence $recurrence, array $data): ?RecurrenceTransaction
|
||||||
|
{
|
||||||
|
$originalCount = $recurrence->recurrenceTransactions()->count();
|
||||||
|
if (1 === $originalCount) {
|
||||||
|
Log::debug('Return the first one');
|
||||||
|
|
||||||
|
return $recurrence->recurrenceTransactions()->first();
|
||||||
|
}
|
||||||
|
// find it based on data
|
||||||
|
$fields = [
|
||||||
|
'id' => 'id',
|
||||||
|
'currency_id' => 'transaction_currency_id',
|
||||||
|
'foreign_currency_id' => 'foreign_currency_id',
|
||||||
|
'source_id' => 'source_id',
|
||||||
|
'destination_id' => 'destination_id',
|
||||||
|
'amount' => 'amount',
|
||||||
|
'foreign_amount' => 'foreign_amount',
|
||||||
|
'description' => 'description',
|
||||||
|
];
|
||||||
|
$query = $recurrence->recurrenceTransactions();
|
||||||
|
foreach ($fields as $field => $column) {
|
||||||
|
if (array_key_exists($field, $data)) {
|
||||||
|
$query->where($column, $data[$field]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->first();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,29 +212,26 @@ class UpdateControllerTest extends TestCase
|
|||||||
// now loop fields, enough to create sets I guess?
|
// now loop fields, enough to create sets I guess?
|
||||||
// TODO maybe do some permutation stuff here?
|
// TODO maybe do some permutation stuff here?
|
||||||
$extraTransaction = [
|
$extraTransaction = [
|
||||||
'description' => $faker->uuid,
|
'currency_id' => $faker->numberBetween(1, 4),
|
||||||
'amount' => number_format($faker->randomFloat(2, 10, 100), 2),
|
'foreign_currency_id' => $faker->numberBetween(4, 6),
|
||||||
'skip' => $faker->numberBetween(1, 3),
|
'source_id' => $faker->numberBetween(1, 3),
|
||||||
'weekend' => $faker->numberBetween(1, 4),
|
'destination_id' => $faker->numberBetween(8),
|
||||||
'budget_id' => $faker->numberBetween(1, 2),
|
'amount' => number_format($faker->randomFloat(2, 10, 100), 2),
|
||||||
'category_id' => $faker->numberBetween(1, 2),
|
'foreign_amount' => number_format($faker->randomFloat(2, 10, 100), 2),
|
||||||
'tags' => ['a', 'c', 'd'],
|
'description' => $faker->uuid,
|
||||||
'source_id' => 1,
|
|
||||||
'destination_id' => 8,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$extraTransactions[] = $extraTransaction;
|
$extraTransactions[] = $extraTransaction;
|
||||||
}
|
}
|
||||||
// TODO later maybe
|
$set[] = [
|
||||||
// $set[] = [
|
'id' => 1,
|
||||||
// 'id' => 1,
|
'fields' => [
|
||||||
// 'fields' => [
|
'transactions' => [
|
||||||
// 'transactions' => [
|
'test_value' => $extraTransactions,
|
||||||
// 'test_value' => $extraTransactions,
|
],
|
||||||
// ],
|
],
|
||||||
// ],
|
'extra_ignore' => [],
|
||||||
// 'extra_ignore' => [],
|
];
|
||||||
// ];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $set;
|
return $set;
|
||||||
|
Loading…
Reference in New Issue
Block a user