No longer have to submit mandatory fields to account end point. Just submit the field you wish to update, the rest will be untouched.

This commit is contained in:
James Cole 2019-08-24 07:56:08 +02:00
parent e5e3797d9c
commit d836c8217d
6 changed files with 161 additions and 71 deletions

View File

@ -290,7 +290,7 @@ class AccountController extends Controller
*/ */
public function update(AccountUpdateRequest $request, Account $account): JsonResponse public function update(AccountUpdateRequest $request, Account $account): JsonResponse
{ {
$data = $request->getAllAccountData(); $data = $request->getUpdateData();
$data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type);
$this->repository->update($account, $data); $this->repository->update($account, $data);
$manager = new Manager; $manager = new Manager;

View File

@ -33,6 +33,52 @@ use FireflyIII\Rules\IsBoolean;
class AccountUpdateRequest extends Request class AccountUpdateRequest extends Request
{ {
/**
* @return array
*/
public function getUpdateData(): array
{
$active = null;
$includeNetWorth = null;
if (null !== $this->get('active')) {
$active = $this->boolean('active');
}
if (null !== $this->get('include_net_worth')) {
$includeNetWorth = $this->boolean('include_net_worth');
}
$data = [
'name' => $this->nullableString('name'),
'active' => $active,
'include_net_worth' => $includeNetWorth,
'account_type' => $this->nullableString('type'),
'account_type_id' => null,
'currency_id' => $this->nullableInteger('currency_id'),
'currency_code' => $this->nullableString('currency_code'),
'virtual_balance' => $this->nullableString('virtual_balance'),
'iban' => $this->nullableString('iban'),
'BIC' => $this->nullableString('bic'),
'account_number' => $this->nullableString('account_number'),
'account_role' => $this->nullableString('account_role'),
'opening_balance' => $this->nullableString('opening_balance'),
'opening_balance_date' => $this->date('opening_balance_date'),
'cc_type' => $this->nullableString('credit_card_type'),
'cc_Monthly_payment_date' => $this->nullableString('monthly_payment_date'),
'notes' => $this->nullableString('notes'),
'interest' => $this->nullableString('interest'),
'interest_period' => $this->nullableString('interest_period'),
];
if ('liability' === $data['account_type']) {
$data['opening_balance'] = bcmul($this->nullableString('liability_amount'), '-1');
$data['opening_balance_date'] = $this->date('liability_start_date');
$data['account_type'] = $this->nullableString('liability_type');
$data['account_type_id'] = null;
}
return $data;
}
/** /**
* Authorize logged in users. * Authorize logged in users.
* *
@ -56,7 +102,7 @@ class AccountUpdateRequest extends Request
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier'))); $types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes'))); $ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$rules = [ $rules = [
'name' => sprintf('required|min:1|uniqueAccountForUser:%d', $account->id), 'name' => sprintf('min:1|uniqueAccountForUser:%d', $account->id),
'type' => sprintf('in:%s', $types), 'type' => sprintf('in:%s', $types),
'iban' => 'iban|nullable', 'iban' => 'iban|nullable',
'bic' => 'bic|nullable', 'bic' => 'bic|nullable',

View File

@ -177,6 +177,37 @@ class Request extends FormRequest
return (int)$string; return (int)$string;
} }
/**
* Return integer value, or NULL when it's not set.
*
* @param string $field
*
* @return int|null
*/
public function nullableInteger(string $field): ?int
{
$value = (string)$this->get($field);
if ('' === $value) {
return null;
}
return (int)$value;
}
/**
* Return string value, or NULL if empty.
*
* @param string $field
*
* @return string|null
*/
public function nullableString(string $field): ?string
{
$string = app('steam')->cleanString((string)($this->get($field) ?? ''));
return '' === $string ? null : $string;
}
/** /**
* Return string value. * Return string value.
* *

View File

@ -26,6 +26,7 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException; use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AccountFactory; use FireflyIII\Factory\AccountFactory;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionGroup;
@ -57,6 +58,17 @@ class AccountRepository implements AccountRepositoryInterface
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
} }
} }
/**
* @param array $types
*
* @return int
*/
public function count(array $types): int
{
return $this->user->accounts()->accountTypeIn($types)->count();
}
/** /**
* Moved here from account CRUD. * Moved here from account CRUD.
* *
@ -76,17 +88,6 @@ class AccountRepository implements AccountRepositoryInterface
return true; return true;
} }
/**
* @param array $types
*
* @return int
*/
public function count(array $types): int
{
return $this->user->accounts()->accountTypeIn($types)->count();
}
/** /**
* @param string $number * @param string $number
* @param array $types * @param array $types
@ -313,17 +314,15 @@ class AccountRepository implements AccountRepositoryInterface
*/ */
public function getMetaValue(Account $account, string $field): ?string public function getMetaValue(Account $account, string $field): ?string
{ {
// TODO no longer need to loop like this /** @var AccountMeta $meta */
$meta = $account->accountMeta()->where('name', $field)->first();
foreach ($account->accountMeta as $meta) { if (null === $meta) {
if ($meta->name === $field) {
return (string)$meta->data;
}
}
return null; return null;
} }
return (string)$meta->data;
}
/** /**
* Get note text or null. * Get note text or null.
* *
@ -342,6 +341,20 @@ class AccountRepository implements AccountRepositoryInterface
return $note->text; return $note->text;
} }
/**
* @param Account $account
*
* @return TransactionJournal|null
*/
public function getOpeningBalance(Account $account): ?TransactionJournal
{
return TransactionJournal
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->transactionTypes([TransactionType::OPENING_BALANCE])
->first(['transaction_journals.*']);
}
/** /**
* Returns the amount of the opening balance for this account. * Returns the amount of the opening balance for this account.
* *
@ -387,6 +400,22 @@ class AccountRepository implements AccountRepositoryInterface
return $journal->date->format('Y-m-d'); return $journal->date->format('Y-m-d');
} }
/**
* @param Account $account
*
* @return TransactionGroup|null
*/
public function getOpeningBalanceGroup(Account $account): ?TransactionGroup
{
$journal = $this->getOpeningBalance($account);
$group = null;
if (null !== $journal) {
$group = $journal->transactionGroup;
}
return $group;
}
/** /**
* @param Account $account * @param Account $account
* *
@ -542,32 +571,4 @@ class AccountRepository implements AccountRepositoryInterface
return $account; return $account;
} }
/**
* @param Account $account
* @return TransactionJournal|null
*/
public function getOpeningBalance(Account $account): ?TransactionJournal
{
return TransactionJournal
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->transactionTypes([TransactionType::OPENING_BALANCE])
->first(['transaction_journals.*']);
}
/**
* @param Account $account
* @return TransactionGroup|null
*/
public function getOpeningBalanceGroup(Account $account): ?TransactionGroup
{
$journal = $this->getOpeningBalance($account);
$group = null;
if (null !== $journal) {
$group = $journal->transactionGroup;
}
return $group;
}
} }

View File

@ -95,12 +95,13 @@ trait AccountServiceTrait
if ($account->accountType->type === AccountType::ASSET) { if ($account->accountType->type === AccountType::ASSET) {
$fields = $this->validAssetFields; $fields = $this->validAssetFields;
} }
if ($account->accountType->type === AccountType::ASSET && 'ccAsset' === $data['account_role']) { if ($account->accountType->type === AccountType::ASSET && isset($data['account_role']) && 'ccAsset' === $data['account_role']) {
$fields = $this->validCCFields; $fields = $this->validCCFields;
} }
/** @var AccountMetaFactory $factory */ /** @var AccountMetaFactory $factory */
$factory = app(AccountMetaFactory::class); $factory = app(AccountMetaFactory::class);
foreach ($fields as $field) { foreach ($fields as $field) {
$factory->crud($account, $field, (string)($data[$field] ?? '')); $factory->crud($account, $field, (string)($data[$field] ?? ''));
} }
} }

