diff --git a/app/Factory/TransactionFactory.php b/app/Factory/TransactionFactory.php index 6cc1c79719..f62147d3cb 100644 --- a/app/Factory/TransactionFactory.php +++ b/app/Factory/TransactionFactory.php @@ -25,15 +25,9 @@ namespace FireflyIII\Factory; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\Budget; -use FireflyIII\Models\Category; use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; -use FireflyIII\Models\TransactionType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Services\Internal\Support\TransactionServiceTrait; use FireflyIII\User; use Illuminate\Support\Collection; @@ -42,19 +36,11 @@ use Illuminate\Support\Collection; */ class TransactionFactory { - /** @var AccountRepositoryInterface */ - private $accountRepository; + use TransactionServiceTrait; + /** @var User */ private $user; - /** - * TransactionFactory constructor. - */ - public function __construct() - { - $this->accountRepository = app(AccountRepositoryInterface::class); - } - /** * @param array $data * @@ -87,6 +73,7 @@ class TransactionFactory * * @return Collection * @throws FireflyException + * @throws \Exception */ public function createPair(TransactionJournal $journal, array $data): Collection { @@ -158,198 +145,7 @@ class TransactionFactory public function setUser(User $user) { $this->user = $user; - $this->accountRepository->setUser($user); } - /** - * @param TransactionJournal $journal - * @param string $direction - * - * @return string - * @throws FireflyException - */ - protected function accountType(TransactionJournal $journal, string $direction): string - { - $types = []; - $type = $journal->transactionType->type; - switch ($type) { - default: - throw new FireflyException(sprintf('Cannot handle type "%s" in accountType()', $type)); - case TransactionType::WITHDRAWAL: - $types['source'] = AccountType::ASSET; - $types['destination'] = AccountType::EXPENSE; - break; - case TransactionType::DEPOSIT: - $types['source'] = AccountType::REVENUE; - $types['destination'] = AccountType::ASSET; - break; - case TransactionType::TRANSFER: - $types['source'] = AccountType::ASSET; - $types['destination'] = AccountType::ASSET; - break; - } - if (!isset($types[$direction])) { - throw new FireflyException(sprintf('No type set for direction "%s" and type "%s"', $type, $direction)); - } - return $types[$direction]; - } - - /** - * @param string $expectedType - * @param int|null $accountId - * @param string|null $accountName - * - * @return Account - * @throws FireflyException - */ - protected function findAccount(string $expectedType, ?int $accountId, ?string $accountName): Account - { - $accountId = intval($accountId); - $accountName = strval($accountName); - - switch ($expectedType) { - case AccountType::ASSET: - if ($accountId > 0) { - // must be able to find it based on ID. Validator should catch invalid ID's. - return $this->accountRepository->findNull($accountId); - } - - // alternatively, return by name. Validator should catch invalid names. - return $this->accountRepository->findByName($accountName, [AccountType::ASSET]); - break; - case AccountType::EXPENSE: - if ($accountId > 0) { - // must be able to find it based on ID. Validator should catch invalid ID's. - return $this->accountRepository->findNull($accountId); - } - if (strlen($accountName) > 0) { - /** @var AccountFactory $factory */ - $factory = app(AccountFactory::class); - $factory->setUser($this->user); - - return $factory->findOrCreate($accountName, AccountType::EXPENSE); - } - - // return cash account: - return $this->accountRepository->getCashAccount(); - break; - case AccountType::REVENUE: - if ($accountId > 0) { - // must be able to find it based on ID. Validator should catch invalid ID's. - return $this->accountRepository->findNull($accountId); - } - if (strlen($accountName) > 0) { - // alternatively, return by name. - /** @var AccountFactory $factory */ - $factory = app(AccountFactory::class); - $factory->setUser($this->user); - - return $factory->findOrCreate($accountName, AccountType::REVENUE); - } - - // return cash account: - return $this->accountRepository->getCashAccount(); - - default: - throw new FireflyException(sprintf('Cannot find account of type "%s".', $expectedType)); - - } - } - - /** - * @param int|null $budgetId - * @param null|string $budgetName - * - * @return Budget|null - */ - protected function findBudget(?int $budgetId, ?string $budgetName): ?Budget - { - /** @var BudgetFactory $factory */ - $factory = app(BudgetFactory::class); - $factory->setUser($this->user); - - return $factory->find($budgetId, $budgetName); - } - - /** - * @param int|null $categoryId - * @param null|string $categoryName - * - * @return Category|null - */ - protected function findCategory(?int $categoryId, ?string $categoryName): ?Category - { - /** @var CategoryFactory $factory */ - $factory = app(CategoryFactory::class); - $factory->setUser($this->user); - - return $factory->findOrCreate($categoryId, $categoryName); - } - - /** - * @param int|null $currencyId - * @param null|string $currencyCode - * - * @return TransactionCurrency|null - */ - protected function findCurrency(?int $currencyId, ?string $currencyCode): ?TransactionCurrency - { - $factory = app(TransactionCurrencyFactory::class); - - return $factory->find($currencyId, $currencyCode); - } - - /** - * @param Transaction $transaction - * @param Budget|null $budget - */ - protected function setBudget(Transaction $transaction, ?Budget $budget): void - { - if (is_null($budget)) { - return; - } - $transaction->budgets()->save($budget); - - return; - } - - /** - * @param Transaction $transaction - * @param Category|null $category - */ - protected function setCategory(Transaction $transaction, ?Category $category): void - { - if (is_null($category)) { - return; - } - $transaction->categories()->save($category); - - return; - } - - /** - * @param Transaction $transaction - * @param string $amount - */ - protected function setForeignAmount(Transaction $transaction, string $amount): void - { - $transaction->foreign_amount = $amount; - $transaction->save(); - } - - /** - * @param Transaction $transaction - * @param TransactionCurrency|null $currency - */ - protected function setForeignCurrency(Transaction $transaction, ?TransactionCurrency $currency): void - { - if (is_null($currency)) { - return; - } - $transaction->foreign_currency_id = $currency->id; - $transaction->save(); - - return; - } } \ No newline at end of file diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php index a2887c870d..dbded6711c 100644 --- a/app/Factory/TransactionJournalFactory.php +++ b/app/Factory/TransactionJournalFactory.php @@ -27,13 +27,16 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Note; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; +use FireflyIII\Services\Internal\Support\JournalServiceTrait; use FireflyIII\User; +use Log; /** * Class TransactionJournalFactory */ class TransactionJournalFactory { + use JournalServiceTrait; /** @var User */ private $user; @@ -47,6 +50,7 @@ class TransactionJournalFactory */ public function create(array $data): TransactionJournal { + Log::debug('Start of TransactionJournalFactory::create()'); // store basic journal first. $type = $this->findTransactionType($data['type']); $defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user); @@ -95,7 +99,7 @@ class TransactionJournalFactory $this->storeMeta($journal, $data, 'payment_date'); $this->storeMeta($journal, $data, 'invoice_date'); $this->storeMeta($journal, $data, 'internal_reference'); - + Log::debug('End of TransactionJournalFactory::create()'); return $journal; } @@ -109,25 +113,6 @@ class TransactionJournalFactory $this->user = $user; } - /** - * Connect bill if present. - * - * @param TransactionJournal $journal - * @param array $data - */ - protected function connectBill(TransactionJournal $journal, array $data): void - { - /** @var BillFactory $factory */ - $factory = app(BillFactory::class); - $factory->setUser($this->user); - $bill = $factory->find($data['bill_id'], $data['bill_name']); - - if (!is_null($bill)) { - $journal->bill_id = $bill->id; - $journal->save(); - } - } - /** * @param TransactionJournal $journal * @param array $data @@ -146,23 +131,6 @@ class TransactionJournalFactory } } - /** - * @param TransactionJournal $journal - * @param array $data - */ - protected function connectTags(TransactionJournal $journal, array $data): void - { - $factory = app(TagFactory::class); - $factory->setUser($journal->user); - if (is_null($data['tags'])) { - return; - } - foreach ($data['tags'] as $string) { - $tag = $factory->findOrCreate($string); - $journal->tags()->save($tag); - } - } - /** * Get the transaction type. Since this is mandatory, will throw an exception when nothing comes up. Will always * use TransactionType repository. @@ -183,39 +151,4 @@ class TransactionJournalFactory return $transactionType; } - /** - * @param TransactionJournal $journal - * @param array $data - * @param string $field - */ - protected function storeMeta(TransactionJournal $journal, array $data, string $field): void - { - $value = $data[$field] ?? null; - if (!is_null($value)) { - $set = [ - 'journal' => $journal, - 'name' => $field, - 'data' => $data[$field], - ]; - /** @var TransactionJournalMetaFactory $factory */ - $factory = app(TransactionJournalMetaFactory::class); - $factory->updateOrCreate($set); - } - } - - /** - * @param TransactionJournal $journal - * @param string $notes - */ - protected function storeNote(TransactionJournal $journal, string $notes): void - { - if (strlen($notes) > 0) { - $note = new Note; - $note->noteable()->associate($journal); - $note->text = $notes; - $note->save(); - } - - } - } \ No newline at end of file diff --git a/app/Http/Requests/ReconciliationFormRequest.php b/app/Http/Requests/ReconciliationUpdateRequest.php similarity index 100% rename from app/Http/Requests/ReconciliationFormRequest.php rename to app/Http/Requests/ReconciliationUpdateRequest.php diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index 3f4a481357..2621dc19d2 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Repositories\Journal; use Exception; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\TransactionJournalFactory; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; @@ -300,14 +301,43 @@ class JournalRepository implements JournalRepositoryInterface * @return TransactionJournal * * @throws \FireflyIII\Exceptions\FireflyException - * @throws Exception */ public function update(TransactionJournal $journal, array $data): TransactionJournal { /** @var JournalUpdateService $service */ $service = app(JournalUpdateService::class); + $service->setUser($this->user); - return $service->update($journal, $data); + try { + $journal = $service->update($journal, $data); + } catch (FireflyException | Exception $e) { + throw new FireflyException($e->getMessage()); + } + + return $journal; } + /** + * Get account of transaction that is more than zero. Only works with unsplit journals. + * + * @param TransactionJournal $journal + * + * @return Account + */ + public function getDestinationAccount(TransactionJournal $journal): Account + { + return $journal->transactions()->where('amount','<',0)->first()->account; + } + + /** + * Get account of transaction that is less than zero. Only works with unsplit journals. + * + * @param TransactionJournal $journal + * + * @return Account + */ + public function getSourceAccount(TransactionJournal $journal): Account + { + return $journal->transactions()->where('amount','>',0)->first()->account; + } } diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php index 7877ea37ec..cd606cb813 100644 --- a/app/Repositories/Journal/JournalRepositoryInterface.php +++ b/app/Repositories/Journal/JournalRepositoryInterface.php @@ -36,6 +36,7 @@ use Illuminate\Support\MessageBag; */ interface JournalRepositoryInterface { + /** * @param TransactionJournal $journal * @param TransactionType $type @@ -99,6 +100,15 @@ interface JournalRepositoryInterface */ public function getAssetTransaction(TransactionJournal $journal): ?Transaction; + /** + * Get account of transaction that is more than zero. Only works with unsplit journals. + * + * @param TransactionJournal $journal + * + * @return Account + */ + public function getDestinationAccount(TransactionJournal $journal): Account; + /** * @param TransactionJournal $journal * @@ -106,6 +116,15 @@ interface JournalRepositoryInterface */ public function getNote(TransactionJournal $journal): ?Note; + /** + * Get account of transaction that is less than zero. Only works with unsplit journals. + * + * @param TransactionJournal $journal + * + * @return Account + */ + public function getSourceAccount(TransactionJournal $journal): Account; + /** * @return Collection */ diff --git a/app/Services/Internal/Support/JournalServiceTrait.php b/app/Services/Internal/Support/JournalServiceTrait.php new file mode 100644 index 0000000000..6d0322b08e --- /dev/null +++ b/app/Services/Internal/Support/JournalServiceTrait.php @@ -0,0 +1,135 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Services\Internal\Support; + +use Exception; +use FireflyIII\Factory\BillFactory; +use FireflyIII\Factory\TagFactory; +use FireflyIII\Factory\TransactionJournalMetaFactory; +use FireflyIII\Models\Note; +use FireflyIII\Models\TransactionJournal; + +/** + * Trait JournalServiceTrait + * + * @package FireflyIII\Services\Internal\Support + */ +trait JournalServiceTrait +{ + + /** + * Connect bill if present. + * + * @param TransactionJournal $journal + * @param array $data + */ + protected function connectBill(TransactionJournal $journal, array $data): void + { + /** @var BillFactory $factory */ + $factory = app(BillFactory::class); + $factory->setUser($this->user); + $bill = $factory->find($data['bill_id'], $data['bill_name']); + + if (!is_null($bill)) { + $journal->bill_id = $bill->id; + $journal->save(); + + return; + } + $journal->bill_id = null; + $journal->save(); + + return; + } + + /** + * @param TransactionJournal $journal + * @param array $data + */ + protected function connectTags(TransactionJournal $journal, array $data): void + { + /** @var TagFactory $factory */ + $factory = app(TagFactory::class); + $factory->setUser($journal->user); + $set = []; + foreach ($data['tags'] as $string) { + if (strlen($string) > 0) { + $tag = $factory->findOrCreate($string); + $set[] = $tag->id; + } + } + $journal->tags()->sync($set); + } + + /** + * @param TransactionJournal $journal + * @param array $data + * @param string $field + */ + protected function storeMeta(TransactionJournal $journal, array $data, string $field): void + { + if (!isset($data[$field])) { + return; + } + $set = [ + 'journal' => $journal, + 'name' => $field, + 'data' => $data[$field], + ]; + /** @var TransactionJournalMetaFactory $factory */ + $factory = app(TransactionJournalMetaFactory::class); + try { + $factory->updateOrCreate($set); + } catch (Exception $e) { + // don't care + } + } + + /** + * @param TransactionJournal $journal + * @param string $notes + */ + protected function storeNote(TransactionJournal $journal, ?string $notes): void + { + $notes = strval($notes); + if (strlen($notes) > 0) { + $note = $journal->notes()->first(); + if (is_null($note)) { + $note = new Note; + $note->noteable()->associate($journal); + } + $note->text = $notes; + $note->save(); + + return; + } + $note = $journal->notes()->first(); + if (!is_null($note)) { + $note->delete(); + } + + return; + + } +} \ No newline at end of file diff --git a/app/Services/Internal/Support/TransactionServiceTrait.php b/app/Services/Internal/Support/TransactionServiceTrait.php new file mode 100644 index 0000000000..cc92aa09df --- /dev/null +++ b/app/Services/Internal/Support/TransactionServiceTrait.php @@ -0,0 +1,260 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Services\Internal\Support; + + +use Exception; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Factory\AccountFactory; +use FireflyIII\Factory\BudgetFactory; +use FireflyIII\Factory\CategoryFactory; +use FireflyIII\Factory\TransactionCurrencyFactory; +use FireflyIII\Models\Account; +use FireflyIII\Models\AccountType; +use FireflyIII\Models\Budget; +use FireflyIII\Models\Category; +use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Models\TransactionType; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; + +/** + * Trait TransactionServiceTrait + * + * @package FireflyIII\Services\Internal\Support + */ +trait TransactionServiceTrait +{ + + /** + * @param TransactionJournal $journal + * @param string $direction + * + * @return string|null + * @throws FireflyException + */ + public function accountType(TransactionJournal $journal, string $direction): ?string + { + $types = []; + $type = $journal->transactionType->type; + switch ($type) { + default: + throw new FireflyException(sprintf('Cannot handle type "%s" in accountType()', $type)); + case TransactionType::WITHDRAWAL: + $types['source'] = AccountType::ASSET; + $types['destination'] = AccountType::EXPENSE; + break; + case TransactionType::DEPOSIT: + $types['source'] = AccountType::REVENUE; + $types['destination'] = AccountType::ASSET; + break; + case TransactionType::TRANSFER: + $types['source'] = AccountType::ASSET; + $types['destination'] = AccountType::ASSET; + break; + case TransactionType::RECONCILIATION: + // always NULL, since this is handled by the reconciliation. + $types['source'] = null; + $types['destination'] = null; + + // return here: + return $types[$direction]; + } + if (!isset($types[$direction])) { + throw new FireflyException(sprintf('No type set for direction "%s" and type "%s"', $type, $direction)); + } + + return $types[$direction]; + } + + /** + * @param string|null $expectedType + * @param int|null $accountId + * @param string|null $accountName + * + * @return Account + * @throws FireflyException + * @throws Exception + */ + public function findAccount(?string $expectedType, ?int $accountId, ?string $accountName): Account + { + $accountId = intval($accountId); + $accountName = strval($accountName); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); + + if(is_null($expectedType)) { + return $repository->findNull($accountId); + } + + switch ($expectedType) { + case AccountType::ASSET: + if ($accountId > 0) { + // must be able to find it based on ID. Validator should catch invalid ID's. + return $repository->findNull($accountId); + } + + // alternatively, return by name. Validator should catch invalid names. + return $repository->findByName($accountName, [AccountType::ASSET]); + break; + case AccountType::EXPENSE: + if ($accountId > 0) { + // must be able to find it based on ID. Validator should catch invalid ID's. + return $repository->findNull($accountId); + } + if (strlen($accountName) > 0) { + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user); + + return $factory->findOrCreate($accountName, AccountType::EXPENSE); + } + + // return cash account: + return $repository->getCashAccount(); + break; + case AccountType::REVENUE: + if ($accountId > 0) { + // must be able to find it based on ID. Validator should catch invalid ID's. + return $repository->findNull($accountId); + } + if (strlen($accountName) > 0) { + // alternatively, return by name. + /** @var AccountFactory $factory */ + $factory = app(AccountFactory::class); + $factory->setUser($this->user); + + return $factory->findOrCreate($accountName, AccountType::REVENUE); + } + + // return cash account: + return $repository->getCashAccount(); + + default: + throw new FireflyException(sprintf('Cannot find account of type "%s".', $expectedType)); + + } + } + + /** + * @param int|null $budgetId + * @param null|string $budgetName + * + * @return Budget|null + */ + protected function findBudget(?int $budgetId, ?string $budgetName): ?Budget + { + /** @var BudgetFactory $factory */ + $factory = app(BudgetFactory::class); + $factory->setUser($this->user); + + return $factory->find($budgetId, $budgetName); + } + + /** + * @param int|null $categoryId + * @param null|string $categoryName + * + * @return Category|null + */ + protected function findCategory(?int $categoryId, ?string $categoryName): ?Category + { + /** @var CategoryFactory $factory */ + $factory = app(CategoryFactory::class); + $factory->setUser($this->user); + + return $factory->findOrCreate($categoryId, $categoryName); + } + + /** + * @param int|null $currencyId + * @param null|string $currencyCode + * + * @return TransactionCurrency|null + */ + protected function findCurrency(?int $currencyId, ?string $currencyCode): ?TransactionCurrency + { + $factory = app(TransactionCurrencyFactory::class); + + return $factory->find($currencyId, $currencyCode); + } + + /** + * @param Transaction $transaction + * @param Budget|null $budget + */ + protected function setBudget(Transaction $transaction, ?Budget $budget): void + { + if (is_null($budget)) { + return; + } + $transaction->budgets()->sync([$budget->id]); + + return; + } + + + /** + * @param Transaction $transaction + * @param Category|null $category + */ + protected function setCategory(Transaction $transaction, ?Category $category): void + { + if (is_null($category)) { + return; + } + $transaction->categories()->sync([$category->id]); + + return; + } + + + /** + * @param Transaction $transaction + * @param string|null $amount + */ + protected function setForeignAmount(Transaction $transaction, ?string $amount): void + { + $transaction->foreign_amount = $amount; + $transaction->save(); + } + + /** + * @param Transaction $transaction + * @param TransactionCurrency|null $currency + */ + protected function setForeignCurrency(Transaction $transaction, ?TransactionCurrency $currency): void + { + if (is_null($currency)) { + return; + } + $transaction->foreign_currency_id = $currency->id; + $transaction->save(); + + return; + } + + +} \ No newline at end of file diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php index d08c66c5cb..a862ae864b 100644 --- a/app/Services/Internal/Update/JournalUpdateService.php +++ b/app/Services/Internal/Update/JournalUpdateService.php @@ -27,9 +27,9 @@ use FireflyIII\Factory\BillFactory; use FireflyIII\Factory\TagFactory; use FireflyIII\Factory\TransactionFactory; use FireflyIII\Factory\TransactionJournalMetaFactory; -use FireflyIII\Models\Note; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Services\Internal\Support\JournalServiceTrait; use FireflyIII\User; use Illuminate\Support\Collection; @@ -40,6 +40,7 @@ use Illuminate\Support\Collection; */ class JournalUpdateService { + use JournalServiceTrait; /** @var User */ private $user; @@ -127,102 +128,4 @@ class JournalUpdateService return $journal; } - /** - * TODO seems duplicate of connectBill in JournalFactory. - * TODO this one is better than journal factory - * Connect bill if present. - * - * @param TransactionJournal $journal - * @param array $data - */ - protected function connectBill(TransactionJournal $journal, array $data): void - { - /** @var BillFactory $factory */ - $factory = app(BillFactory::class); - $factory->setUser($this->user); - $bill = $factory->find($data['bill_id'], $data['bill_name']); - - if (!is_null($bill)) { - $journal->bill_id = $bill->id; - $journal->save(); - - return; - } - $journal->bill_id = null; - $journal->save(); - - return; - } - - /** - * TODO seems duplicate or very equal to connectTags() in JournalFactory. - * - * @param TransactionJournal $journal - * @param array $data - */ - protected function connectTags(TransactionJournal $journal, array $data): void - { - /** @var TagFactory $factory */ - $factory = app(TagFactory::class); - $factory->setUser($journal->user); - $set = []; - foreach ($data['tags'] as $string) { - if (strlen($string) > 0) { - $tag = $factory->findOrCreate($string); - $set[] = $tag->id; - } - } - $journal->tags()->sync($set); - } - - /** - * TODO seems duplicate of storeMeta() in journalfactory. - * TODO this one is better than the one in journal factory (NULL)> - * - * @param TransactionJournal $journal - * @param array $data - * @param string $field - * - * @throws \Exception - */ - protected function storeMeta(TransactionJournal $journal, array $data, string $field): void - { - $set = [ - 'journal' => $journal, - 'name' => $field, - 'data' => $data[$field], - ]; - /** @var TransactionJournalMetaFactory $factory */ - $factory = app(TransactionJournalMetaFactory::class); - $factory->updateOrCreate($set); - } - - /** - * TODO is duplicate of storeNote in journal factory. - * - * @param TransactionJournal $journal - * @param string $notes - */ - protected function storeNote(TransactionJournal $journal, string $notes): void - { - if (strlen($notes) > 0) { - $note = $journal->notes()->first(); - if (is_null($note)) { - $note = new Note; - $note->noteable()->associate($journal); - } - $note->text = $notes; - $note->save(); - - return; - } - $note = $journal->notes()->first(); - if (!is_null($note)) { - $note->delete(); - } - - return; - - } - } \ No newline at end of file diff --git a/app/Services/Internal/Update/TransactionUpdateService.php b/app/Services/Internal/Update/TransactionUpdateService.php index d6685feb1f..37275627cc 100644 --- a/app/Services/Internal/Update/TransactionUpdateService.php +++ b/app/Services/Internal/Update/TransactionUpdateService.php @@ -24,19 +24,8 @@ declare(strict_types=1); namespace FireflyIII\Services\Internal\Update; use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Factory\AccountFactory; -use FireflyIII\Factory\BudgetFactory; -use FireflyIII\Factory\CategoryFactory; -use FireflyIII\Factory\TransactionCurrencyFactory; -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\Budget; -use FireflyIII\Models\Category; use FireflyIII\Models\Transaction; -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Models\TransactionJournal; -use FireflyIII\Models\TransactionType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Services\Internal\Support\TransactionServiceTrait; use FireflyIII\User; /** @@ -44,14 +33,29 @@ use FireflyIII\User; */ class TransactionUpdateService { - /** @var AccountRepositoryInterface */ - private $accountRepository; + use TransactionServiceTrait; + /** @var User */ private $user; - public function __construct() + + /** + * @param int $transactionId + * + * @return Transaction|null + */ + public function reconcile(int $transactionId): ?Transaction { - $this->accountRepository = app(AccountRepositoryInterface::class); + $transaction = Transaction::find($transactionId); + if (!is_null($transaction)) { + $transaction->reconciled = true; + $transaction->save(); + + return $transaction; + } + + return null; + } /** @@ -60,7 +64,6 @@ class TransactionUpdateService public function setUser(User $user): void { $this->user = $user; - $this->accountRepository->setUser($user); } /** @@ -78,6 +81,7 @@ class TransactionUpdateService // update description: $transaction->description = $description; + $foreignAmount = null; if (floatval($transaction->amount) < 0) { // this is the source transaction. $type = $this->accountType($journal, 'source'); @@ -126,218 +130,5 @@ class TransactionUpdateService return $transaction; } - /** - * TODO this method is duplicated - * - * @param TransactionJournal $journal - * @param string $direction - * - * @return string - * @throws FireflyException - */ - protected function accountType(TransactionJournal $journal, string $direction): string - { - $types = []; - $type = $journal->transactionType->type; - switch ($type) { - default: - throw new FireflyException(sprintf('Cannot handle type "%s" in accountType()', $type)); - case TransactionType::WITHDRAWAL: - $types['source'] = AccountType::ASSET; - $types['destination'] = AccountType::EXPENSE; - break; - case TransactionType::DEPOSIT: - $types['source'] = AccountType::REVENUE; - $types['destination'] = AccountType::ASSET; - break; - case TransactionType::TRANSFER: - $types['source'] = AccountType::ASSET; - $types['destination'] = AccountType::ASSET; - break; - } - if (!isset($types[$direction])) { - throw new FireflyException(sprintf('No type set for direction "%s" and type "%s"', $type, $direction)); - } - - return $types[$direction]; - } - - /** - * TODO this method is duplicated. - * - * @param string $expectedType - * @param int|null $accountId - * @param string|null $accountName - * - * @return Account - * @throws FireflyException - */ - protected function findAccount(string $expectedType, ?int $accountId, ?string $accountName): Account - { - $accountId = intval($accountId); - $accountName = strval($accountName); - - switch ($expectedType) { - case AccountType::ASSET: - if ($accountId > 0) { - // must be able to find it based on ID. Validator should catch invalid ID's. - return $this->accountRepository->findNull($accountId); - } - - // alternatively, return by name. Validator should catch invalid names. - return $this->accountRepository->findByName($accountName, [AccountType::ASSET]); - break; - case AccountType::EXPENSE: - if ($accountId > 0) { - // must be able to find it based on ID. Validator should catch invalid ID's. - return $this->accountRepository->findNull($accountId); - } - if (strlen($accountName) > 0) { - /** @var AccountFactory $factory */ - $factory = app(AccountFactory::class); - $factory->setUser($this->user); - - return $factory->findOrCreate($accountName, AccountType::EXPENSE); - } - - // return cash account: - return $this->accountRepository->getCashAccount(); - break; - case AccountType::REVENUE: - if ($accountId > 0) { - // must be able to find it based on ID. Validator should catch invalid ID's. - return $this->accountRepository->findNull($accountId); - } - if (strlen($accountName) > 0) { - // alternatively, return by name. - /** @var AccountFactory $factory */ - $factory = app(AccountFactory::class); - $factory->setUser($this->user); - - return $factory->findOrCreate($accountName, AccountType::REVENUE); - } - - // return cash account: - return $this->accountRepository->getCashAccount(); - - default: - throw new FireflyException(sprintf('Cannot find account of type "%s".', $expectedType)); - - } - } - - /** - * TODO method is duplicated - * - * @param int|null $budgetId - * @param null|string $budgetName - * - * @return Budget|null - */ - protected function findBudget(?int $budgetId, ?string $budgetName): ?Budget - { - /** @var BudgetFactory $factory */ - $factory = app(BudgetFactory::class); - $factory->setUser($this->user); - - return $factory->find($budgetId, $budgetName); - } - - /** - * TODO method is duplicated - * - * @param int|null $categoryId - * @param null|string $categoryName - * - * @return Category|null - */ - protected function findCategory(?int $categoryId, ?string $categoryName): ?Category - { - /** @var CategoryFactory $factory */ - $factory = app(CategoryFactory::class); - $factory->setUser($this->user); - - return $factory->findOrCreate($categoryId, $categoryName); - } - - /** - * TODO method is duplicated - * - * @param int|null $currencyId - * @param null|string $currencyCode - * - * @return TransactionCurrency|null - */ - protected function findCurrency(?int $currencyId, ?string $currencyCode): ?TransactionCurrency - { - $factory = app(TransactionCurrencyFactory::class); - - return $factory->find($currencyId, $currencyCode); - } - - /** - * TODO almost the same as in transaction factory. - * - * @param Transaction $transaction - * @param Budget|null $budget - */ - protected function setBudget(Transaction $transaction, ?Budget $budget): void - { - if (is_null($budget)) { - return; - } - $transaction->budgets()->sync([$budget->id]); - - return; - } - - /** - * TODO almost the same as in transaction factory. - * - * @param Transaction $transaction - * @param Category|null $category - */ - protected function setCategory(Transaction $transaction, ?Category $category): void - { - if (is_null($category)) { - return; - } - $transaction->categories()->sync([$category->id]); - - return; - } - - /** - * TODO method is duplicated - * - * @param Transaction $transaction - * @param string|null $amount - */ - protected function setForeignAmount(Transaction $transaction, ?string $amount): void - { - $transaction->foreign_amount = $amount; - $transaction->save(); - } - - /** - * TODO method is duplicated - * - * @param Transaction $transaction - * @param TransactionCurrency|null $currency - */ - protected function setForeignCurrency(Transaction $transaction, ?TransactionCurrency $currency): void - { - if (is_null($currency)) { - $transaction->foreign_currency_id = null; - $transaction->save(); - - return; - } - $transaction->foreign_currency_id = $currency->id; - $transaction->save(); - - return; - } - } \ No newline at end of file