mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-15 16:57:09 +00:00
🤖 Auto commit for release 'develop' on 2025-09-07
This commit is contained in:
@@ -478,18 +478,18 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac
|
||||
|
||||
public function getAccountsByType(array $types, ?array $sort = []): Collection
|
||||
{
|
||||
$res = array_intersect([AccountTypeEnum::ASSET->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value], $types);
|
||||
$query = $this->user->accounts();
|
||||
$res = array_intersect([AccountTypeEnum::ASSET->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value], $types);
|
||||
$query = $this->user->accounts();
|
||||
if (0 !== count($types)) {
|
||||
$query->accountTypeIn($types);
|
||||
}
|
||||
|
||||
// add sort parameters
|
||||
$allowed = config('firefly.allowed_db_sort_parameters.Account', []);
|
||||
$sorted = 0;
|
||||
$sorted = 0;
|
||||
if (0 !== count($sort)) {
|
||||
foreach ($sort as $param) {
|
||||
if(in_array($param[0], $allowed, true)) {
|
||||
if (in_array($param[0], $allowed, true)) {
|
||||
$query->orderBy($param[0], $param[1]);
|
||||
++$sorted;
|
||||
}
|
||||
|
@@ -115,12 +115,13 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
public function getJournalLinks(?LinkType $linkType = null): Collection
|
||||
{
|
||||
$query = TransactionJournalLink::with(['source', 'destination'])
|
||||
->leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
|
||||
->leftJoin('transaction_journals as dest_journals', 'journal_links.destination_id', '=', 'dest_journals.id')
|
||||
->where('source_journals.user_id', $this->user->id)
|
||||
->where('dest_journals.user_id', $this->user->id)
|
||||
->whereNull('source_journals.deleted_at')
|
||||
->whereNull('dest_journals.deleted_at');
|
||||
->leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
|
||||
->leftJoin('transaction_journals as dest_journals', 'journal_links.destination_id', '=', 'dest_journals.id')
|
||||
->where('source_journals.user_id', $this->user->id)
|
||||
->where('dest_journals.user_id', $this->user->id)
|
||||
->whereNull('source_journals.deleted_at')
|
||||
->whereNull('dest_journals.deleted_at')
|
||||
;
|
||||
|
||||
if ($linkType instanceof LinkType) {
|
||||
$query->where('journal_links.link_type_id', $linkType->id);
|
||||
@@ -149,7 +150,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
$merged = $outward->merge($inward);
|
||||
|
||||
return $merged->filter(
|
||||
static fn(TransactionJournalLink $link) => null !== $link->source && null !== $link->destination
|
||||
static fn (TransactionJournalLink $link) => null !== $link->source && null !== $link->destination
|
||||
);
|
||||
}
|
||||
|
||||
@@ -188,7 +189,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$link = new TransactionJournalLink();
|
||||
$link = new TransactionJournalLink();
|
||||
$link->linkType()->associate($linkType);
|
||||
if ('inward' === $information['direction']) {
|
||||
app('log')->debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->inward, $inward->id, $outward->id));
|
||||
@@ -229,8 +230,9 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
public function findSpecificLink(LinkType $linkType, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink
|
||||
{
|
||||
return TransactionJournalLink::where('link_type_id', $linkType->id)
|
||||
->where('source_id', $inward->id)
|
||||
->where('destination_id', $outward->id)->first();
|
||||
->where('source_id', $inward->id)
|
||||
->where('destination_id', $outward->id)->first()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +294,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface, UserGroupInterf
|
||||
$journalLink->refresh();
|
||||
}
|
||||
|
||||
$journalLink->link_type_id = $data['link_type_id'] ?? $journalLink->link_type_id;
|
||||
$journalLink->link_type_id = $data['link_type_id'] ?? $journalLink->link_type_id;
|
||||
$journalLink->save();
|
||||
if (array_key_exists('notes', $data) && null !== $data['notes']) {
|
||||
$this->setNoteText($journalLink, $data['notes']);
|
||||
|
@@ -241,7 +241,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
|
||||
Log::debug(sprintf('Will add/remove %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
|
||||
|
||||
// if the amount is positive, make sure it fits in piggy bank:
|
||||
if (1 === bccomp($amount, '0') && -1 === bccomp( $room, $amount)) {
|
||||
if (1 === bccomp($amount, '0') && -1 === bccomp($room, $amount)) {
|
||||
// amount is positive and $room is smaller than $amount
|
||||
Log::debug(sprintf('Room in piggy bank for extra money is %f', $room));
|
||||
Log::debug(sprintf('There is NO room to add %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
|
||||
@@ -259,7 +259,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
|
||||
return $compare;
|
||||
}
|
||||
|
||||
return $amount;
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -272,9 +272,9 @@ class TagRepository implements TagRepositoryInterface, UserGroupInterface
|
||||
$amount = Steam::positive((string) $journal['amount']);
|
||||
$type = $journal['transaction_type_type'];
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
$amount = bcmul( $amount, '-1');
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
$sums[$currencyId][$type] = bcadd((string) $sums[$currencyId][$type], $amount);
|
||||
$sums[$currencyId][$type] = bcadd((string) $sums[$currencyId][$type], $amount);
|
||||
|
||||
$foreignCurrencyId = $journal['foreign_currency_id'];
|
||||
if (null !== $foreignCurrencyId && 0 !== $foreignCurrencyId) {
|
||||
@@ -292,7 +292,7 @@ class TagRepository implements TagRepositoryInterface, UserGroupInterface
|
||||
// add foreign amount to correct type:
|
||||
$amount = Steam::positive((string) $journal['foreign_amount']);
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
$amount = bcmul( $amount, '-1');
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
$sums[$foreignCurrencyId][$type] = bcadd((string) $sums[$foreignCurrencyId][$type], $amount);
|
||||
}
|
||||
|
@@ -50,6 +50,7 @@ use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use function Safe\json_decode;
|
||||
|
||||
/**
|
||||
@@ -143,21 +144,22 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
{
|
||||
$repository = app(AttachmentRepositoryInterface::class);
|
||||
$repository->setUser($this->user);
|
||||
$journals = $group->transactionJournals->pluck('id')->toArray();
|
||||
$set = Attachment::whereIn('attachable_id', $journals)
|
||||
->where('attachable_type', TransactionJournal::class)
|
||||
->where('uploaded', true)
|
||||
->whereNull('deleted_at')->get();
|
||||
$journals = $group->transactionJournals->pluck('id')->toArray();
|
||||
$set = Attachment::whereIn('attachable_id', $journals)
|
||||
->where('attachable_type', TransactionJournal::class)
|
||||
->where('uploaded', true)
|
||||
->whereNull('deleted_at')->get()
|
||||
;
|
||||
|
||||
$result = [];
|
||||
$result = [];
|
||||
|
||||
/** @var Attachment $attachment */
|
||||
foreach ($set as $attachment) {
|
||||
$journalId = $attachment->attachable_id;
|
||||
$result[$journalId] ??= [];
|
||||
$current = $attachment->toArray();
|
||||
$current['file_exists'] = true;
|
||||
$current['notes'] = $repository->getNoteText($attachment);
|
||||
$journalId = $attachment->attachable_id;
|
||||
$result[$journalId] ??= [];
|
||||
$current = $attachment->toArray();
|
||||
$current['file_exists'] = true;
|
||||
$current['notes'] = $repository->getNoteText($attachment);
|
||||
// already determined that this attachable is a TransactionJournal.
|
||||
$current['journal_title'] = $attachment->attachable->description;
|
||||
$result[$journalId][] = $current;
|
||||
@@ -173,8 +175,9 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
{
|
||||
/** @var null|Note $note */
|
||||
$note = Note::where('noteable_id', $journalId)
|
||||
->where('noteable_type', TransactionJournal::class)
|
||||
->first();
|
||||
->where('noteable_type', TransactionJournal::class)
|
||||
->first()
|
||||
;
|
||||
if (null === $note) {
|
||||
return null;
|
||||
}
|
||||
@@ -195,13 +198,14 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
$q->orWhereIn('destination_id', $journals);
|
||||
}
|
||||
)
|
||||
->with(['source', 'destination', 'source.transactions'])
|
||||
->leftJoin('link_types', 'link_types.id', '=', 'journal_links.link_type_id')
|
||||
->get(['journal_links.*', 'link_types.inward', 'link_types.outward', 'link_types.editable']);
|
||||
->with(['source', 'destination', 'source.transactions'])
|
||||
->leftJoin('link_types', 'link_types.id', '=', 'journal_links.link_type_id')
|
||||
->get(['journal_links.*', 'link_types.inward', 'link_types.outward', 'link_types.editable'])
|
||||
;
|
||||
|
||||
/** @var TransactionJournalLink $entry */
|
||||
foreach ($set as $entry) {
|
||||
$journalId = in_array($entry->source_id, $journals, true) ? $entry->source_id : $entry->destination_id;
|
||||
$journalId = in_array($entry->source_id, $journals, true) ? $entry->source_id : $entry->destination_id;
|
||||
$return[$journalId] ??= [];
|
||||
|
||||
// phpstan: the editable field is provided by the query.
|
||||
@@ -247,6 +251,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
return Amount::formatAnything($currency, app('steam')->negative($amount));
|
||||
}
|
||||
|
||||
return Amount::formatAnything($currency, $amount);
|
||||
}
|
||||
|
||||
@@ -262,13 +267,14 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
return '';
|
||||
}
|
||||
|
||||
$currency = $transaction->foreignCurrency;
|
||||
$type = $journal->transactionType->type;
|
||||
$amount = app('steam')->positive($transaction->foreign_amount);
|
||||
$currency = $transaction->foreignCurrency;
|
||||
$type = $journal->transactionType->type;
|
||||
$amount = app('steam')->positive($transaction->foreign_amount);
|
||||
if (TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
return Amount::formatAnything($currency, app('steam')->negative($amount));
|
||||
}
|
||||
return Amount::formatAnything($currency, $amount);
|
||||
|
||||
return Amount::formatAnything($currency, $amount);
|
||||
}
|
||||
|
||||
public function getLocation(int $journalId): ?Location
|
||||
@@ -288,10 +294,11 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
public function getMetaDateFields(int $journalId, array $fields): NullArrayObject
|
||||
{
|
||||
$query = DB::table('journal_meta')
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereIn('name', $fields)
|
||||
->whereNull('deleted_at')
|
||||
->get(['name', 'data']);
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereIn('name', $fields)
|
||||
->whereNull('deleted_at')
|
||||
->get(['name', 'data'])
|
||||
;
|
||||
$return = [];
|
||||
|
||||
foreach ($query as $row) {
|
||||
@@ -307,10 +314,11 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
public function getMetaFields(int $journalId, array $fields): NullArrayObject
|
||||
{
|
||||
$query = DB::table('journal_meta')
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereIn('name', $fields)
|
||||
->whereNull('deleted_at')
|
||||
->get(['name', 'data']);
|
||||
->where('transaction_journal_id', $journalId)
|
||||
->whereIn('name', $fields)
|
||||
->whereNull('deleted_at')
|
||||
->get(['name', 'data'])
|
||||
;
|
||||
$return = [];
|
||||
|
||||
foreach ($query as $row) {
|
||||
@@ -331,8 +339,9 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
$journals = $group->transactionJournals->pluck('id')->toArray();
|
||||
$currency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
|
||||
$data = PiggyBankEvent::whereIn('transaction_journal_id', $journals)
|
||||
->with('piggyBank', 'piggyBank.account')
|
||||
->get(['piggy_bank_events.*']);
|
||||
->with('piggyBank', 'piggyBank.account')
|
||||
->get(['piggy_bank_events.*'])
|
||||
;
|
||||
|
||||
/** @var PiggyBankEvent $row */
|
||||
foreach ($data as $row) {
|
||||
@@ -340,13 +349,14 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
continue;
|
||||
}
|
||||
// get currency preference.
|
||||
$currencyPreference = AccountMeta::where('account_id', $row->piggyBank->account_id)
|
||||
->where('name', 'currency_id')
|
||||
->first();
|
||||
$currencyPreference = AccountMeta::where('account_id', $row->piggyBank->account_id)
|
||||
->where('name', 'currency_id')
|
||||
->first()
|
||||
;
|
||||
if (null !== $currencyPreference) {
|
||||
$currency = TransactionCurrency::where('id', $currencyPreference->data)->first();
|
||||
}
|
||||
$journalId = $row->transaction_journal_id;
|
||||
$journalId = $row->transaction_journal_id;
|
||||
$return[$journalId] ??= [];
|
||||
|
||||
$return[$journalId][] = [
|
||||
@@ -373,10 +383,11 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface,
|
||||
public function getTags(int $journalId): array
|
||||
{
|
||||
$result = DB::table('tag_transaction_journal')
|
||||
->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
|
||||
->where('tag_transaction_journal.transaction_journal_id', $journalId)
|
||||
->orderBy('tags.tag', 'ASC')
|
||||
->get(['tags.tag']);
|
||||
->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
|
||||
->where('tag_transaction_journal.transaction_journal_id', $journalId)
|
||||
->orderBy('tags.tag', 'ASC')
|
||||
->get(['tags.tag'])
|
||||
;
|
||||
|
||||
return $result->pluck('tag')->toArray();
|
||||
}
|
||||
|
@@ -229,7 +229,7 @@ class UserRepository implements UserRepositoryInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function hasRole(null|Authenticatable|User $user, string $role): bool
|
||||
public function hasRole(Authenticatable|User|null $user, string $role): bool
|
||||
{
|
||||
if (!$user instanceof Authenticatable) {
|
||||
return false;
|
||||
@@ -270,7 +270,7 @@ class UserRepository implements UserRepositoryInterface
|
||||
return $collection;
|
||||
}
|
||||
|
||||
public function inviteUser(null|Authenticatable|User $user, string $email): InvitedUser
|
||||
public function inviteUser(Authenticatable|User|null $user, string $email): InvitedUser
|
||||
{
|
||||
if (!$user instanceof User) {
|
||||
throw new FireflyException('User is not a User object.');
|
||||
|
@@ -105,9 +105,9 @@ interface UserRepositoryInterface
|
||||
|
||||
public function getUserGroups(User $user): Collection;
|
||||
|
||||
public function hasRole(null|Authenticatable|User $user, string $role): bool;
|
||||
public function hasRole(Authenticatable|User|null $user, string $role): bool;
|
||||
|
||||
public function inviteUser(null|Authenticatable|User $user, string $email): InvitedUser;
|
||||
public function inviteUser(Authenticatable|User|null $user, string $email): InvitedUser;
|
||||
|
||||
public function redeemCode(string $code): void;
|
||||
|
||||
|
Reference in New Issue
Block a user