View File

@ -23,10 +23,8 @@ declare(strict_types=1);
namespace FireflyIII\Services\Internal\Update; namespace FireflyIII\Services\Internal\Update;
use FireflyIII\Factory\TransactionCurrencyFactory;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Support\AccountServiceTrait; use FireflyIII\Services\Internal\Support\AccountServiceTrait;
use FireflyIII\User; use FireflyIII\User;
@ -39,13 +37,13 @@ class AccountUpdateService
{ {
use AccountServiceTrait; use AccountServiceTrait;
/** @var array */
private $canHaveVirtual;
/** @var AccountRepositoryInterface */ /** @var AccountRepositoryInterface */
protected $accountRepository; protected $accountRepository;
/** @var array */
private $canHaveVirtual;
/** @var User */ /** @var User */
private $user; private $user;
/** /**
* Constructor. * Constructor.
*/ */
@ -73,22 +71,35 @@ class AccountUpdateService
$this->user = $account->user; $this->user = $account->user;
// update the account itself: // update the account itself:
$account->name = $data['name'];
$account->active = $data['active']; $account->name = $data['name'] ?? $account->name;
$account->active = $data['active'] ?? $account->active;
if (null !== $data['virtual_balance']) {
$account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance']; $account->virtual_balance = '' === trim($data['virtual_balance']) ? '0' : $data['virtual_balance'];
$account->iban = $data['iban']; }
$account->iban = $data['iban'] ?? $account->iban;
$account->save(); $account->save();
if (isset($data['currency_id']) && 0 === $data['currency_id']) {
if (isset($data['currency_id']) && null !== $data['currency_id'] && 0 === $data['currency_id']) {
unset($data['currency_id']); unset($data['currency_id']);
} }
// find currency, or use default currency instead. // find currency, or use default currency instead.
if (null !== $data['currency_id'] || null !== $data['currency_code']) {
$currency = $this->getCurrency((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null)); $currency = $this->getCurrency((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null));
unset($data['currency_code']); unset($data['currency_code']);
$data['currency_id'] = $currency->id; $data['currency_id'] = $currency->id;
}
if (null === $data['currency_id']) {
$data['currency_id'] = $this->accountRepository->getMetaValue($account, 'currency_id');
}
if (null === $data['account_role']) {
$data['account_role'] = $this->accountRepository->getMetaValue($account, 'account_role');
}
// update all meta data: // update all meta data:
$this->updateMetaData($account, $data); $this->updateMetaData($account, $data);
@ -108,7 +119,7 @@ class AccountUpdateService
} }
// update note: // update note:
if (isset($data['notes'])) { if (isset($data['notes']) && null !== $data['notes']) {
$this->updateNote($account, (string)$data['notes']); $this->updateNote($account, (string)$data['notes']);
} }