mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-05 04:03:26 +00:00
Clean up old tests.
This commit is contained in:
@@ -108,31 +108,31 @@ class AccountUpdateService
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
private function updateLocation(Account $account, array $data): void
|
||||
private function updateAccount(Account $account, array $data): Account
|
||||
{
|
||||
$updateLocation = $data['update_location'] ?? false;
|
||||
// location must be updated?
|
||||
if (true === $updateLocation) {
|
||||
// if all set to NULL, delete
|
||||
if (null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level']) {
|
||||
$account->locations()->delete();
|
||||
}
|
||||
// update the account itself:
|
||||
$account->name = $data['name'] ?? $account->name;
|
||||
$account->active = $data['active'] ?? $account->active;
|
||||
$account->iban = $data['iban'] ?? $account->iban;
|
||||
|
||||
// otherwise, update or create.
|
||||
if (!(null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level'])) {
|
||||
$location = $this->accountRepository->getLocation($account);
|
||||
if (null === $location) {
|
||||
$location = new Location;
|
||||
$location->locatable()->associate($account);
|
||||
}
|
||||
|
||||
$location->latitude = $data['latitude'] ?? config('firefly.default_location.latitude');
|
||||
$location->longitude = $data['longitude'] ?? config('firefly.default_location.longitude');
|
||||
$location->zoom_level = $data['zoom_level'] ?? config('firefly.default_location.zoom_level');
|
||||
$location->save();
|
||||
}
|
||||
// liability stuff:
|
||||
$liabilityType = $data['liability_type'] ?? '';
|
||||
if ($this->isLiability($account) && $this->isLiabilityType($liabilityType)) {
|
||||
$type = $this->getAccountType($liabilityType);
|
||||
$account->account_type_id = $type->id;
|
||||
}
|
||||
|
||||
// update virtual balance (could be set to zero if empty string).
|
||||
if (null !== $data['virtual_balance']) {
|
||||
$account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance'];
|
||||
}
|
||||
|
||||
$account->save();
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,93 +169,6 @@ class AccountUpdateService
|
||||
return AccountType::whereType($type)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
private function updateAccount(Account $account, array $data): Account
|
||||
{
|
||||
// update the account itself:
|
||||
$account->name = $data['name'] ?? $account->name;
|
||||
$account->active = $data['active'] ?? $account->active;
|
||||
$account->iban = $data['iban'] ?? $account->iban;
|
||||
|
||||
// liability stuff:
|
||||
$liabilityType = $data['liability_type'] ?? '';
|
||||
if ($this->isLiability($account) && $this->isLiabilityType($liabilityType)) {
|
||||
$type = $this->getAccountType($liabilityType);
|
||||
$account->account_type_id = $type->id;
|
||||
}
|
||||
|
||||
// update virtual balance (could be set to zero if empty string).
|
||||
if (null !== $data['virtual_balance']) {
|
||||
$account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance'];
|
||||
}
|
||||
|
||||
$account->save();
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
private function updatePreferences(Account $account, array $data): void
|
||||
{
|
||||
Log::debug(sprintf('Now in updatePreferences(#%d)', $account->id));
|
||||
if (array_key_exists('active', $data) && (false === $data['active'] || 0 === $data['active'])) {
|
||||
Log::debug('Account was marked as inactive.');
|
||||
$preference = app('preferences')->getForUser($account->user, 'frontpageAccounts');
|
||||
if (null !== $preference) {
|
||||
$removeAccountId = (int)$account->id;
|
||||
$array = $preference->data;
|
||||
Log::debug('Current list of accounts: ', $array);
|
||||
Log::debug(sprintf('Going to remove account #%d', $removeAccountId));
|
||||
$filtered = array_filter(
|
||||
$array, function ($accountId) use ($removeAccountId) {
|
||||
return (int)$accountId !== $removeAccountId;
|
||||
}
|
||||
);
|
||||
Log::debug('Left with accounts', array_values($filtered));
|
||||
app('preferences')->setForUser($account->user, 'frontpageAccounts', array_values($filtered));
|
||||
app('preferences')->forget($account->user, 'frontpageAccounts');
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug("Found no frontpageAccounts preference, do nothing.");
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug('Account was not marked as inactive, do nothing.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
private function updateOpeningBalance(Account $account, array $data): void
|
||||
{
|
||||
|
||||
// has valid initial balance (IB) data?
|
||||
$type = $account->accountType;
|
||||
// if it can have a virtual balance, it can also have an opening balance.
|
||||
|
||||
if (in_array($type->type, $this->canHaveVirtual, true)) {
|
||||
|
||||
// check if is submitted as empty, that makes it valid:
|
||||
if ($this->validOBData($data) && !$this->isEmptyOBData($data)) {
|
||||
$this->updateOBGroup($account, $data);
|
||||
}
|
||||
|
||||
if (!$this->validOBData($data) && $this->isEmptyOBData($data)) {
|
||||
$this->deleteOBGroup($account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
@@ -314,4 +227,91 @@ class AccountUpdateService
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
private function updateLocation(Account $account, array $data): void
|
||||
{
|
||||
$updateLocation = $data['update_location'] ?? false;
|
||||
// location must be updated?
|
||||
if (true === $updateLocation) {
|
||||
// if all set to NULL, delete
|
||||
if (null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level']) {
|
||||
$account->locations()->delete();
|
||||
}
|
||||
|
||||
// otherwise, update or create.
|
||||
if (!(null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level'])) {
|
||||
$location = $this->accountRepository->getLocation($account);
|
||||
if (null === $location) {
|
||||
$location = new Location;
|
||||
$location->locatable()->associate($account);
|
||||
}
|
||||
|
||||
$location->latitude = $data['latitude'] ?? config('firefly.default_location.latitude');
|
||||
$location->longitude = $data['longitude'] ?? config('firefly.default_location.longitude');
|
||||
$location->zoom_level = $data['zoom_level'] ?? config('firefly.default_location.zoom_level');
|
||||
$location->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
private function updateOpeningBalance(Account $account, array $data): void
|
||||
{
|
||||
|
||||
// has valid initial balance (IB) data?
|
||||
$type = $account->accountType;
|
||||
// if it can have a virtual balance, it can also have an opening balance.
|
||||
|
||||
if (in_array($type->type, $this->canHaveVirtual, true)) {
|
||||
|
||||
// check if is submitted as empty, that makes it valid:
|
||||
if ($this->validOBData($data) && !$this->isEmptyOBData($data)) {
|
||||
$this->updateOBGroup($account, $data);
|
||||
}
|
||||
|
||||
if (!$this->validOBData($data) && $this->isEmptyOBData($data)) {
|
||||
$this->deleteOBGroup($account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
private function updatePreferences(Account $account, array $data): void
|
||||
{
|
||||
Log::debug(sprintf('Now in updatePreferences(#%d)', $account->id));
|
||||
if (array_key_exists('active', $data) && (false === $data['active'] || 0 === $data['active'])) {
|
||||
Log::debug('Account was marked as inactive.');
|
||||
$preference = app('preferences')->getForUser($account->user, 'frontpageAccounts');
|
||||
if (null !== $preference) {
|
||||
$removeAccountId = (int)$account->id;
|
||||
$array = $preference->data;
|
||||
Log::debug('Current list of accounts: ', $array);
|
||||
Log::debug(sprintf('Going to remove account #%d', $removeAccountId));
|
||||
$filtered = array_filter(
|
||||
$array, function ($accountId) use ($removeAccountId) {
|
||||
return (int)$accountId !== $removeAccountId;
|
||||
}
|
||||
);
|
||||
Log::debug('Left with accounts', array_values($filtered));
|
||||
app('preferences')->setForUser($account->user, 'frontpageAccounts', array_values($filtered));
|
||||
app('preferences')->forget($account->user, 'frontpageAccounts');
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug("Found no frontpageAccounts preference, do nothing.");
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug('Account was not marked as inactive, do nothing.');
|
||||
}
|
||||
}
|
||||
|
@@ -136,6 +136,69 @@ class BillUpdateService
|
||||
return $bill;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param array $data
|
||||
*
|
||||
* @return Bill
|
||||
*/
|
||||
private function updateBillProperties(Bill $bill, array $data): Bill
|
||||
{
|
||||
|
||||
if (isset($data['name']) && '' !== (string)$data['name']) {
|
||||
$bill->name = $data['name'];
|
||||
}
|
||||
|
||||
if (isset($data['amount_min']) && '' !== (string)$data['amount_min']) {
|
||||
$bill->amount_min = $data['amount_min'];
|
||||
}
|
||||
if (isset($data['amount_max']) && '' !== (string)$data['amount_max']) {
|
||||
$bill->amount_max = $data['amount_max'];
|
||||
}
|
||||
if (isset($data['date']) && '' !== (string)$data['date']) {
|
||||
$bill->date = $data['date'];
|
||||
}
|
||||
if (isset($data['repeat_freq']) && '' !== (string)$data['repeat_freq']) {
|
||||
$bill->repeat_freq = $data['repeat_freq'];
|
||||
}
|
||||
if (isset($data['skip']) && '' !== (string)$data['skip']) {
|
||||
$bill->skip = $data['skip'];
|
||||
}
|
||||
if (isset($data['active']) && is_bool($data['active'])) {
|
||||
$bill->active = $data['active'];
|
||||
}
|
||||
|
||||
$bill->match = 'EMPTY';
|
||||
$bill->automatch = true;
|
||||
$bill->save();
|
||||
|
||||
return $bill;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param int $oldOrder
|
||||
* @param int $newOrder
|
||||
*/
|
||||
private function updateOrder(Bill $bill, int $oldOrder, int $newOrder): void
|
||||
{
|
||||
if ($newOrder > $oldOrder) {
|
||||
$this->user->bills()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder)
|
||||
->where('bills.id', '!=', $bill->id)
|
||||
->update(['order' => DB::raw('bills.order-1')]);
|
||||
$bill->order = $newOrder;
|
||||
$bill->save();
|
||||
}
|
||||
if ($newOrder < $oldOrder) {
|
||||
$this->user->bills()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder)
|
||||
->where('bills.id', '!=', $bill->id)
|
||||
->update(['order' => DB::raw('bills.order+1')]);
|
||||
$bill->order = $newOrder;
|
||||
$bill->save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param array $oldData
|
||||
@@ -195,7 +258,6 @@ class BillUpdateService
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Rule $rule
|
||||
* @param string $key
|
||||
@@ -206,67 +268,4 @@ class BillUpdateService
|
||||
{
|
||||
return $rule->ruleTriggers()->where('trigger_type', $key)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param int $oldOrder
|
||||
* @param int $newOrder
|
||||
*/
|
||||
private function updateOrder(Bill $bill, int $oldOrder, int $newOrder): void
|
||||
{
|
||||
if ($newOrder > $oldOrder) {
|
||||
$this->user->bills()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder)
|
||||
->where('bills.id', '!=', $bill->id)
|
||||
->update(['order' => DB::raw('bills.order-1')]);
|
||||
$bill->order = $newOrder;
|
||||
$bill->save();
|
||||
}
|
||||
if ($newOrder < $oldOrder) {
|
||||
$this->user->bills()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder)
|
||||
->where('bills.id', '!=', $bill->id)
|
||||
->update(['order' => DB::raw('bills.order+1')]);
|
||||
$bill->order = $newOrder;
|
||||
$bill->save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param array $data
|
||||
*
|
||||
* @return Bill
|
||||
*/
|
||||
private function updateBillProperties(Bill $bill, array $data): Bill
|
||||
{
|
||||
|
||||
if (isset($data['name']) && '' !== (string)$data['name']) {
|
||||
$bill->name = $data['name'];
|
||||
}
|
||||
|
||||
if (isset($data['amount_min']) && '' !== (string)$data['amount_min']) {
|
||||
$bill->amount_min = $data['amount_min'];
|
||||
}
|
||||
if (isset($data['amount_max']) && '' !== (string)$data['amount_max']) {
|
||||
$bill->amount_max = $data['amount_max'];
|
||||
}
|
||||
if (isset($data['date']) && '' !== (string)$data['date']) {
|
||||
$bill->date = $data['date'];
|
||||
}
|
||||
if (isset($data['repeat_freq']) && '' !== (string)$data['repeat_freq']) {
|
||||
$bill->repeat_freq = $data['repeat_freq'];
|
||||
}
|
||||
if (isset($data['skip']) && '' !== (string)$data['skip']) {
|
||||
$bill->skip = $data['skip'];
|
||||
}
|
||||
if (isset($data['active']) && is_bool($data['active'])) {
|
||||
$bill->active = $data['active'];
|
||||
}
|
||||
|
||||
$bill->match = 'EMPTY';
|
||||
$bill->automatch = true;
|
||||
$bill->save();
|
||||
|
||||
return $bill;
|
||||
}
|
||||
}
|
||||
|
@@ -23,13 +23,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Services\Internal\Update;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\RecurrenceTransactionMeta;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use Log;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class CategoryUpdateService
|
||||
@@ -54,6 +54,14 @@ class CategoryUpdateService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $user
|
||||
*/
|
||||
public function setUser($user): void
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param array $data
|
||||
@@ -75,27 +83,6 @@ class CategoryUpdateService
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $oldName
|
||||
* @param string $newName
|
||||
*/
|
||||
private function updateRuleActions(string $oldName, string $newName): void
|
||||
{
|
||||
$types = ['set_category',];
|
||||
$actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id')
|
||||
->where('rules.user_id', $this->user->id)
|
||||
->whereIn('rule_actions.action_type', $types)
|
||||
->where('rule_actions.action_value', $oldName)
|
||||
->get(['rule_actions.*']);
|
||||
Log::debug(sprintf('Found %d actions to update.', $actions->count()));
|
||||
/** @var RuleAction $action */
|
||||
foreach ($actions as $action) {
|
||||
$action->action_value = $newName;
|
||||
$action->save();
|
||||
Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $oldName
|
||||
* @param string $newName
|
||||
@@ -118,11 +105,24 @@ class CategoryUpdateService
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $user
|
||||
* @param string $oldName
|
||||
* @param string $newName
|
||||
*/
|
||||
public function setUser($user): void
|
||||
private function updateRuleActions(string $oldName, string $newName): void
|
||||
{
|
||||
$this->user = $user;
|
||||
$types = ['set_category',];
|
||||
$actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id')
|
||||
->where('rules.user_id', $this->user->id)
|
||||
->whereIn('rule_actions.action_type', $types)
|
||||
->where('rule_actions.action_value', $oldName)
|
||||
->get(['rule_actions.*']);
|
||||
Log::debug(sprintf('Found %d actions to update.', $actions->count()));
|
||||
/** @var RuleAction $action */
|
||||
foreach ($actions as $action) {
|
||||
$action->action_value = $newName;
|
||||
$action->save();
|
||||
Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +145,7 @@ class CategoryUpdateService
|
||||
* @param Category $category
|
||||
* @param array $data
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
private function updateNotes(Category $category, array $data): void
|
||||
{
|
||||
|
@@ -108,16 +108,15 @@ class GroupCloneService
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournalMeta $meta
|
||||
* @param TransactionJournal $newJournal
|
||||
* @param Transaction $transaction
|
||||
* @param TransactionJournal $newJournal
|
||||
*/
|
||||
private function cloneMeta(TransactionJournalMeta $meta, TransactionJournal $newJournal): void
|
||||
private function cloneTransaction(Transaction $transaction, TransactionJournal $newJournal): void
|
||||
{
|
||||
$newMeta = $meta->replicate();
|
||||
$newMeta->transaction_journal_id = $newJournal->id;
|
||||
if ('recurrence_id' !== $newMeta->name) {
|
||||
$newMeta->save();
|
||||
}
|
||||
$newTransaction = $transaction->replicate();
|
||||
$newTransaction->transaction_journal_id = $newJournal->id;
|
||||
$newTransaction->reconciled = false;
|
||||
$newTransaction->save();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,15 +136,16 @@ class GroupCloneService
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Transaction $transaction
|
||||
* @param TransactionJournal $newJournal
|
||||
* @param TransactionJournalMeta $meta
|
||||
* @param TransactionJournal $newJournal
|
||||
*/
|
||||
private function cloneTransaction(Transaction $transaction, TransactionJournal $newJournal): void
|
||||
private function cloneMeta(TransactionJournalMeta $meta, TransactionJournal $newJournal): void
|
||||
{
|
||||
$newTransaction = $transaction->replicate();
|
||||
$newTransaction->transaction_journal_id = $newJournal->id;
|
||||
$newTransaction->reconciled = false;
|
||||
$newTransaction->save();
|
||||
$newMeta = $meta->replicate();
|
||||
$newMeta->transaction_journal_id = $newJournal->id;
|
||||
if ('recurrence_id' !== $newMeta->name) {
|
||||
$newMeta->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -96,37 +96,6 @@ class GroupUpdateService
|
||||
return $transactionGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionGroup $transactionGroup
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function createTransactionJournal(TransactionGroup $transactionGroup, array $data): void
|
||||
{
|
||||
|
||||
$submission = [
|
||||
'transactions' => [
|
||||
$data,
|
||||
],
|
||||
];
|
||||
/** @var TransactionJournalFactory $factory */
|
||||
$factory = app(TransactionJournalFactory::class);
|
||||
$factory->setUser($transactionGroup->user);
|
||||
try {
|
||||
$collection = $factory->create($submission);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
throw new FireflyException(sprintf('Could not create new transaction journal: %s', $e->getMessage()));
|
||||
}
|
||||
$collection->each(
|
||||
function (TransactionJournal $journal) use ($transactionGroup) {
|
||||
$transactionGroup->transactionJournals()->save($journal);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update single journal.
|
||||
*
|
||||
@@ -191,4 +160,35 @@ class GroupUpdateService
|
||||
return $updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionGroup $transactionGroup
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function createTransactionJournal(TransactionGroup $transactionGroup, array $data): void
|
||||
{
|
||||
|
||||
$submission = [
|
||||
'transactions' => [
|
||||
$data,
|
||||
],
|
||||
];
|
||||
/** @var TransactionJournalFactory $factory */
|
||||
$factory = app(TransactionJournalFactory::class);
|
||||
$factory->setUser($transactionGroup->user);
|
||||
try {
|
||||
$collection = $factory->create($submission);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
throw new FireflyException(sprintf('Could not create new transaction journal: %s', $e->getMessage()));
|
||||
}
|
||||
$collection->each(
|
||||
function (TransactionJournal $journal) use ($transactionGroup) {
|
||||
$transactionGroup->transactionJournals()->save($journal);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -161,47 +161,61 @@ class JournalUpdateService
|
||||
}
|
||||
|
||||
/**
|
||||
* Get destination transaction.
|
||||
*
|
||||
* @return Transaction
|
||||
* @return bool
|
||||
*/
|
||||
private function getDestinationTransaction(): Transaction
|
||||
private function hasValidAccounts(): bool
|
||||
{
|
||||
if (null === $this->destinationTransaction) {
|
||||
$this->destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first();
|
||||
}
|
||||
|
||||
return $this->destinationTransaction;
|
||||
return $this->hasValidSourceAccount() && $this->hasValidDestinationAccount();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current or expected type of the journal (in case of a change) based on the data in the array.
|
||||
*
|
||||
* If the array contains key 'type' and the value is correct, this is returned. Otherwise, the original type is returned.
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
private function getExpectedType(): string
|
||||
private function hasValidSourceAccount(): bool
|
||||
{
|
||||
Log::debug('Now in getExpectedType()');
|
||||
if ($this->hasFields(['type'])) {
|
||||
return ucfirst('opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']);
|
||||
Log::debug('Now in hasValidSourceAccount().');
|
||||
$sourceId = $this->data['source_id'] ?? null;
|
||||
$sourceName = $this->data['source_name'] ?? null;
|
||||
|
||||
if (!$this->hasFields(['source_id', 'source_name'])) {
|
||||
$origSourceAccount = $this->getOriginalSourceAccount();
|
||||
$sourceId = $origSourceAccount->id;
|
||||
$sourceName = $origSourceAccount->name;
|
||||
}
|
||||
|
||||
return $this->transactionJournal->transactionType->type;
|
||||
// make new account validator.
|
||||
$expectedType = $this->getExpectedType();
|
||||
Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
|
||||
|
||||
// make a new validator.
|
||||
/** @var AccountValidator $validator */
|
||||
$validator = app(AccountValidator::class);
|
||||
$validator->setTransactionType($expectedType);
|
||||
$validator->setUser($this->transactionJournal->user);
|
||||
|
||||
$result = $validator->validateSource($sourceId, $sourceName, null);
|
||||
Log::debug(sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true)));
|
||||
|
||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
||||
|
||||
// validate submitted info:
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account
|
||||
* @param array $fields
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function getOriginalDestinationAccount(): Account
|
||||
private function hasFields(array $fields): bool
|
||||
{
|
||||
if (null === $this->destinationAccount) {
|
||||
$destination = $this->getDestinationTransaction();
|
||||
$this->destinationAccount = $destination->account;
|
||||
foreach ($fields as $field) {
|
||||
if (array_key_exists($field, $this->data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->destinationAccount;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,96 +245,20 @@ class JournalUpdateService
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a validation and returns the destination account. This method will break if the dest isn't really valid.
|
||||
* This method returns the current or expected type of the journal (in case of a change) based on the data in the array.
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
private function getValidDestinationAccount(): Account
|
||||
{
|
||||
Log::debug('Now in getValidDestinationAccount().');
|
||||
|
||||
if (!$this->hasFields(['destination_id', 'destination_name'])) {
|
||||
return $this->getOriginalDestinationAccount();
|
||||
}
|
||||
|
||||
$destInfo = [
|
||||
'id' => (int)($this->data['destination_id'] ?? null),
|
||||
'name' => $this->data['destination_name'] ?? null,
|
||||
'iban' => $this->data['destination_iban'] ?? null,
|
||||
'number' => $this->data['destination_number'] ?? null,
|
||||
'bic' => $this->data['destination_bic'] ?? null,
|
||||
];
|
||||
|
||||
// make new account validator.
|
||||
$expectedType = $this->getExpectedType();
|
||||
Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
|
||||
try {
|
||||
$result = $this->getAccount($expectedType, 'destination', $destInfo);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage()));
|
||||
$result = $this->getOriginalDestinationAccount();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a validation and returns the source account. This method will break if the source isn't really valid.
|
||||
* If the array contains key 'type' and the value is correct, this is returned. Otherwise, the original type is returned.
|
||||
*
|
||||
* @return Account
|
||||
* @return string
|
||||
*/
|
||||
private function getValidSourceAccount(): Account
|
||||
private function getExpectedType(): string
|
||||
{
|
||||
Log::debug('Now in getValidSourceAccount().');
|
||||
|
||||
if (!$this->hasFields(['source_id', 'source_name'])) {
|
||||
return $this->getOriginalSourceAccount();
|
||||
Log::debug('Now in getExpectedType()');
|
||||
if ($this->hasFields(['type'])) {
|
||||
return ucfirst('opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']);
|
||||
}
|
||||
|
||||
$sourceInfo = [
|
||||
'id' => (int)($this->data['source_id'] ?? null),
|
||||
'name' => $this->data['source_name'] ?? null,
|
||||
'iban' => $this->data['source_iban'] ?? null,
|
||||
'number' => $this->data['source_number'] ?? null,
|
||||
'bic' => $this->data['source_bic'] ?? null,
|
||||
];
|
||||
|
||||
$expectedType = $this->getExpectedType();
|
||||
try {
|
||||
$result = $this->getAccount($expectedType, 'source', $sourceInfo);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage()));
|
||||
|
||||
$result = $this->getOriginalSourceAccount();
|
||||
}
|
||||
|
||||
Log::debug(sprintf('getValidSourceAccount() will return #%d ("%s")', $result->id, $result->name));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasFields(array $fields): bool
|
||||
{
|
||||
foreach ($fields as $field) {
|
||||
if (array_key_exists($field, $this->data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function hasValidAccounts(): bool
|
||||
{
|
||||
return $this->hasValidSourceAccount() && $this->hasValidDestinationAccount();
|
||||
return $this->transactionJournal->transactionType->type;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,36 +299,64 @@ class JournalUpdateService
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @return Account
|
||||
*/
|
||||
private function hasValidSourceAccount(): bool
|
||||
private function getOriginalDestinationAccount(): Account
|
||||
{
|
||||
Log::debug('Now in hasValidSourceAccount().');
|
||||
$sourceId = $this->data['source_id'] ?? null;
|
||||
$sourceName = $this->data['source_name'] ?? null;
|
||||
|
||||
if (!$this->hasFields(['source_id', 'source_name'])) {
|
||||
$origSourceAccount = $this->getOriginalSourceAccount();
|
||||
$sourceId = $origSourceAccount->id;
|
||||
$sourceName = $origSourceAccount->name;
|
||||
if (null === $this->destinationAccount) {
|
||||
$destination = $this->getDestinationTransaction();
|
||||
$this->destinationAccount = $destination->account;
|
||||
}
|
||||
|
||||
// make new account validator.
|
||||
return $this->destinationAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get destination transaction.
|
||||
*
|
||||
* @return Transaction
|
||||
*/
|
||||
private function getDestinationTransaction(): Transaction
|
||||
{
|
||||
if (null === $this->destinationTransaction) {
|
||||
$this->destinationTransaction = $this->transactionJournal->transactions()->where('amount', '>', 0)->first();
|
||||
}
|
||||
|
||||
return $this->destinationTransaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a validation and returns the source account. This method will break if the source isn't really valid.
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
private function getValidSourceAccount(): Account
|
||||
{
|
||||
Log::debug('Now in getValidSourceAccount().');
|
||||
|
||||
if (!$this->hasFields(['source_id', 'source_name'])) {
|
||||
return $this->getOriginalSourceAccount();
|
||||
}
|
||||
|
||||
$sourceInfo = [
|
||||
'id' => (int)($this->data['source_id'] ?? null),
|
||||
'name' => $this->data['source_name'] ?? null,
|
||||
'iban' => $this->data['source_iban'] ?? null,
|
||||
'number' => $this->data['source_number'] ?? null,
|
||||
'bic' => $this->data['source_bic'] ?? null,
|
||||
];
|
||||
|
||||
$expectedType = $this->getExpectedType();
|
||||
Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
|
||||
try {
|
||||
$result = $this->getAccount($expectedType, 'source', $sourceInfo);
|
||||
} catch (FireflyException $e) {
|
||||
Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage()));
|
||||
|
||||
// make a new validator.
|
||||
/** @var AccountValidator $validator */
|
||||
$validator = app(AccountValidator::class);
|
||||
$validator->setTransactionType($expectedType);
|
||||
$validator->setUser($this->transactionJournal->user);
|
||||
$result = $this->getOriginalSourceAccount();
|
||||
}
|
||||
|
||||
$result = $validator->validateSource($sourceId, $sourceName, null);
|
||||
Log::debug(sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true)));
|
||||
Log::debug(sprintf('getValidSourceAccount() will return #%d ("%s")', $result->id, $result->name));
|
||||
|
||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
||||
|
||||
// validate submitted info:
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -427,36 +393,68 @@ class JournalUpdateService
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a validation and returns the destination account. This method will break if the dest isn't really valid.
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
private function updateAmount(): void
|
||||
private function getValidDestinationAccount(): Account
|
||||
{
|
||||
if (!$this->hasFields(['amount'])) {
|
||||
return;
|
||||
Log::debug('Now in getValidDestinationAccount().');
|
||||
|
||||
if (!$this->hasFields(['destination_id', 'destination_name'])) {
|
||||
return $this->getOriginalDestinationAccount();
|
||||
}
|
||||
|
||||
$value = $this->data['amount'] ?? '';
|
||||
$destInfo = [
|
||||
'id' => (int)($this->data['destination_id'] ?? null),
|
||||
'name' => $this->data['destination_name'] ?? null,
|
||||
'iban' => $this->data['destination_iban'] ?? null,
|
||||
'number' => $this->data['destination_number'] ?? null,
|
||||
'bic' => $this->data['destination_bic'] ?? null,
|
||||
];
|
||||
|
||||
// make new account validator.
|
||||
$expectedType = $this->getExpectedType();
|
||||
Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
|
||||
try {
|
||||
$amount = $this->getAmount($value);
|
||||
$result = $this->getAccount($expectedType, 'destination', $destInfo);
|
||||
} catch (FireflyException $e) {
|
||||
Log::debug(sprintf('getAmount("%s") returns error: %s', $value, $e->getMessage()));
|
||||
Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage()));
|
||||
$result = $this->getOriginalDestinationAccount();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates journal transaction type.
|
||||
*/
|
||||
private function updateType(): void
|
||||
{
|
||||
Log::debug('Now in updateType()');
|
||||
if ($this->hasFields(['type'])) {
|
||||
$type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Trying to change journal #%d from a %s to a %s.',
|
||||
$this->transactionJournal->id, $this->transactionJournal->transactionType->type, $type
|
||||
)
|
||||
);
|
||||
|
||||
/** @var TransactionTypeFactory $typeFactory */
|
||||
$typeFactory = app(TransactionTypeFactory::class);
|
||||
$result = $typeFactory->find($this->data['type']);
|
||||
if (null !== $result) {
|
||||
Log::debug('Changed transaction type!');
|
||||
$this->transactionJournal->transaction_type_id = $result->id;
|
||||
$this->transactionJournal->save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
$origSourceTransaction = $this->getSourceTransaction();
|
||||
$origSourceTransaction->amount = app('steam')->negative($amount);
|
||||
$origSourceTransaction->save();
|
||||
|
||||
|
||||
$destTransaction = $this->getDestinationTransaction();
|
||||
$destTransaction->amount = app('steam')->positive($amount);
|
||||
$destTransaction->save();
|
||||
|
||||
|
||||
// refresh transactions.
|
||||
$this->sourceTransaction->refresh();
|
||||
$this->destinationTransaction->refresh();
|
||||
Log::debug(sprintf('Updated amount to "%s"', $amount));
|
||||
Log::debug('No type field present.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -479,6 +477,47 @@ class JournalUpdateService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update journal generic field. Cannot be set to NULL.
|
||||
*
|
||||
* @param string $fieldName
|
||||
*/
|
||||
private function updateField(string $fieldName): void
|
||||
{
|
||||
if (array_key_exists($fieldName, $this->data) && '' !== (string)$this->data[$fieldName]) {
|
||||
$value = $this->data[$fieldName];
|
||||
|
||||
if ('date' === $fieldName) {
|
||||
if ($value instanceof Carbon) {
|
||||
// update timezone.
|
||||
$value->setTimezone(config('app.timezone'));
|
||||
}
|
||||
if (!($value instanceof Carbon)) {
|
||||
$value = new Carbon($value);
|
||||
}
|
||||
// do some parsing.
|
||||
Log::debug(sprintf('Create date value from string "%s".', $value));
|
||||
}
|
||||
|
||||
|
||||
$this->transactionJournal->$fieldName = $value;
|
||||
Log::debug(sprintf('Updated %s', $fieldName));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateCategory(): void
|
||||
{
|
||||
// update category
|
||||
if ($this->hasFields(['category_id', 'category_name'])) {
|
||||
Log::debug('Will update category.');
|
||||
|
||||
$this->storeCategory($this->transactionJournal, new NullArrayObject($this->data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -494,13 +533,103 @@ class JournalUpdateService
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateCategory(): void
|
||||
private function updateTags(): void
|
||||
{
|
||||
// update category
|
||||
if ($this->hasFields(['category_id', 'category_name'])) {
|
||||
Log::debug('Will update category.');
|
||||
if ($this->hasFields(['tags'])) {
|
||||
Log::debug('Will update tags.');
|
||||
$tags = $this->data['tags'] ?? null;
|
||||
$this->storeTags($this->transactionJournal, $tags);
|
||||
}
|
||||
}
|
||||
|
||||
$this->storeCategory($this->transactionJournal, new NullArrayObject($this->data));
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateReconciled(): void
|
||||
{
|
||||
if (array_key_exists('reconciled', $this->data) && is_bool($this->data['reconciled'])) {
|
||||
$this->transactionJournal->transactions()->update(['reconciled' => $this->data['reconciled']]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateNotes(): void
|
||||
{
|
||||
// update notes.
|
||||
if ($this->hasFields(['notes'])) {
|
||||
$notes = '' === (string)$this->data['notes'] ? null : $this->data['notes'];
|
||||
$this->storeNotes($this->transactionJournal, $notes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateMeta(): void
|
||||
{
|
||||
// update meta fields.
|
||||
// first string
|
||||
if ($this->hasFields($this->metaString)) {
|
||||
Log::debug('Meta string fields are present.');
|
||||
$this->updateMetaFields();
|
||||
}
|
||||
|
||||
// then date fields.
|
||||
if ($this->hasFields($this->metaDate)) {
|
||||
Log::debug('Meta date fields are present.');
|
||||
$this->updateMetaDateFields();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateMetaFields(): void
|
||||
{
|
||||
/** @var TransactionJournalMetaFactory $factory */
|
||||
$factory = app(TransactionJournalMetaFactory::class);
|
||||
|
||||
foreach ($this->metaString as $field) {
|
||||
if ($this->hasFields([$field])) {
|
||||
$value = '' === $this->data[$field] ? null : $this->data[$field];
|
||||
Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
|
||||
$set = [
|
||||
'journal' => $this->transactionJournal,
|
||||
'name' => $field,
|
||||
'data' => $value,
|
||||
];
|
||||
$factory->updateOrCreate($set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateMetaDateFields(): void
|
||||
{
|
||||
/** @var TransactionJournalMetaFactory $factory */
|
||||
$factory = app(TransactionJournalMetaFactory::class);
|
||||
|
||||
foreach ($this->metaDate as $field) {
|
||||
if ($this->hasFields([$field])) {
|
||||
try {
|
||||
$value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
|
||||
} catch (Exception $e) {
|
||||
Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
|
||||
$set = [
|
||||
'journal' => $this->transactionJournal,
|
||||
'name' => $field,
|
||||
'data' => $value,
|
||||
];
|
||||
$factory->updateOrCreate($set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,33 +666,37 @@ class JournalUpdateService
|
||||
}
|
||||
|
||||
/**
|
||||
* Update journal generic field. Cannot be set to NULL.
|
||||
*
|
||||
* @param string $fieldName
|
||||
*/
|
||||
private function updateField(string $fieldName): void
|
||||
private function updateAmount(): void
|
||||
{
|
||||
if (array_key_exists($fieldName, $this->data) && '' !== (string)$this->data[$fieldName]) {
|
||||
$value = $this->data[$fieldName];
|
||||
|
||||
if ('date' === $fieldName) {
|
||||
if ($value instanceof Carbon) {
|
||||
// update timezone.
|
||||
$value->setTimezone(config('app.timezone'));
|
||||
}
|
||||
if (!($value instanceof Carbon)) {
|
||||
$value = new Carbon($value);
|
||||
}
|
||||
// do some parsing.
|
||||
Log::debug(sprintf('Create date value from string "%s".', $value));
|
||||
}
|
||||
|
||||
|
||||
$this->transactionJournal->$fieldName = $value;
|
||||
Log::debug(sprintf('Updated %s', $fieldName));
|
||||
if (!$this->hasFields(['amount'])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$value = $this->data['amount'] ?? '';
|
||||
try {
|
||||
$amount = $this->getAmount($value);
|
||||
} catch (FireflyException $e) {
|
||||
Log::debug(sprintf('getAmount("%s") returns error: %s', $value, $e->getMessage()));
|
||||
|
||||
return;
|
||||
}
|
||||
$origSourceTransaction = $this->getSourceTransaction();
|
||||
$origSourceTransaction->amount = app('steam')->negative($amount);
|
||||
$origSourceTransaction->save();
|
||||
|
||||
|
||||
$destTransaction = $this->getDestinationTransaction();
|
||||
$destTransaction->amount = app('steam')->positive($amount);
|
||||
$destTransaction->save();
|
||||
|
||||
|
||||
// refresh transactions.
|
||||
$this->sourceTransaction->refresh();
|
||||
$this->destinationTransaction->refresh();
|
||||
Log::debug(sprintf('Updated amount to "%s"', $amount));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -628,138 +761,4 @@ class JournalUpdateService
|
||||
$this->sourceTransaction->refresh();
|
||||
$this->destinationTransaction->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateMeta(): void
|
||||
{
|
||||
// update meta fields.
|
||||
// first string
|
||||
if ($this->hasFields($this->metaString)) {
|
||||
Log::debug('Meta string fields are present.');
|
||||
$this->updateMetaFields();
|
||||
}
|
||||
|
||||
// then date fields.
|
||||
if ($this->hasFields($this->metaDate)) {
|
||||
Log::debug('Meta date fields are present.');
|
||||
$this->updateMetaDateFields();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateMetaDateFields(): void
|
||||
{
|
||||
/** @var TransactionJournalMetaFactory $factory */
|
||||
$factory = app(TransactionJournalMetaFactory::class);
|
||||
|
||||
foreach ($this->metaDate as $field) {
|
||||
if ($this->hasFields([$field])) {
|
||||
try {
|
||||
$value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
|
||||
} catch (Exception $e) {
|
||||
Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
|
||||
$set = [
|
||||
'journal' => $this->transactionJournal,
|
||||
'name' => $field,
|
||||
'data' => $value,
|
||||
];
|
||||
$factory->updateOrCreate($set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateMetaFields(): void
|
||||
{
|
||||
/** @var TransactionJournalMetaFactory $factory */
|
||||
$factory = app(TransactionJournalMetaFactory::class);
|
||||
|
||||
foreach ($this->metaString as $field) {
|
||||
if ($this->hasFields([$field])) {
|
||||
$value = '' === $this->data[$field] ? null : $this->data[$field];
|
||||
Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
|
||||
$set = [
|
||||
'journal' => $this->transactionJournal,
|
||||
'name' => $field,
|
||||
'data' => $value,
|
||||
];
|
||||
$factory->updateOrCreate($set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateNotes(): void
|
||||
{
|
||||
// update notes.
|
||||
if ($this->hasFields(['notes'])) {
|
||||
$notes = '' === (string)$this->data['notes'] ? null : $this->data['notes'];
|
||||
$this->storeNotes($this->transactionJournal, $notes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateTags(): void
|
||||
{
|
||||
if ($this->hasFields(['tags'])) {
|
||||
Log::debug('Will update tags.');
|
||||
$tags = $this->data['tags'] ?? null;
|
||||
$this->storeTags($this->transactionJournal, $tags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates journal transaction type.
|
||||
*/
|
||||
private function updateType(): void
|
||||
{
|
||||
Log::debug('Now in updateType()');
|
||||
if ($this->hasFields(['type'])) {
|
||||
$type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Trying to change journal #%d from a %s to a %s.',
|
||||
$this->transactionJournal->id, $this->transactionJournal->transactionType->type, $type
|
||||
)
|
||||
);
|
||||
|
||||
/** @var TransactionTypeFactory $typeFactory */
|
||||
$typeFactory = app(TransactionTypeFactory::class);
|
||||
$result = $typeFactory->find($this->data['type']);
|
||||
if (null !== $result) {
|
||||
Log::debug('Changed transaction type!');
|
||||
$this->transactionJournal->transaction_type_id = $result->id;
|
||||
$this->transactionJournal->save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Log::debug('No type field present.');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function updateReconciled(): void
|
||||
{
|
||||
if (array_key_exists('reconciled', $this->data) && is_bool($this->data['reconciled'])) {
|
||||
$this->transactionJournal->transactions()->update(['reconciled' => $this->data['reconciled']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\RecurrenceRepetition;
|
||||
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
|
||||
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
|
||||
use FireflyIII\User;
|
||||
@@ -56,53 +57,55 @@ class RecurrenceUpdateService
|
||||
*/
|
||||
public function update(Recurrence $recurrence, array $data): Recurrence
|
||||
{
|
||||
$this->user = $recurrence->user;
|
||||
$transactionType = $recurrence->transactionType;
|
||||
if (isset($data['recurrence']['type'])) {
|
||||
$transactionType = $this->findTransactionType(ucfirst($data['recurrence']['type']));
|
||||
}
|
||||
$this->user = $recurrence->user;
|
||||
// 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']['nr_of_repetitions'] ?? $recurrence->repetitions;
|
||||
$recurrence->apply_rules = $data['recurrence']['apply_rules'] ?? $recurrence->apply_rules;
|
||||
$recurrence->active = $data['recurrence']['active'] ?? $recurrence->active;
|
||||
|
||||
// if nr_of_repetitions is set, then drop the "repeat_until" field.
|
||||
if (0 !== $recurrence->repetitions) {
|
||||
$recurrence->repeat_until = null;
|
||||
}
|
||||
|
||||
if (isset($data['recurrence']['repetition_end'])) {
|
||||
if (in_array($data['recurrence']['repetition_end'], ['forever', 'until_date'])) {
|
||||
$recurrence->repetitions = 0;
|
||||
if (array_key_exists('recurrence', $data)) {
|
||||
$info = $data['recurrence'];
|
||||
if (array_key_exists('title', $info)) {
|
||||
$recurrence->title = $info['title'];
|
||||
}
|
||||
if (in_array($data['recurrence']['repetition_end'], ['forever', 'times'])) {
|
||||
$recurrence->repeat_until = null;
|
||||
if (array_key_exists('description', $info)) {
|
||||
$recurrence->description = $info['description'];
|
||||
}
|
||||
if (array_key_exists('first_date', $info)) {
|
||||
$recurrence->first_date = $info['first_date'];
|
||||
}
|
||||
if (array_key_exists('repeat_until', $info)) {
|
||||
$recurrence->repeat_until = $info['repeat_until'];
|
||||
$recurrence->repetitions = 0;
|
||||
}
|
||||
if (array_key_exists('nr_of_repetitions', $info)) {
|
||||
if (0 !== (int)$info['nr_of_repetitions']) {
|
||||
$recurrence->repeat_until = null;
|
||||
}
|
||||
$recurrence->repetitions = $info['nr_of_repetitions'];
|
||||
}
|
||||
if (array_key_exists('apply_rules', $info)) {
|
||||
$recurrence->apply_rules = $info['apply_rules'];
|
||||
}
|
||||
if (array_key_exists('active', $info)) {
|
||||
$recurrence->active = $info['active'];
|
||||
}
|
||||
// update all meta data:
|
||||
if (array_key_exists('notes', $info)) {
|
||||
$this->setNoteText($recurrence, $info['notes']);
|
||||
}
|
||||
}
|
||||
$recurrence->save();
|
||||
|
||||
// update all meta data:
|
||||
|
||||
if (isset($data['recurrence']['notes']) && null !== $data['recurrence']['notes']) {
|
||||
$this->setNoteText($recurrence, $data['recurrence']['notes']);
|
||||
}
|
||||
|
||||
// update all repetitions
|
||||
if (null !== $data['repetitions']) {
|
||||
$this->deleteRepetitions($recurrence);
|
||||
$this->createRepetitions($recurrence, $data['repetitions'] ?? []);
|
||||
if (array_key_exists('repetitions', $data)) {
|
||||
Log::debug('Will update repetitions array');
|
||||
// update each repetition or throw error yay
|
||||
$this->updateRepetitions($recurrence, $data['repetitions'] ?? []);
|
||||
}
|
||||
|
||||
// update all transactions (and associated meta-data)
|
||||
if (null !== $data['transactions']) {
|
||||
$this->deleteTransactions($recurrence);
|
||||
$this->createTransactions($recurrence, $data['transactions'] ?? []);
|
||||
}
|
||||
// // update all transactions (and associated meta-data)
|
||||
// if (array_key_exists('transactions', $data)) {
|
||||
// $this->deleteTransactions($recurrence);
|
||||
// $this->createTransactions($recurrence, $data['transactions'] ?? []);
|
||||
// }
|
||||
|
||||
return $recurrence;
|
||||
}
|
||||
@@ -133,4 +136,76 @@ class RecurrenceUpdateService
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Recurrence $recurrence
|
||||
* @param array $repetitions
|
||||
*/
|
||||
private function updateRepetitions(Recurrence $recurrence, array $repetitions): void
|
||||
{
|
||||
$originalCount = $recurrence->recurrenceRepetitions()->count();
|
||||
if (0 === count($repetitions)) {
|
||||
// wont drop repetition, rather avoid.
|
||||
return;
|
||||
}
|
||||
// user added or removed repetitions, delete all and recreate:
|
||||
if ($originalCount !== count($repetitions)) {
|
||||
Log::debug('Del + recreate');
|
||||
$this->deleteRepetitions($recurrence);
|
||||
$this->createRepetitions($recurrence, $repetitions);
|
||||
|
||||
return;
|
||||
}
|
||||
// loop all and try to match them:
|
||||
if ($originalCount === count($repetitions)) {
|
||||
Log::debug('Loop and find');
|
||||
foreach ($repetitions as $current) {
|
||||
$match = $this->matchRepetition($recurrence, $current);
|
||||
if (null === $match) {
|
||||
throw new FireflyException('Cannot match recurring repetition to existing repetition. Not sure what to do. Break.');
|
||||
}
|
||||
$fields = [
|
||||
'type' => 'repetition_type',
|
||||
'moment' => 'repetition_moment',
|
||||
'skip' => 'repetition_skip',
|
||||
'weekend' => 'weekend',];
|
||||
foreach ($fields as $field => $column) {
|
||||
if (array_key_exists($field, $current)) {
|
||||
$match->$column = $current[$field];
|
||||
$match->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return RecurrenceRepetition|null
|
||||
*/
|
||||
private function matchRepetition(Recurrence $recurrence, array $data): ?RecurrenceRepetition
|
||||
{
|
||||
$originalCount = $recurrence->recurrenceRepetitions()->count();
|
||||
if (1 === $originalCount) {
|
||||
Log::debug('Return the first one');
|
||||
return $recurrence->recurrenceRepetitions()->first();
|
||||
}
|
||||
// find it:
|
||||
$fields = ['id' => 'id',
|
||||
'type' => 'repetition_type',
|
||||
'moment' => 'repetition_moment',
|
||||
'skip' => 'repetition_skip',
|
||||
'weekend' => 'weekend',
|
||||
];
|
||||
$query = $recurrence->recurrenceRepetitions();
|
||||
foreach ($fields as $field => $column) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$query->where($column, $data[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
return $query->first();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user