mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-18 18:44:16 +00:00
Fix piggy bank orders
This commit is contained in:
@@ -39,7 +39,8 @@ use Illuminate\Database\QueryException;
|
|||||||
class PiggyBankFactory
|
class PiggyBankFactory
|
||||||
{
|
{
|
||||||
use CreatesObjectGroups;
|
use CreatesObjectGroups;
|
||||||
public User $user {
|
|
||||||
|
public User $user {
|
||||||
set(User $value) {
|
set(User $value) {
|
||||||
$this->user = $value;
|
$this->user = $value;
|
||||||
$this->currencyRepository->setUser($value);
|
$this->currencyRepository->setUser($value);
|
||||||
@@ -47,14 +48,14 @@ class PiggyBankFactory
|
|||||||
$this->piggyBankRepository->setUser($value);
|
$this->piggyBankRepository->setUser($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private CurrencyRepositoryInterface $currencyRepository;
|
private CurrencyRepositoryInterface $currencyRepository;
|
||||||
private AccountRepositoryInterface $accountRepository;
|
private AccountRepositoryInterface $accountRepository;
|
||||||
private PiggyBankRepositoryInterface $piggyBankRepository;
|
private PiggyBankRepositoryInterface $piggyBankRepository;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||||
$this->piggyBankRepository = app(PiggyBankRepositoryInterface::class);
|
$this->piggyBankRepository = app(PiggyBankRepositoryInterface::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,23 +66,24 @@ class PiggyBankFactory
|
|||||||
*
|
*
|
||||||
* @return PiggyBank
|
* @return PiggyBank
|
||||||
*/
|
*/
|
||||||
public function store(array $data): PiggyBank {
|
public function store(array $data): PiggyBank
|
||||||
|
{
|
||||||
|
|
||||||
$piggyBankData =$data;
|
$piggyBankData = $data;
|
||||||
|
|
||||||
// unset some fields
|
// unset some fields
|
||||||
unset($piggyBankData['object_group_title'],$piggyBankData['transaction_currency_code'],$piggyBankData['transaction_currency_id'],$piggyBankData['accounts'], $piggyBankData['object_group_id'], $piggyBankData['notes']);
|
unset($piggyBankData['object_group_title'], $piggyBankData['transaction_currency_code'], $piggyBankData['transaction_currency_id'], $piggyBankData['accounts'], $piggyBankData['object_group_id'], $piggyBankData['notes']);
|
||||||
|
|
||||||
// validate amount:
|
// validate amount:
|
||||||
if (array_key_exists('target_amount', $piggyBankData) && '' === (string)$piggyBankData['target_amount']) {
|
if (array_key_exists('target_amount', $piggyBankData) && '' === (string) $piggyBankData['target_amount']) {
|
||||||
$piggyBankData['target_amount'] = '0';
|
$piggyBankData['target_amount'] = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
$piggyBankData['start_date_tz'] = $piggyBankData['start_date']?->format('e');
|
$piggyBankData['start_date_tz'] = $piggyBankData['start_date']?->format('e');
|
||||||
$piggyBankData['target_date_tz'] = $piggyBankData['target_date']?->format('e');
|
$piggyBankData['target_date_tz'] = $piggyBankData['target_date']?->format('e');
|
||||||
$piggyBankData['account_id'] = null;
|
$piggyBankData['account_id'] = null;
|
||||||
$piggyBankData['transaction_currency_id'] = $this->getCurrency($data)->id;
|
$piggyBankData['transaction_currency_id'] = $this->getCurrency($data)->id;
|
||||||
$piggyBankData['order'] = 131337;
|
$piggyBankData['order'] = 131337;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/** @var PiggyBank $piggyBank */
|
/** @var PiggyBank $piggyBank */
|
||||||
@@ -95,7 +97,7 @@ class PiggyBankFactory
|
|||||||
$this->linkToAccountIds($piggyBank, $data['accounts']);
|
$this->linkToAccountIds($piggyBank, $data['accounts']);
|
||||||
$this->piggyBankRepository->updateNote($piggyBank, $data['notes']);
|
$this->piggyBankRepository->updateNote($piggyBank, $data['notes']);
|
||||||
|
|
||||||
$objectGroupTitle = $data['object_group_title'] ?? '';
|
$objectGroupTitle = $data['object_group_title'] ?? '';
|
||||||
if ('' !== $objectGroupTitle) {
|
if ('' !== $objectGroupTitle) {
|
||||||
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
|
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
|
||||||
if (null !== $objectGroup) {
|
if (null !== $objectGroup) {
|
||||||
@@ -104,7 +106,7 @@ class PiggyBankFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try also with ID
|
// try also with ID
|
||||||
$objectGroupId = (int)($data['object_group_id'] ?? 0);
|
$objectGroupId = (int) ($data['object_group_id'] ?? 0);
|
||||||
if (0 !== $objectGroupId) {
|
if (0 !== $objectGroupId) {
|
||||||
$objectGroup = $this->findObjectGroupById($objectGroupId);
|
$objectGroup = $this->findObjectGroupById($objectGroupId);
|
||||||
if (null !== $objectGroup) {
|
if (null !== $objectGroup) {
|
||||||
@@ -118,15 +120,19 @@ class PiggyBankFactory
|
|||||||
|
|
||||||
public function find(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank
|
public function find(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank
|
||||||
{
|
{
|
||||||
$piggyBankId = (int)$piggyBankId;
|
$piggyBankId = (int) $piggyBankId;
|
||||||
$piggyBankName = (string)$piggyBankName;
|
$piggyBankName = (string) $piggyBankName;
|
||||||
if ('' === $piggyBankName && 0 === $piggyBankId) {
|
if ('' === $piggyBankName && 0 === $piggyBankId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// first find by ID:
|
// first find by ID:
|
||||||
if ($piggyBankId > 0) {
|
if ($piggyBankId > 0) {
|
||||||
/** @var null|PiggyBank $piggyBank */
|
$piggyBank = PiggyBank
|
||||||
$piggyBank = $this->user->piggyBanks()->find($piggyBankId);
|
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||||
|
->where('accounts.user_id', $this->user->id)
|
||||||
|
->where('piggy_banks.id', $piggyBankId)
|
||||||
|
->first(['piggy_banks.*']);
|
||||||
if (null !== $piggyBank) {
|
if (null !== $piggyBank) {
|
||||||
return $piggyBank;
|
return $piggyBank;
|
||||||
}
|
}
|
||||||
@@ -146,26 +152,33 @@ class PiggyBankFactory
|
|||||||
|
|
||||||
public function findByName(string $name): ?PiggyBank
|
public function findByName(string $name): ?PiggyBank
|
||||||
{
|
{
|
||||||
return $this->user->piggyBanks()->where('piggy_banks.name', $name)->first();
|
return PiggyBank
|
||||||
|
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||||
|
->where('accounts.user_id', $this->user->id)
|
||||||
|
->where('piggy_banks.name', $name)
|
||||||
|
->first(['piggy_banks.*']);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getCurrency(array $data): TransactionCurrency {
|
private function getCurrency(array $data): TransactionCurrency
|
||||||
|
{
|
||||||
// currency:
|
// currency:
|
||||||
$defaultCurrency = app('amount')->getDefaultCurrency();
|
$defaultCurrency = app('amount')->getDefaultCurrency();
|
||||||
$currency = null;
|
$currency = null;
|
||||||
if (array_key_exists('transaction_currency_code', $data)) {
|
if (array_key_exists('transaction_currency_code', $data)) {
|
||||||
$currency = $this->currencyRepository->findByCode((string)($data['transaction_currency_code'] ?? ''));
|
$currency = $this->currencyRepository->findByCode((string) ($data['transaction_currency_code'] ?? ''));
|
||||||
}
|
}
|
||||||
if (array_key_exists('transaction_currency_id', $data)) {
|
if (array_key_exists('transaction_currency_id', $data)) {
|
||||||
$currency = $this->currencyRepository->find((int)($data['transaction_currency_id'] ?? 0));
|
$currency = $this->currencyRepository->find((int) ($data['transaction_currency_id'] ?? 0));
|
||||||
}
|
}
|
||||||
$currency ??= $defaultCurrency;
|
$currency ??= $defaultCurrency;
|
||||||
return $currency;
|
return $currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setOrder(PiggyBank $piggyBank, array $data): PiggyBank {
|
private function setOrder(PiggyBank $piggyBank, array $data): PiggyBank
|
||||||
|
{
|
||||||
$this->resetOrder();
|
$this->resetOrder();
|
||||||
$order = $this->getMaxOrder() + 1;
|
$order = $this->getMaxOrder() + 1;
|
||||||
if (array_key_exists('order', $data)) {
|
if (array_key_exists('order', $data)) {
|
||||||
$order = $data['order'];
|
$order = $data['order'];
|
||||||
}
|
}
|
||||||
@@ -178,13 +191,12 @@ class PiggyBankFactory
|
|||||||
public function resetOrder(): void
|
public function resetOrder(): void
|
||||||
{
|
{
|
||||||
// TODO duplicate code
|
// TODO duplicate code
|
||||||
$set = PiggyBank
|
$set = PiggyBank
|
||||||
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||||
->where('accounts.user_id', $this->user->id)
|
->where('accounts.user_id', $this->user->id)
|
||||||
->with(
|
->with(
|
||||||
[
|
[
|
||||||
'account',
|
|
||||||
'objectGroups',
|
'objectGroups',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -207,19 +219,20 @@ class PiggyBankFactory
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function linkToAccountIds(PiggyBank $piggyBank, array $accounts): void {
|
public function linkToAccountIds(PiggyBank $piggyBank, array $accounts): void
|
||||||
|
{
|
||||||
$toBeLinked = [];
|
$toBeLinked = [];
|
||||||
/** @var array $info */
|
/** @var array $info */
|
||||||
foreach($accounts as $info) {
|
foreach ($accounts as $info) {
|
||||||
$account = $this->accountRepository->find((int)($info['account_id'] ?? 0));
|
$account = $this->accountRepository->find((int) ($info['account_id'] ?? 0));
|
||||||
if(null === $account) {
|
if (null === $account) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(array_key_exists('current_amount',$info)) {
|
if (array_key_exists('current_amount', $info)) {
|
||||||
$toBeLinked[$account->id] = ['current_amount' => $info['current_amount']];
|
$toBeLinked[$account->id] = ['current_amount' => $info['current_amount']];
|
||||||
//$piggyBank->accounts()->syncWithoutDetaching([$account->id => ['current_amount' => $info['current_amount'] ?? '0']]);
|
//$piggyBank->accounts()->syncWithoutDetaching([$account->id => ['current_amount' => $info['current_amount'] ?? '0']]);
|
||||||
}
|
}
|
||||||
if(!array_key_exists('current_amount', $info)) {
|
if (!array_key_exists('current_amount', $info)) {
|
||||||
$toBeLinked[$account->id] = [];
|
$toBeLinked[$account->id] = [];
|
||||||
//$piggyBank->accounts()->syncWithoutDetaching([$account->id]);
|
//$piggyBank->accounts()->syncWithoutDetaching([$account->id]);
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
|||||||
namespace FireflyIII\Handlers\Observer;
|
namespace FireflyIII\Handlers\Observer;
|
||||||
|
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
|
use FireflyIII\Models\PiggyBank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AccountObserver
|
* Class AccountObserver
|
||||||
@@ -38,8 +39,9 @@ class AccountObserver
|
|||||||
{
|
{
|
||||||
app('log')->debug('Observe "deleting" of an account.');
|
app('log')->debug('Observe "deleting" of an account.');
|
||||||
$account->accountMeta()->delete();
|
$account->accountMeta()->delete();
|
||||||
|
/** @var PiggyBank $piggy */
|
||||||
foreach ($account->piggyBanks()->get() as $piggy) {
|
foreach ($account->piggyBanks()->get() as $piggy) {
|
||||||
$piggy->delete();
|
$piggy->accounts()->detach($account);
|
||||||
}
|
}
|
||||||
foreach ($account->attachments()->get() as $attachment) {
|
foreach ($account->attachments()->get() as $attachment) {
|
||||||
$attachment->delete();
|
$attachment->delete();
|
||||||
|
@@ -29,7 +29,9 @@ use Exception;
|
|||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Http\Middleware\IsDemoUser;
|
use FireflyIII\Http\Middleware\IsDemoUser;
|
||||||
use FireflyIII\Models\AccountType;
|
use FireflyIII\Models\AccountType;
|
||||||
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\TransactionType;
|
use FireflyIII\Models\TransactionType;
|
||||||
|
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||||
use FireflyIII\Support\Http\Controllers\GetConfigurationData;
|
use FireflyIII\Support\Http\Controllers\GetConfigurationData;
|
||||||
use FireflyIII\Support\Models\AccountBalanceCalculator;
|
use FireflyIII\Support\Models\AccountBalanceCalculator;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
@@ -291,7 +293,10 @@ class DebugController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// has piggies
|
// has piggies
|
||||||
if ($user->piggyBanks()->count() > 0) {
|
$repository = app(PiggyBankRepositoryInterface::class);
|
||||||
|
$repository->setUser($user);
|
||||||
|
|
||||||
|
if ($repository->getPiggyBanks()->count() > 0) {
|
||||||
$flags[] = '<span title="Has piggy banks">:pig:</span>';
|
$flags[] = '<span title="Has piggy banks">:pig:</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -120,6 +120,7 @@ class HomeController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(AccountRepositoryInterface $repository): mixed
|
public function index(AccountRepositoryInterface $repository): mixed
|
||||||
{
|
{
|
||||||
|
|
||||||
$types = config('firefly.accountTypesByIdentifier.asset');
|
$types = config('firefly.accountTypesByIdentifier.asset');
|
||||||
$count = $repository->count($types);
|
$count = $repository->count($types);
|
||||||
Log::channel('audit')->info('User visits homepage.');
|
Log::channel('audit')->info('User visits homepage.');
|
||||||
|
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace FireflyIII\Models;
|
namespace FireflyIII\Models;
|
||||||
|
|
||||||
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -55,7 +56,7 @@ class PiggyBank extends Model
|
|||||||
'target_amount' => 'string',
|
'target_amount' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $fillable = ['name', 'account_id', 'order', 'target_amount', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'active', 'transaction_currency_id'];
|
protected $fillable = ['name', 'order', 'target_amount', 'start_date', 'start_date_tz', 'target_date', 'target_date_tz', 'active', 'transaction_currency_id'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
* Route binder. Converts the key in the URL to the specified object (or throw 404).
|
||||||
@@ -83,10 +84,9 @@ class PiggyBank extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(TransactionCurrency::class);
|
return $this->belongsTo(TransactionCurrency::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function account(): BelongsTo
|
public function account(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Account::class);
|
throw new FireflyException('This method is not available on PiggyBank.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attachments(): MorphMany
|
public function attachments(): MorphMany
|
||||||
|
@@ -204,21 +204,26 @@ trait ModifiesPiggyBanks
|
|||||||
$oldOrder = $piggyBank->order;
|
$oldOrder = $piggyBank->order;
|
||||||
// app('log')->debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
|
// app('log')->debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
|
||||||
if ($newOrder > $oldOrder) {
|
if ($newOrder > $oldOrder) {
|
||||||
$this->user->piggyBanks()->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder)
|
PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
->where('piggy_banks.id', '!=', $piggyBank->id)
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||||
->decrement('piggy_banks.order')
|
->where('accounts.user_id', $this->user->id)
|
||||||
;
|
->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder)
|
||||||
|
->where('piggy_banks.id', '!=', $piggyBank->id)
|
||||||
|
->distinct()->decrement('piggy_banks.order');
|
||||||
|
|
||||||
$piggyBank->order = $newOrder;
|
$piggyBank->order = $newOrder;
|
||||||
app('log')->debug(sprintf('[1] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
|
app('log')->debug(sprintf('[1] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
|
||||||
$piggyBank->save();
|
$piggyBank->save();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
|
||||||
$this->user->piggyBanks()->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder)
|
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
|
||||||
|
->where('accounts.user_id', $this->user->id)
|
||||||
|
->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder)
|
||||||
->where('piggy_banks.id', '!=', $piggyBank->id)
|
->where('piggy_banks.id', '!=', $piggyBank->id)
|
||||||
->increment('piggy_banks.order')
|
->distinct()->increment('piggy_banks.order');
|
||||||
;
|
|
||||||
$piggyBank->order = $newOrder;
|
$piggyBank->order = $newOrder;
|
||||||
app('log')->debug(sprintf('[2] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
|
app('log')->debug(sprintf('[2] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
|
||||||
$piggyBank->save();
|
$piggyBank->save();
|
||||||
|
@@ -289,7 +289,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
->where('accounts.user_id', auth()->user()->id)
|
->where('accounts.user_id', auth()->user()->id)
|
||||||
->with(
|
->with(
|
||||||
[
|
[
|
||||||
'account',
|
|
||||||
'objectGroups',
|
'objectGroups',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
@@ -36,6 +36,7 @@ use FireflyIII\Models\Category;
|
|||||||
use FireflyIII\Models\CurrencyExchangeRate;
|
use FireflyIII\Models\CurrencyExchangeRate;
|
||||||
use FireflyIII\Models\GroupMembership;
|
use FireflyIII\Models\GroupMembership;
|
||||||
use FireflyIII\Models\ObjectGroup;
|
use FireflyIII\Models\ObjectGroup;
|
||||||
|
use FireflyIII\Models\PiggyBank;
|
||||||
use FireflyIII\Models\Preference;
|
use FireflyIII\Models\Preference;
|
||||||
use FireflyIII\Models\Recurrence;
|
use FireflyIII\Models\Recurrence;
|
||||||
use FireflyIII\Models\Role;
|
use FireflyIII\Models\Role;
|
||||||
|
Reference in New Issue
Block a user