Reformat various code.

This commit is contained in:
James Cole 2022-03-29 14:59:58 +02:00
parent 29bed2547c
commit d1a09ff33b
No known key found for this signature in database
GPG Key ID: B49A324B7EAD6D80
115 changed files with 2700 additions and 2699 deletions

View File

@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Jobs;
use Carbon\Carbon;
use FireflyIII\Events\RequestedReportOnJournals;
use FireflyIII\Events\WarnUserAboutBill;
use FireflyIII\Models\Bill;
use Illuminate\Bus\Queueable;

View File

@ -53,6 +53,6 @@ class AccessTokenCreatedMail extends Mailable
{
return $this
->markdown('emails.token-created')
->subject((string)trans('email.access_token_created_subject'));
->subject((string) trans('email.access_token_created_subject'));
}
}

View File

@ -46,7 +46,7 @@ class AdminTestMail extends Mailable
*/
public function __construct(string $email)
{
$this->email = $email;
$this->email = $email;
}
/**
@ -58,6 +58,6 @@ class AdminTestMail extends Mailable
{
return $this
->markdown('emails.admin-test')
->subject((string)trans('email.admin_test_subject'));
->subject((string) trans('email.admin_test_subject'));
}
}

View File

@ -34,8 +34,8 @@ class BillWarningMail extends Mailable
use Queueable, SerializesModels;
public Bill $bill;
public string $field;
public int $diff;
public string $field;
/**
* ConfirmEmailChangeMail constructor.
@ -46,9 +46,9 @@ class BillWarningMail extends Mailable
*/
public function __construct(Bill $bill, string $field, int $diff)
{
$this->bill = $bill;
$this->field = $field;
$this->diff = $diff;
$this->bill = $bill;
$this->field = $field;
$this->diff = $diff;
}
/**

View File

@ -51,9 +51,9 @@ class ConfirmEmailChangeMail extends Mailable
*/
public function __construct(string $newEmail, string $oldEmail, string $url)
{
$this->newEmail = $newEmail;
$this->oldEmail = $oldEmail;
$this->url = $url;
$this->newEmail = $newEmail;
$this->oldEmail = $oldEmail;
$this->url = $url;
}
/**
@ -66,7 +66,7 @@ class ConfirmEmailChangeMail extends Mailable
return $this
//->view('emails.confirm-email-change-html')
//->text('emails.confirm-email-change-text')
->markdown('emails.confirm-email-change')
->markdown('emails.confirm-email-change')
->subject((string) trans('email.email_change_subject'));
}
}

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Mail;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
@ -56,11 +57,11 @@ class NewIPAddressWarningMail extends Mailable
*/
public function build(): self
{
$this->time = now(config('app.timezone'))->isoFormat((string)trans('config.date_time_js'));
$this->time = now(config('app.timezone'))->isoFormat((string) trans('config.date_time_js'));
$this->host = '';
try {
$hostName = gethostbyaddr($this->ipAddress);
} catch(\Exception $e) {
} catch (Exception $e) {
$hostName = $this->ipAddress;
}
if ($hostName !== $this->ipAddress) {
@ -69,6 +70,6 @@ class NewIPAddressWarningMail extends Mailable
return $this
->markdown('emails.new-ip')
->subject((string)trans('email.login_from_new_ip'));
->subject((string) trans('email.login_from_new_ip'));
}
}

View File

@ -47,7 +47,7 @@ class RegisteredUser extends Mailable
*/
public function __construct(string $address)
{
$this->address = $address;
$this->address = $address;
}
/**
@ -59,6 +59,6 @@ class RegisteredUser extends Mailable
{
return $this
->markdown('emails.registered')
->subject((string)trans('email.registered_subject'));
->subject((string) trans('email.registered_subject'));
}
}

View File

@ -46,7 +46,7 @@ class RequestedNewPassword extends Mailable
*/
public function __construct(string $url)
{
$this->url = $url;
$this->url = $url;
}
/**
@ -58,6 +58,6 @@ class RequestedNewPassword extends Mailable
{
return $this
->markdown('emails.password')
->subject((string)trans('email.reset_pw_subject'));
->subject((string) trans('email.reset_pw_subject'));
}
}

View File

@ -48,9 +48,9 @@ class UndoEmailChangeMail extends Mailable
*/
public function __construct(string $newEmail, string $oldEmail, string $url)
{
$this->newEmail = $newEmail;
$this->oldEmail = $oldEmail;
$this->url = $url;
$this->newEmail = $newEmail;
$this->oldEmail = $oldEmail;
$this->url = $url;
}
/**
@ -62,6 +62,6 @@ class UndoEmailChangeMail extends Mailable
{
return $this
->markdown('emails.undo-email-change')
->subject((string)trans('email.email_change_subject'));
->subject((string) trans('email.email_change_subject'));
}
}

View File

@ -138,7 +138,7 @@ class Account extends Model
public static function routeBinder(string $value): Account
{
if (auth()->check()) {
$accountId = (int)$value;
$accountId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Account $account */
@ -266,7 +266,7 @@ class Account extends Model
*/
public function setVirtualBalanceAttribute($value): void
{
$value = (string)$value;
$value = (string) $value;
if ('' === $value) {
$value = null;
}

View File

@ -49,34 +49,34 @@ use Illuminate\Support\Carbon;
*/
class AccountType extends Model
{
/** @var string */
public const DEFAULT = 'Default account';
/** @var string */
public const CASH = 'Cash account';
/** @var string */
public const ASSET = 'Asset account';
/** @var string */
public const EXPENSE = 'Expense account';
/** @var string */
public const REVENUE = 'Revenue account';
/** @var string */
public const INITIAL_BALANCE = 'Initial balance account';
/** @var string */
public const BENEFICIARY = 'Beneficiary account';
/** @var string */
public const IMPORT = 'Import account';
/** @var string */
public const RECONCILIATION = 'Reconciliation account';
/** @var string */
public const LOAN = 'Loan';
/** @var string */
public const DEBT = 'Debt';
/** @var string */
public const MORTGAGE = 'Mortgage';
public const CASH = 'Cash account';
/** @var string */
public const CREDITCARD = 'Credit card';
/** @var string */
public const DEBT = 'Debt';
/** @var string */
public const DEFAULT = 'Default account';
/** @var string */
public const EXPENSE = 'Expense account';
/** @var string */
public const IMPORT = 'Import account';
/** @var string */
public const INITIAL_BALANCE = 'Initial balance account';
/** @var string */
public const LIABILITY_CREDIT = 'Liability credit account';
/** @var string */
public const LOAN = 'Loan';
/** @var string */
public const MORTGAGE = 'Mortgage';
/** @var string */
public const RECONCILIATION = 'Reconciliation account';
/** @var string */
public const REVENUE = 'Revenue account';
/**
* The attributes that should be casted to native types.
*

View File

@ -111,7 +111,7 @@ class Attachment extends Model
public static function routeBinder(string $value): Attachment
{
if (auth()->check()) {
$attachmentId = (int)$value;
$attachmentId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Attachment $attachment */
@ -143,7 +143,7 @@ class Attachment extends Model
*/
public function fileName(): string
{
return sprintf('at-%s.data', (string)$this->id);
return sprintf('at-%s.data', (string) $this->id);
}
/**

View File

@ -96,7 +96,7 @@ class AvailableBudget extends Model
public static function routeBinder(string $value): AvailableBudget
{
if (auth()->check()) {
$availableBudgetId = (int)$value;
$availableBudgetId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var AvailableBudget $availableBudget */

View File

@ -139,7 +139,7 @@ class Bill extends Model
public static function routeBinder(string $value): Bill
{
if (auth()->check()) {
$billId = (int)$value;
$billId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Bill $bill */
@ -184,7 +184,7 @@ class Bill extends Model
*/
public function setAmountMaxAttribute($value): void
{
$this->attributes['amount_max'] = (string)$value;
$this->attributes['amount_max'] = (string) $value;
}
/**
@ -194,7 +194,7 @@ class Bill extends Model
*/
public function setAmountMinAttribute($value): void
{
$this->attributes['amount_min'] = (string)$value;
$this->attributes['amount_min'] = (string) $value;
}
/**

View File

@ -38,26 +38,26 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Budget
*
* @property int $id
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property Carbon|null $deleted_at
* @property int $user_id
* @property string $name
* @property bool $active
* @property bool $encrypted
* @property int $order
* @property-read Collection|Attachment[] $attachments
* @property-read int|null $attachments_count
* @property-read Collection|AutoBudget[] $autoBudgets
* @property-read int|null $auto_budgets_count
* @property-read Collection|BudgetLimit[] $budgetlimits
* @property-read int|null $budgetlimits_count
* @property-read Collection|TransactionJournal[] $transactionJournals
* @property-read int|null $transaction_journals_count
* @property-read Collection|Transaction[] $transactions
* @property-read int|null $transactions_count
* @property-read User $user
* @property int $id
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property Carbon|null $deleted_at
* @property int $user_id
* @property string $name
* @property bool $active
* @property bool $encrypted
* @property int $order
* @property-read Collection|Attachment[] $attachments
* @property-read int|null $attachments_count
* @property-read Collection|AutoBudget[] $autoBudgets
* @property-read int|null $auto_budgets_count
* @property-read Collection|BudgetLimit[] $budgetlimits
* @property-read int|null $budgetlimits_count
* @property-read Collection|TransactionJournal[] $transactionJournals
* @property-read int|null $transaction_journals_count
* @property-read Collection|Transaction[] $transactions
* @property-read int|null $transactions_count
* @property-read User $user
* @method static \Illuminate\Database\Eloquent\Builder|Budget newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Budget newQuery()
* @method static Builder|Budget onlyTrashed()
@ -74,11 +74,11 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|Budget withTrashed()
* @method static Builder|Budget withoutTrashed()
* @mixin Eloquent
* @property string $email
* @property int|null $user_group_id
* @property string $email
* @property int|null $user_group_id
* @method static \Illuminate\Database\Eloquent\Builder|Budget whereUserGroupId($value)
* @property-read Collection|\FireflyIII\Models\Note[] $notes
* @property-read int|null $notes_count
* @property-read Collection|Note[] $notes
* @property-read int|null $notes_count
*/
class Budget extends Model
{
@ -113,7 +113,7 @@ class Budget extends Model
public static function routeBinder(string $value): Budget
{
if (auth()->check()) {
$budgetId = (int)$value;
$budgetId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Budget $budget */

View File

@ -90,7 +90,7 @@ class BudgetLimit extends Model
public static function routeBinder(string $value): BudgetLimit
{
if (auth()->check()) {
$budgetLimitId = (int)$value;
$budgetLimitId = (int) $value;
$budgetLimit = self::where('budget_limits.id', $budgetLimitId)
->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
->where('budgets.user_id', auth()->user()->id)

View File

@ -104,7 +104,7 @@ class Category extends Model
public static function routeBinder(string $value): Category
{
if (auth()->check()) {
$categoryId = (int)$value;
$categoryId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Category $category */

View File

@ -93,7 +93,7 @@ class LinkType extends Model
public static function routeBinder(string $value): LinkType
{
if (auth()->check()) {
$linkTypeId = (int)$value;
$linkTypeId = (int) $value;
$linkType = self::find($linkTypeId);
if (null !== $linkType) {
return $linkType;

View File

@ -90,7 +90,7 @@ class ObjectGroup extends Model
public static function routeBinder(string $value): ObjectGroup
{
if (auth()->check()) {
$objectGroupId = (int)$value;
$objectGroupId = (int) $value;
/** @var ObjectGroup $objectGroup */
$objectGroup = self::where('object_groups.id', $objectGroupId)
->where('object_groups.user_id', auth()->user()->id)->first();

View File

@ -115,7 +115,7 @@ class PiggyBank extends Model
public static function routeBinder(string $value): PiggyBank
{
if (auth()->check()) {
$piggyBankId = (int)$value;
$piggyBankId = (int) $value;
$piggyBank = self::where('piggy_banks.id', $piggyBankId)
->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
->where('accounts.user_id', auth()->user()->id)->first(['piggy_banks.*']);
@ -186,6 +186,6 @@ class PiggyBank extends Model
*/
public function setTargetamountAttribute($value): void
{
$this->attributes['targetamount'] = (string)$value;
$this->attributes['targetamount'] = (string) $value;
}
}

View File

@ -86,7 +86,7 @@ class PiggyBankEvent extends Model
*/
public function setAmountAttribute($value): void
{
$this->attributes['amount'] = (string)$value;
$this->attributes['amount'] = (string) $value;
}
/**

View File

@ -31,14 +31,14 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* FireflyIII\Models\PiggyBankRepetition
*
* @property int $id
* @property int $id
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property int $piggy_bank_id
* @property int $piggy_bank_id
* @property \Illuminate\Support\Carbon|null $startdate
* @property \Illuminate\Support\Carbon|null $targetdate
* @property string $currentamount
* @property-read PiggyBank $piggyBank
* @property string $currentamount
* @property-read PiggyBank $piggyBank
* @method static EloquentBuilder|PiggyBankRepetition newModelQuery()
* @method static EloquentBuilder|PiggyBankRepetition newQuery()
* @method static EloquentBuilder|PiggyBankRepetition onDates(Carbon $start, Carbon $target)
@ -124,6 +124,6 @@ class PiggyBankRepetition extends Model
*/
public function setCurrentamountAttribute($value): void
{
$this->attributes['currentamount'] = (string)$value;
$this->attributes['currentamount'] = (string) $value;
}
}

View File

@ -130,7 +130,7 @@ class Recurrence extends Model
public static function routeBinder(string $value): Recurrence
{
if (auth()->check()) {
$recurrenceId = (int)$value;
$recurrenceId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Recurrence $recurrence */

View File

@ -111,7 +111,7 @@ class Rule extends Model
public static function routeBinder(string $value): Rule
{
if (auth()->check()) {
$ruleId = (int)$value;
$ruleId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Rule $rule */

View File

@ -102,7 +102,7 @@ class RuleGroup extends Model
public static function routeBinder(string $value): RuleGroup
{
if (auth()->check()) {
$ruleGroupId = (int)$value;
$ruleGroupId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var RuleGroup $ruleGroup */

View File

@ -113,7 +113,7 @@ class Tag extends Model
public static function routeBinder(string $value): Tag
{
if (auth()->check()) {
$tagId = (int)$value;
$tagId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Tag $tag */

View File

@ -236,7 +236,7 @@ class Transaction extends Model
*/
public function setAmountAttribute($value): void
{
$this->attributes['amount'] = (string)$value;
$this->attributes['amount'] = (string) $value;
}
/**

View File

@ -97,7 +97,7 @@ class TransactionCurrency extends Model
public static function routeBinder(string $value): TransactionCurrency
{
if (auth()->check()) {
$currencyId = (int)$value;
$currencyId = (int) $value;
$currency = self::find($currencyId);
if (null !== $currency) {
return $currency;

View File

@ -94,7 +94,7 @@ class TransactionGroup extends Model
public static function routeBinder(string $value): TransactionGroup
{
if (auth()->check()) {
$groupId = (int)$value;
$groupId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var TransactionGroup $group */

View File

@ -160,7 +160,7 @@ class TransactionJournal extends Model
public static function routeBinder(string $value): TransactionJournal
{
if (auth()->check()) {
$journalId = (int)$value;
$journalId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var TransactionJournal $journal */

View File

@ -87,7 +87,7 @@ class TransactionJournalLink extends Model
public static function routeBinder(string $value): TransactionJournalLink
{
if (auth()->check()) {
$linkId = (int)$value;
$linkId = (int) $value;
$link = self::where('journal_links.id', $linkId)
->leftJoin('transaction_journals as t_a', 't_a.id', '=', 'source_id')
->leftJoin('transaction_journals as t_b', 't_b.id', '=', 'destination_id')

View File

@ -58,20 +58,20 @@ class TransactionType extends Model
{
use SoftDeletes;
/** @var string */
public const WITHDRAWAL = 'Withdrawal';
/** @var string */
public const DEPOSIT = 'Deposit';
/** @var string */
public const TRANSFER = 'Transfer';
public const INVALID = 'Invalid';
/** @var string */
public const LIABILITY_CREDIT = 'Liability credit';
/** @var string */
public const OPENING_BALANCE = 'Opening balance';
/** @var string */
public const RECONCILIATION = 'Reconciliation';
/** @var string */
public const INVALID = 'Invalid';
public const TRANSFER = 'Transfer';
/** @var string */
public const LIABILITY_CREDIT = 'Liability credit';
public const WITHDRAWAL = 'Withdrawal';
/** @var string[] */
protected $casts
= [

View File

@ -53,14 +53,14 @@ use Illuminate\Support\Carbon;
*/
class UserRole extends Model
{
public const READ_ONLY = 'ro';
public const CHANGE_TRANSACTIONS = 'change_tx';
public const CHANGE_RULES = 'change_rules';
public const CHANGE_PIGGY_BANKS = 'change_piggies';
public const CHANGE_REPETITIONS = 'change_reps';
public const VIEW_REPORTS = 'view_reports';
public const CHANGE_RULES = 'change_rules';
public const CHANGE_TRANSACTIONS = 'change_tx';
public const FULL = 'full';
public const OWNER = 'owner';
public const READ_ONLY = 'ro';
public const VIEW_REPORTS = 'view_reports';
protected $fillable = ['title'];
/**

View File

@ -80,17 +80,17 @@ class Webhook extends Model
// dont forget to update the config in firefly.php
// triggers
public const TRIGGER_STORE_TRANSACTION = 100;
public const TRIGGER_UPDATE_TRANSACTION = 110;
public const TRIGGER_DESTROY_TRANSACTION = 120;
// actions
public const RESPONSE_TRANSACTIONS = 200;
public const DELIVERY_JSON = 300;
public const RESPONSE_ACCOUNTS = 210;
public const RESPONSE_NONE = 220;
// actions
public const RESPONSE_TRANSACTIONS = 200;
public const TRIGGER_DESTROY_TRANSACTION = 120;
public const TRIGGER_STORE_TRANSACTION = 100;
// delivery
public const DELIVERY_JSON = 300;
public const TRIGGER_UPDATE_TRANSACTION = 110;
protected $casts
= [
'active' => 'boolean',
@ -111,7 +111,7 @@ class Webhook extends Model
public static function routeBinder(string $value): Webhook
{
if (auth()->check()) {
$webhookId = (int)$value;
$webhookId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var Webhook $webhook */

View File

@ -75,7 +75,7 @@ class WebhookAttempt extends Model
public static function routeBinder(string $value): WebhookAttempt
{
if (auth()->check()) {
$attemptId = (int)$value;
$attemptId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var WebhookAttempt $attempt */

View File

@ -89,7 +89,7 @@ class WebhookMessage extends Model
public static function routeBinder(string $value): WebhookMessage
{
if (auth()->check()) {
$messageId = (int)$value;
$messageId = (int) $value;
/** @var User $user */
$user = auth()->user();
/** @var WebhookMessage $message */

View File

@ -48,7 +48,6 @@ use Laravel\Passport\Client;
use Laravel\Passport\Events\AccessTokenCreated;
use Log;
use Mail;
use Request;
use Session;
/**
@ -76,7 +75,7 @@ class EventServiceProvider extends ServiceProvider
'FireflyIII\Handlers\Events\UserEventHandler@checkSingleUserIsAdmin',
'FireflyIII\Handlers\Events\UserEventHandler@demoUserBackToEnglish',
],
ActuallyLoggedIn::class => [
ActuallyLoggedIn::class => [
'FireflyIII\Handlers\Events\UserEventHandler@storeUserIPAddress',
],
DetectedNewIPAddress::class => [
@ -137,7 +136,7 @@ class EventServiceProvider extends ServiceProvider
],
// bill related events:
WarnUserAboutBill::class => [
WarnUserAboutBill::class => [
'FireflyIII\Handlers\Events\BillEventHandler@warnAboutBill',
],
];
@ -171,14 +170,14 @@ class EventServiceProvider extends ServiceProvider
static function (Client $oauthClient) {
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
$user = $repository->find((int)$oauthClient->user_id);
$user = $repository->find((int) $oauthClient->user_id);
if (null === $user) {
Log::info('OAuth client generated but no user associated.');
return;
}
$email = $user->email;
$email = $user->email;
// see if user has alternative email address:
$pref = app('preferences')->getForUser($user, 'remote_guard_alt_email');

View File

@ -198,21 +198,6 @@ class AccountRepository implements AccountRepositoryInterface
return $account;
}
/**
* @param Account $account
*
* @return TransactionCurrency|null
*/
public function getAccountCurrency(Account $account): ?TransactionCurrency
{
$currencyId = (int)$this->getMetaValue($account, 'currency_id');
if ($currencyId > 0) {
return TransactionCurrency::find($currencyId);
}
return null;
}
/**
* Return account type or null if not found.
*
@ -244,38 +229,6 @@ class AccountRepository implements AccountRepositoryInterface
return $query->get(['accounts.*']);
}
/**
* @param array $types
* @param array|null $sort
*
* @return Collection
*/
public function getAccountsByType(array $types, ?array $sort = []): Collection
{
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
$query = $this->user->accounts();
if (!empty($types)) {
$query->accountTypeIn($types);
}
// add sort parameters. At this point they're filtered to allowed fields to sort by:
if (!empty($sort)) {
foreach ($sort as $param) {
$query->orderBy($param[0], $param[1]);
}
}
if (empty($sort)) {
if (!empty($res)) {
$query->orderBy('accounts.order', 'ASC');
}
$query->orderBy('accounts.active', 'DESC');
$query->orderBy('accounts.name', 'ASC');
}
return $query->get(['accounts.*']);
}
/**
* @param array $types
*
@ -384,31 +337,6 @@ class AccountRepository implements AccountRepositoryInterface
return $account->locations()->first();
}
/**
* Return meta value for account. Null if not found.
*
* @param Account $account
* @param string $field
*
* @return null|string
*/
public function getMetaValue(Account $account, string $field): ?string
{
$result = $account->accountMeta->filter(
function (AccountMeta $meta) use ($field) {
return strtolower($meta->name) === strtolower($field);
}
);
if (0 === $result->count()) {
return null;
}
if (1 === $result->count()) {
return (string)$result->first()->data;
}
return null;
}
/**
* Get note text or null.
*
@ -427,20 +355,6 @@ class AccountRepository implements AccountRepositoryInterface
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.
*
@ -463,7 +377,7 @@ class AccountRepository implements AccountRepositoryInterface
return null;
}
return (string)$transaction->amount;
return (string) $transaction->amount;
}
/**
@ -498,6 +412,20 @@ class AccountRepository implements AccountRepositoryInterface
return $journal?->transactionGroup;
}
/**
* @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
*
@ -550,6 +478,46 @@ class AccountRepository implements AccountRepositoryInterface
return $factory->create($data);
}
/**
* @param Account $account
*
* @return TransactionCurrency|null
*/
public function getAccountCurrency(Account $account): ?TransactionCurrency
{
$currencyId = (int) $this->getMetaValue($account, 'currency_id');
if ($currencyId > 0) {
return TransactionCurrency::find($currencyId);
}
return null;
}
/**
* Return meta value for account. Null if not found.
*
* @param Account $account
* @param string $field
*
* @return null|string
*/
public function getMetaValue(Account $account, string $field): ?string
{
$result = $account->accountMeta->filter(
function (AccountMeta $meta) use ($field) {
return strtolower($meta->name) === strtolower($field);
}
);
if (0 === $result->count()) {
return null;
}
if (1 === $result->count()) {
return (string) $result->first()->data;
}
return null;
}
/**
* @inheritDoc
*/
@ -558,8 +526,8 @@ class AccountRepository implements AccountRepositoryInterface
$info = $account->transactions()->get(['transaction_currency_id', 'foreign_currency_id'])->toArray();
$currencyIds = [];
foreach ($info as $entry) {
$currencyIds[] = (int)$entry['transaction_currency_id'];
$currencyIds[] = (int)$entry['foreign_currency_id'];
$currencyIds[] = (int) $entry['transaction_currency_id'];
$currencyIds[] = (int) $entry['foreign_currency_id'];
}
$currencyIds = array_unique($currencyIds);
@ -590,19 +558,65 @@ class AccountRepository implements AccountRepositoryInterface
AccountType::MORTGAGE => [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE],
];
if (array_key_exists(ucfirst($type), $sets)) {
$order = (int)$this->getAccountsByType($sets[ucfirst($type)])->max('order');
$order = (int) $this->getAccountsByType($sets[ucfirst($type)])->max('order');
Log::debug(sprintf('Return max order of "%s" set: %d', $type, $order));
return $order;
}
$specials = [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION];
$order = (int)$this->getAccountsByType($specials)->max('order');
$order = (int) $this->getAccountsByType($specials)->max('order');
Log::debug(sprintf('Return max order of "%s" set (specials!): %d', $type, $order));
return $order;
}
/**
* @param array $types
* @param array|null $sort
*
* @return Collection
*/
public function getAccountsByType(array $types, ?array $sort = []): Collection
{
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
$query = $this->user->accounts();
if (!empty($types)) {
$query->accountTypeIn($types);
}
// add sort parameters. At this point they're filtered to allowed fields to sort by:
if (!empty($sort)) {
foreach ($sort as $param) {
$query->orderBy($param[0], $param[1]);
}
}
if (empty($sort)) {
if (!empty($res)) {
$query->orderBy('accounts.order', 'ASC');
}
$query->orderBy('accounts.active', 'DESC');
$query->orderBy('accounts.name', 'ASC');
}
return $query->get(['accounts.*']);
}
/**
* Returns the date of the very first transaction in this account.
*
* @param Account $account
*
* @return Carbon|null
*/
public function oldestJournalDate(Account $account): ?Carbon
{
$journal = $this->oldestJournal($account);
return $journal?->date;
}
/**
* Returns the date of the very first transaction in this account.
*
@ -620,26 +634,12 @@ class AccountRepository implements AccountRepositoryInterface
->orderBy('transaction_journals.id', 'ASC')
->first(['transaction_journals.id']);
if (null !== $first) {
return TransactionJournal::find((int)$first->id);
return TransactionJournal::find((int) $first->id);
}
return null;
}
/**
* Returns the date of the very first transaction in this account.
*
* @param Account $account
*
* @return Carbon|null
*/
public function oldestJournalDate(Account $account): ?Carbon
{
$journal = $this->oldestJournal($account);
return $journal?->date;
}
/**
* @inheritDoc
*/
@ -661,7 +661,7 @@ class AccountRepository implements AccountRepositoryInterface
$account->order = 0;
continue;
}
if ($index !== (int)$account->order) {
if ($index !== (int) $account->order) {
Log::debug(sprintf('Account #%d ("%s"): order should %d be but is %d.', $account->id, $account->name, $index, $account->order));
$account->order = $index;
$account->save();

View File

@ -138,7 +138,7 @@ class AccountTasker implements AccountTaskerInterface
// Obtain a list of columns
$sum = [];
foreach ($report['accounts'] as $accountId => $row) {
$sum[$accountId] = (float)$row['sum'];
$sum[$accountId] = (float) $row['sum'];
}
array_multisort($sum, SORT_ASC, $report['accounts']);
@ -146,6 +146,67 @@ class AccountTasker implements AccountTaskerInterface
return $report;
}
/**
* @param array $array
*
* @return array
*/
private function groupExpenseByDestination(array $array): array
{
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);
$currencies = [$defaultCurrency->id => $defaultCurrency,];
$report = [
'accounts' => [],
'sums' => [],
];
/** @var array $journal */
foreach ($array as $journal) {
$sourceId = (int) $journal['destination_account_id'];
$currencyId = (int) $journal['currency_id'];
$key = sprintf('%s-%s', $sourceId, $currencyId);
$currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepos->find($currencyId);
$report['accounts'][$key] = $report['accounts'][$key] ?? [
'id' => $sourceId,
'name' => $journal['destination_account_name'],
'sum' => '0',
'average' => '0',
'count' => 0,
'currency_id' => $currencies[$currencyId]->id,
'currency_name' => $currencies[$currencyId]->name,
'currency_symbol' => $currencies[$currencyId]->symbol,
'currency_code' => $currencies[$currencyId]->code,
'currency_decimal_places' => $currencies[$currencyId]->decimal_places,
];
$report['accounts'][$key]['sum'] = bcadd($report['accounts'][$key]['sum'], $journal['amount']);
Log::debug(sprintf('Sum for %s is now %s', $journal['destination_account_name'], $report['accounts'][$key]['sum']));
++$report['accounts'][$key]['count'];
}
// do averages and sums.
foreach (array_keys($report['accounts']) as $key) {
if ($report['accounts'][$key]['count'] > 1) {
$report['accounts'][$key]['average'] = bcdiv($report['accounts'][$key]['sum'], (string) $report['accounts'][$key]['count']);
}
$currencyId = $report['accounts'][$key]['currency_id'];
$report['sums'][$currencyId] = $report['sums'][$currencyId] ?? [
'sum' => '0',
'currency_id' => $report['accounts'][$key]['currency_id'],
'currency_name' => $report['accounts'][$key]['currency_name'],
'currency_symbol' => $report['accounts'][$key]['currency_symbol'],
'currency_code' => $report['accounts'][$key]['currency_code'],
'currency_decimal_places' => $report['accounts'][$key]['currency_decimal_places'],
];
$report['sums'][$currencyId]['sum'] = bcadd($report['sums'][$currencyId]['sum'], $report['accounts'][$key]['sum']);
}
return $report;
}
/**
* @param Carbon $start
* @param Carbon $end
@ -170,7 +231,7 @@ class AccountTasker implements AccountTaskerInterface
// Obtain a list of columns
$sum = [];
foreach ($report['accounts'] as $accountId => $row) {
$sum[$accountId] = (float)$row['sum'];
$sum[$accountId] = (float) $row['sum'];
}
array_multisort($sum, SORT_DESC, $report['accounts']);
@ -178,75 +239,6 @@ class AccountTasker implements AccountTaskerInterface
return $report;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
/**
* @param array $array
*
* @return array
*/
private function groupExpenseByDestination(array $array): array
{
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);
$currencies = [$defaultCurrency->id => $defaultCurrency,];
$report = [
'accounts' => [],
'sums' => [],
];
/** @var array $journal */
foreach ($array as $journal) {
$sourceId = (int)$journal['destination_account_id'];
$currencyId = (int)$journal['currency_id'];
$key = sprintf('%s-%s', $sourceId, $currencyId);
$currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepos->find($currencyId);
$report['accounts'][$key] = $report['accounts'][$key] ?? [
'id' => $sourceId,
'name' => $journal['destination_account_name'],
'sum' => '0',
'average' => '0',
'count' => 0,
'currency_id' => $currencies[$currencyId]->id,
'currency_name' => $currencies[$currencyId]->name,
'currency_symbol' => $currencies[$currencyId]->symbol,
'currency_code' => $currencies[$currencyId]->code,
'currency_decimal_places' => $currencies[$currencyId]->decimal_places,
];
$report['accounts'][$key]['sum'] = bcadd($report['accounts'][$key]['sum'], $journal['amount']);
Log::debug(sprintf('Sum for %s is now %s', $journal['destination_account_name'], $report['accounts'][$key]['sum']));
++$report['accounts'][$key]['count'];
}
// do averages and sums.
foreach (array_keys($report['accounts']) as $key) {
if ($report['accounts'][$key]['count'] > 1) {
$report['accounts'][$key]['average'] = bcdiv($report['accounts'][$key]['sum'], (string)$report['accounts'][$key]['count']);
}
$currencyId = $report['accounts'][$key]['currency_id'];
$report['sums'][$currencyId] = $report['sums'][$currencyId] ?? [
'sum' => '0',
'currency_id' => $report['accounts'][$key]['currency_id'],
'currency_name' => $report['accounts'][$key]['currency_name'],
'currency_symbol' => $report['accounts'][$key]['currency_symbol'],
'currency_code' => $report['accounts'][$key]['currency_code'],
'currency_decimal_places' => $report['accounts'][$key]['currency_decimal_places'],
];
$report['sums'][$currencyId]['sum'] = bcadd($report['sums'][$currencyId]['sum'], $report['accounts'][$key]['sum']);
}
return $report;
}
/**
* @param array $array
*
@ -265,8 +257,8 @@ class AccountTasker implements AccountTaskerInterface
/** @var array $journal */
foreach ($array as $journal) {
$sourceId = (int)$journal['source_account_id'];
$currencyId = (int)$journal['currency_id'];
$sourceId = (int) $journal['source_account_id'];
$currencyId = (int) $journal['currency_id'];
$key = sprintf('%s-%s', $sourceId, $currencyId);
if (!array_key_exists($key, $report['accounts'])) {
$currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepos->find($currencyId);
@ -290,7 +282,7 @@ class AccountTasker implements AccountTaskerInterface
// do averages and sums.
foreach (array_keys($report['accounts']) as $key) {
if ($report['accounts'][$key]['count'] > 1) {
$report['accounts'][$key]['average'] = bcdiv($report['accounts'][$key]['sum'], (string)$report['accounts'][$key]['count']);
$report['accounts'][$key]['average'] = bcdiv($report['accounts'][$key]['sum'], (string) $report['accounts'][$key]['count']);
}
$currencyId = $report['accounts'][$key]['currency_id'];
$report['sums'][$currencyId] = $report['sums'][$currencyId] ?? [
@ -306,4 +298,12 @@ class AccountTasker implements AccountTaskerInterface
return $report;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
}

View File

@ -56,109 +56,6 @@ class OperationsRepository implements OperationsRepositoryInterface
return $this->sortByCurrency($journals, 'negative');
}
/**
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified accounts. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
*
* @param Carbon $start
* @param Carbon $end
* @param Collection|null $accounts
*
* @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array
{
$journals = $this->getTransactions($start, $end, $accounts, TransactionType::DEPOSIT);
return $this->sortByCurrency($journals, 'positive');
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
/**
* @inheritDoc
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null
): array {
$journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency);
return $this->groupByCurrency($journals, 'negative');
}
/**
* @inheritDoc
*/
public function sumExpensesByDestination(
Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null
): array {
$journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency);
return $this->groupByDirection($journals, 'destination', 'negative');
}
/**
* @inheritDoc
*/
public function sumExpensesBySource(
Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null
): array {
$journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency);
return $this->groupByDirection($journals, 'source', 'negative');
}
/**
* @inheritDoc
*/
public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null
): array {
$journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency);
return $this->groupByCurrency($journals, 'positive');
}
/**
* @inheritDoc
*/
public function sumIncomeByDestination(
Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null
): array {
$journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency);
return $this->groupByDirection($journals, 'destination', 'positive');
}
/**
* @inheritDoc
*/
public function sumIncomeBySource(
Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null
): array {
$journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency);
return $this->groupByDirection($journals, 'source', 'positive');
}
/**
* @inheritDoc
*/
public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array
{
$journals = $this->getTransactionsForSum(TransactionType::TRANSFER, $start, $end, $accounts, null, $currency);
return $this->groupByEither($journals);
}
/**
* Collect transactions with some parameters
*
@ -190,8 +87,8 @@ class OperationsRepository implements OperationsRepositoryInterface
{
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$journalId = (int)$journal['transaction_journal_id'];
$currencyId = (int) $journal['currency_id'];
$journalId = (int) $journal['transaction_journal_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'currency_id' => $journal['currency_id'],
@ -203,7 +100,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
$array[$currencyId]['transaction_journals'][$journalId] = [
'amount' => app('steam')->$direction((string)$journal['amount']),
'amount' => app('steam')->$direction((string) $journal['amount']),
'date' => $journal['date'],
'transaction_journal_id' => $journalId,
'budget_name' => $journal['budget_name'],
@ -223,6 +120,45 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
/**
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified accounts. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
*
* @param Carbon $start
* @param Carbon $end
* @param Collection|null $accounts
*
* @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array
{
$journals = $this->getTransactions($start, $end, $accounts, TransactionType::DEPOSIT);
return $this->sortByCurrency($journals, 'positive');
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
/**
* @inheritDoc
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null
): array
{
$journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency);
return $this->groupByCurrency($journals, 'negative');
}
/**
* @param Carbon $start
* @param Carbon $end
@ -236,7 +172,8 @@ class OperationsRepository implements OperationsRepositoryInterface
private function getTransactionsForSum(
string $type, Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $opposing = null, ?TransactionCurrency $currency = null
): array {
): array
{
$start->startOfDay();
$end->endOfDay();
@ -314,7 +251,7 @@ class OperationsRepository implements OperationsRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'sum' => '0',
'currency_id' => $currencyId,
@ -326,7 +263,7 @@ class OperationsRepository implements OperationsRepositoryInterface
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->$direction($journal['amount']));
// also do foreign amount:
$foreignId = (int)$journal['foreign_currency_id'];
$foreignId = (int) $journal['foreign_currency_id'];
if (0 !== $foreignId) {
$array[$foreignId] = $array[$foreignId] ?? [
'sum' => '0',
@ -343,6 +280,18 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
/**
* @inheritDoc
*/
public function sumExpensesByDestination(
Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null
): array
{
$journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency);
return $this->groupByDirection($journals, 'destination', 'negative');
}
/**
* @param array $journals
* @param string $direction
@ -368,10 +317,10 @@ class OperationsRepository implements OperationsRepositoryInterface
'currency_code' => $journal['currency_code'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
$array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->$method((string)$journal['amount']));
$array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->$method((string) $journal['amount']));
// also do foreign amount:
if (0 !== (int)$journal['foreign_currency_id']) {
if (0 !== (int) $journal['foreign_currency_id']) {
$key = sprintf('%s-%s', $journal[$idKey], $journal['foreign_currency_id']);
$array[$key] = $array[$key] ?? [
'id' => $journal[$idKey],
@ -383,13 +332,70 @@ class OperationsRepository implements OperationsRepositoryInterface
'currency_code' => $journal['foreign_currency_code'],
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
];
$array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->$method((string)$journal['foreign_amount']));
$array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->$method((string) $journal['foreign_amount']));
}
}
return $array;
}
/**
* @inheritDoc
*/
public function sumExpensesBySource(
Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $expense = null, ?TransactionCurrency $currency = null
): array
{
$journals = $this->getTransactionsForSum(TransactionType::WITHDRAWAL, $start, $end, $accounts, $expense, $currency);
return $this->groupByDirection($journals, 'source', 'negative');
}
/**
* @inheritDoc
*/
public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null
): array
{
$journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency);
return $this->groupByCurrency($journals, 'positive');
}
/**
* @inheritDoc
*/
public function sumIncomeByDestination(
Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null
): array
{
$journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency);
return $this->groupByDirection($journals, 'destination', 'positive');
}
/**
* @inheritDoc
*/
public function sumIncomeBySource(
Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $revenue = null, ?TransactionCurrency $currency = null
): array
{
$journals = $this->getTransactionsForSum(TransactionType::DEPOSIT, $start, $end, $accounts, $revenue, $currency);
return $this->groupByDirection($journals, 'source', 'positive');
}
/**
* @inheritDoc
*/
public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array
{
$journals = $this->getTransactionsForSum(TransactionType::TRANSFER, $start, $end, $accounts, null, $currency);
return $this->groupByEither($journals);
}
/**
* @param array $journals
*
@ -404,9 +410,9 @@ class OperationsRepository implements OperationsRepositoryInterface
}
$final = [];
foreach ($return as $array) {
$array['difference_float'] = (float)$array['difference'];
$array['in_float'] = (float)$array['in'];
$array['out_float'] = (float)$array['out'];
$array['difference_float'] = (float) $array['difference'];
$array['in_float'] = (float) $array['in'];
$array['out_float'] = (float) $array['out'];
$final[] = $array;
}
@ -430,7 +436,7 @@ class OperationsRepository implements OperationsRepositoryInterface
// source first
$return[$sourceKey] = $return[$sourceKey] ?? [
'id' => (string)$sourceId,
'id' => (string) $sourceId,
'name' => $journal['source_account_name'],
'difference' => '0',
'difference_float' => 0,
@ -438,13 +444,13 @@ class OperationsRepository implements OperationsRepositoryInterface
'in_float' => 0,
'out' => '0',
'out_float' => 0,
'currency_id' => (string)$currencyId,
'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'],
];
// dest next:
$return[$destKey] = $return[$destKey] ?? [
'id' => (string)$destinationId,
'id' => (string) $destinationId,
'name' => $journal['destination_account_name'],
'difference' => '0',
'difference_float' => 0,
@ -452,7 +458,7 @@ class OperationsRepository implements OperationsRepositoryInterface
'in_float' => 0,
'out' => '0',
'out_float' => 0,
'currency_id' => (string)$currencyId,
'currency_id' => (string) $currencyId,
'currency_code' => $journal['currency_code'],
];
@ -474,7 +480,7 @@ class OperationsRepository implements OperationsRepositoryInterface
// same as above:
// source first
$return[$sourceKey] = $return[$sourceKey] ?? [
'id' => (string)$sourceId,
'id' => (string) $sourceId,
'name' => $journal['source_account_name'],
'difference' => '0',
'difference_float' => 0,
@ -482,13 +488,13 @@ class OperationsRepository implements OperationsRepositoryInterface
'in_float' => 0,
'out' => '0',
'out_float' => 0,
'currency_id' => (string)$currencyId,
'currency_id' => (string) $currencyId,
'currency_code' => $journal['foreign_currency_code'],
];
// dest next:
$return[$destKey] = $return[$destKey] ?? [
'id' => (string)$destinationId,
'id' => (string) $destinationId,
'name' => $journal['destination_account_name'],
'difference' => '0',
'difference_float' => 0,
@ -496,7 +502,7 @@ class OperationsRepository implements OperationsRepositoryInterface
'in_float' => 0,
'out' => '0',
'out_float' => 0,
'currency_id' => (string)$currencyId,
'currency_id' => (string) $currencyId,
'currency_code' => $journal['foreign_currency_code'],
];
// source account? money goes out! (same as above)

View File

@ -33,7 +33,6 @@ use FireflyIII\User;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Log;
/**
* Class AttachmentRepository.

View File

@ -55,6 +55,36 @@ class BillRepository implements BillRepositoryInterface
private User $user;
/**
* @inheritDoc
*/
public function billEndsWith(string $query, int $limit): Collection
{
$search = $this->user->bills();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%%%s', $query));
}
$search->orderBy('name', 'ASC')
->where('active', true);
return $search->take($limit)->get();
}
/**
* @inheritDoc
*/
public function billStartsWith(string $query, int $limit): Collection
{
$search = $this->user->bills();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%s%%', $query));
}
$search->orderBy('name', 'ASC')
->where('active', true);
return $search->take($limit)->get();
}
/**
* Correct order of piggies in case of issues.
*/
@ -63,7 +93,7 @@ class BillRepository implements BillRepositoryInterface
$set = $this->user->bills()->orderBy('order', 'ASC')->get();
$current = 1;
foreach ($set as $bill) {
if ((int)$bill->order !== $current) {
if ((int) $bill->order !== $current) {
$bill->order = $current;
$bill->save();
}
@ -95,18 +125,6 @@ class BillRepository implements BillRepositoryInterface
$this->user->bills()->delete();
}
/**
* Find a bill by ID.
*
* @param int $billId
*
* @return Bill|null
*/
public function find(int $billId): ?Bill
{
return $this->user->bills()->find($billId);
}
/**
* Find bill by parameters.
*
@ -118,7 +136,7 @@ class BillRepository implements BillRepositoryInterface
public function findBill(?int $billId, ?string $billName): ?Bill
{
if (null !== $billId) {
$searchResult = $this->find((int)$billId);
$searchResult = $this->find((int) $billId);
if (null !== $searchResult) {
Log::debug(sprintf('Found bill based on #%d, will return it.', $billId));
@ -126,7 +144,7 @@ class BillRepository implements BillRepositoryInterface
}
}
if (null !== $billName) {
$searchResult = $this->findByName((string)$billName);
$searchResult = $this->findByName((string) $billName);
if (null !== $searchResult) {
Log::debug(sprintf('Found bill based on "%s", will return it.', $billName));
@ -138,6 +156,18 @@ class BillRepository implements BillRepositoryInterface
return null;
}
/**
* Find a bill by ID.
*
* @param int $billId
*
* @return Bill|null
*/
public function find(int $billId): ?Bill
{
return $this->user->bills()->find($billId);
}
/**
* Find a bill by name.
*
@ -150,17 +180,6 @@ class BillRepository implements BillRepositoryInterface
return $this->user->bills()->where('name', $name)->first(['bills.*']);
}
/**
* @return Collection
*/
public function getActiveBills(): Collection
{
return $this->user->bills()
->where('active', true)
->orderBy('bills.name', 'ASC')
->get(['bills.*', DB::raw('((bills.amount_min + bills.amount_max) / 2) AS expectedAmount'),]);
}
/**
* Get all attachments.
*
@ -249,7 +268,7 @@ class BillRepository implements BillRepositoryInterface
$set = $bill->transactionJournals()->after($start)->before($end)->get(['transaction_journals.*']);
if ($set->count() > 0) {
$journalIds = $set->pluck('id')->toArray();
$amount = (string)Transaction::whereIn('transaction_journal_id', $journalIds)->where('amount', '<', 0)->sum('amount');
$amount = (string) Transaction::whereIn('transaction_journal_id', $journalIds)->where('amount', '<', 0)->sum('amount');
$sum = bcadd($sum, $amount);
//Log::debug(sprintf('Total > 0, so add to sum %f, which becomes %f', $amount, $sum));
}
@ -258,6 +277,17 @@ class BillRepository implements BillRepositoryInterface
return $sum;
}
/**
* @return Collection
*/
public function getActiveBills(): Collection
{
return $this->user->bills()
->where('active', true)
->orderBy('bills.name', 'ASC')
->get(['bills.*', DB::raw('((bills.amount_min + bills.amount_max) / 2) AS expectedAmount'),]);
}
/**
* Get the total amount of money paid for the users active bills in the date range given,
* grouped per currency.
@ -275,10 +305,10 @@ class BillRepository implements BillRepositoryInterface
foreach ($bills as $bill) {
/** @var Collection $set */
$set = $bill->transactionJournals()->after($start)->before($end)->get(['transaction_journals.*']);
$currencyId = (int)$bill->transaction_currency_id;
$currencyId = (int) $bill->transaction_currency_id;
if ($set->count() > 0) {
$journalIds = $set->pluck('id')->toArray();
$amount = (string)Transaction::whereIn('transaction_journal_id', $journalIds)->where('amount', '<', 0)->sum('amount');
$amount = (string) Transaction::whereIn('transaction_journal_id', $journalIds)->where('amount', '<', 0)->sum('amount');
$return[$currencyId] = $return[$currencyId] ?? '0';
$return[$currencyId] = bcadd($amount, $return[$currencyId]);
//Log::debug(sprintf('Total > 0, so add to sum %f, which becomes %f (currency %d)', $amount, $return[$currencyId], $currencyId));
@ -311,7 +341,7 @@ class BillRepository implements BillRepositoryInterface
if ($total > 0) {
$average = bcdiv(bcadd($bill->amount_max, $bill->amount_min), '2');
$multi = bcmul($average, (string)$total);
$multi = bcmul($average, (string) $total);
$sum = bcadd($sum, $multi);
//Log::debug(sprintf('Total > 0, so add to sum %f, which becomes %f', $multi, $sum));
}
@ -320,6 +350,71 @@ class BillRepository implements BillRepositoryInterface
return $sum;
}
/**
* Between start and end, tells you on which date(s) the bill is expected to hit.
*
* @param Bill $bill
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getPayDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection
{
$set = new Collection;
$currentStart = clone $start;
//Log::debug(sprintf('Now at bill "%s" (%s)', $bill->name, $bill->repeat_freq));
//Log::debug(sprintf('First currentstart is %s', $currentStart->format('Y-m-d')));
while ($currentStart <= $end) {
//Log::debug(sprintf('Currentstart is now %s.', $currentStart->format('Y-m-d')));
$nextExpectedMatch = $this->nextDateMatch($bill, $currentStart);
//Log::debug(sprintf('Next Date match after %s is %s', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
if ($nextExpectedMatch > $end) {// If nextExpectedMatch is after end, we continue
break;
}
$set->push(clone $nextExpectedMatch);
//Log::debug(sprintf('Now %d dates in set.', $set->count()));
$nextExpectedMatch->addDay();
//Log::debug(sprintf('Currentstart (%s) has become %s.', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
$currentStart = clone $nextExpectedMatch;
}
return $set;
}
/**
* Given a bill and a date, this method will tell you at which moment this bill expects its next
* transaction. Whether or not it is there already, is not relevant.
*
* @param Bill $bill
* @param Carbon $date
*
* @return Carbon
* @throws JsonException
*/
public function nextDateMatch(Bill $bill, Carbon $date): Carbon
{
$cache = new CacheProperties;
$cache->addProperty($bill->id);
$cache->addProperty('nextDateMatch');
$cache->addProperty($date);
if ($cache->has()) {
return $cache->get();
}
// find the most recent date for this bill NOT in the future. Cache this date:
$start = clone $bill->date;
while ($start < $date) {
$start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
}
$cache->store($start);
return $start;
}
/**
* Get the total amount of money due for the users active bills in the date range given.
*
@ -338,13 +433,13 @@ class BillRepository implements BillRepositoryInterface
$dates = $this->getPayDatesInRange($bill, $start, $end);
$count = $bill->transactionJournals()->after($start)->before($end)->count();
$total = $dates->count() - $count;
$currencyId = (int)$bill->transaction_currency_id;
$currencyId = (int) $bill->transaction_currency_id;
//Log::debug(sprintf('Dates = %d, journalCount = %d, total = %d', $dates->count(), $count, $total));
if ($total > 0) {
$average = bcdiv(bcadd($bill->amount_max, $bill->amount_min), '2');
$multi = bcmul($average, (string)$total);
$multi = bcmul($average, (string) $total);
$return[$currencyId] = $return[$currencyId] ?? '0';
$return[$currencyId] = bcadd($return[$currencyId], $multi);
//Log::debug(sprintf('Total > 0, so add to sum %f, which becomes %f (for currency %d)', $multi, $return[$currencyId], $currencyId));
@ -378,7 +473,7 @@ class BillRepository implements BillRepositoryInterface
/** @var Note $note */
$note = $bill->notes()->first();
if (null !== $note) {
return (string)$note->text;
return (string) $note->text;
}
return '';
@ -403,7 +498,7 @@ class BillRepository implements BillRepositoryInterface
foreach ($journals as $journal) {
/** @var Transaction $transaction */
$transaction = $journal->transactions()->where('amount', '<', 0)->first();
$currencyId = (int)$journal->transaction_currency_id;
$currencyId = (int) $journal->transaction_currency_id;
$currency = $journal->transactionCurrency;
$result[$currencyId] = $result[$currencyId] ?? [
'sum' => '0',
@ -424,7 +519,7 @@ class BillRepository implements BillRepositoryInterface
* @var array $arr
*/
foreach ($result as $currencyId => $arr) {
$result[$currencyId]['avg'] = bcdiv($arr['sum'], (string)$arr['count']);
$result[$currencyId]['avg'] = bcdiv($arr['sum'], (string) $arr['count']);
}
return $result;
@ -464,41 +559,6 @@ class BillRepository implements BillRepositoryInterface
);
}
/**
* Between start and end, tells you on which date(s) the bill is expected to hit.
*
* @param Bill $bill
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getPayDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection
{
$set = new Collection;
$currentStart = clone $start;
//Log::debug(sprintf('Now at bill "%s" (%s)', $bill->name, $bill->repeat_freq));
//Log::debug(sprintf('First currentstart is %s', $currentStart->format('Y-m-d')));
while ($currentStart <= $end) {
//Log::debug(sprintf('Currentstart is now %s.', $currentStart->format('Y-m-d')));
$nextExpectedMatch = $this->nextDateMatch($bill, $currentStart);
//Log::debug(sprintf('Next Date match after %s is %s', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
if ($nextExpectedMatch > $end) {// If nextExpectedMatch is after end, we continue
break;
}
$set->push(clone $nextExpectedMatch);
//Log::debug(sprintf('Now %d dates in set.', $set->count()));
$nextExpectedMatch->addDay();
//Log::debug(sprintf('Currentstart (%s) has become %s.', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
$currentStart = clone $nextExpectedMatch;
}
return $set;
}
/**
* Return all rules for one bill
*
@ -572,7 +632,7 @@ class BillRepository implements BillRepositoryInterface
if (null === $transaction) {
continue;
}
$currencyId = (int)$journal->transaction_currency_id;
$currencyId = (int) $journal->transaction_currency_id;
$currency = $journal->transactionCurrency;
$result[$currencyId] = $result[$currencyId] ?? [
'sum' => '0',
@ -593,7 +653,7 @@ class BillRepository implements BillRepositoryInterface
* @var array $arr
*/
foreach ($result as $currencyId => $arr) {
$result[$currencyId]['avg'] = bcdiv($arr['sum'], (string)$arr['count']);
$result[$currencyId]['avg'] = bcdiv($arr['sum'], (string) $arr['count']);
}
return $result;
@ -609,43 +669,13 @@ class BillRepository implements BillRepositoryInterface
{
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$journal = $bill->user->transactionJournals()->find((int)$transaction['transaction_journal_id']);
$journal = $bill->user->transactionJournals()->find((int) $transaction['transaction_journal_id']);
$journal->bill_id = $bill->id;
$journal->save();
Log::debug(sprintf('Linked journal #%d to bill #%d', $journal->id, $bill->id));
}
}
/**
* Given a bill and a date, this method will tell you at which moment this bill expects its next
* transaction. Whether or not it is there already, is not relevant.
*
* @param Bill $bill
* @param Carbon $date
*
* @return Carbon
* @throws JsonException
*/
public function nextDateMatch(Bill $bill, Carbon $date): Carbon
{
$cache = new CacheProperties;
$cache->addProperty($bill->id);
$cache->addProperty('nextDateMatch');
$cache->addProperty($date);
if ($cache->has()) {
return $cache->get();
}
// find the most recent date for this bill NOT in the future. Cache this date:
$start = clone $bill->date;
while ($start < $date) {
$start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
}
$cache->store($start);
return $start;
}
/**
* Given the date in $date, this method will return a moment in the future where the bill is expected to be paid.
*
@ -782,35 +812,4 @@ class BillRepository implements BillRepositoryInterface
return $service->update($bill, $data);
}
/**
* @inheritDoc
*/
public function billEndsWith(string $query, int $limit): Collection
{
$search = $this->user->bills();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%%%s', $query));
}
$search->orderBy('name', 'ASC')
->where('active', true);
return $search->take($limit)->get();
}
/**
* @inheritDoc
*/
public function billStartsWith(string $query, int $limit): Collection
{
$search = $this->user->bills();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%s%%', $query));
}
$search->orderBy('name', 'ASC')
->where('active', true);
return $search->take($limit)->get();
}
}

View File

@ -35,11 +35,6 @@ use Illuminate\Support\Collection;
interface BillRepositoryInterface
{
/**
* Add correct order to bills.
*/
public function correctOrder(): void;
/**
* @param string $query
* @param int $limit
@ -56,6 +51,11 @@ interface BillRepositoryInterface
*/
public function billStartsWith(string $query, int $limit): Collection;
/**
* Add correct order to bills.
*/
public function correctOrder(): void;
/**
* @param Bill $bill
*

View File

@ -124,7 +124,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
->where('start_date', $start->format('Y-m-d'))
->where('end_date', $end->format('Y-m-d'))->first();
if (null !== $availableBudget) {
$amount = (string)$availableBudget->amount;
$amount = (string) $availableBudget->amount;
}
return $amount;

View File

@ -147,6 +147,22 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
->where('end_date', $end->format('Y-m-d'))->first();
}
/**
* @param TransactionCurrency $currency
* @param Carbon|null $start
* @param Carbon|null $end
*
* @return Collection
*/
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection
{
return $this->getAllBudgetLimits($start, $end)->filter(
static function (BudgetLimit $budgetLimit) use ($currency) {
return $budgetLimit->transaction_currency_id === $currency->id;
}
);
}
/**
* @param Carbon|null $start
* @param Carbon|null $end
@ -215,22 +231,6 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
)->get(['budget_limits.*']);
}
/**
* @param TransactionCurrency $currency
* @param Carbon|null $start
* @param Carbon|null $end
*
* @return Collection
*/
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection
{
return $this->getAllBudgetLimits($start, $end)->filter(
static function (BudgetLimit $budgetLimit) use ($currency) {
return $budgetLimit->transaction_currency_id === $currency->id;
}
);
}
/**
* @param Budget $budget
* @param Carbon|null $start
@ -318,7 +318,7 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
$currency->save();
// find the budget:
$budget = $this->user->budgets()->find((int)$data['budget_id']);
$budget = $this->user->budgets()->find((int) $data['budget_id']);
if (null === $budget) {
throw new FireflyException('200004: Budget does not exist.');
}

View File

@ -50,6 +50,36 @@ class BudgetRepository implements BudgetRepositoryInterface
{
private User $user;
/**
* @inheritDoc
*/
public function budgetEndsWith(string $query, int $limit): Collection
{
$search = $this->user->budgets();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%%%s', $query));
}
$search->orderBy('order', 'ASC')
->orderBy('name', 'ASC')->where('active', true);
return $search->take($limit)->get();
}
/**
* @inheritDoc
*/
public function budgetStartsWith(string $query, int $limit): Collection
{
$search = $this->user->budgets();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%s%%', $query));
}
$search->orderBy('order', 'ASC')
->orderBy('name', 'ASC')->where('active', true);
return $search->take($limit)->get();
}
/**
* @return bool
*/
@ -76,6 +106,17 @@ class BudgetRepository implements BudgetRepositoryInterface
return true;
}
/**
* @return Collection
*/
public function getActiveBudgets(): Collection
{
return $this->user->budgets()->where('active', true)
->orderBy('order', 'ASC')
->orderBy('name', 'ASC')
->get();
}
/**
* @param Budget $budget
*
@ -98,14 +139,23 @@ class BudgetRepository implements BudgetRepositoryInterface
$budgets = $this->getBudgets();
/** @var Budget $budget */
foreach ($budgets as $budget) {
DB::table('budget_transaction')->where('budget_id', (int)$budget->id)->delete();
DB::table('budget_transaction_journal')->where('budget_id', (int)$budget->id)->delete();
RecurrenceTransactionMeta::where('name', 'budget_id')->where('value', (string)$budget->id)->delete();
RuleAction::where('action_type', 'set_budget')->where('action_value', (string)$budget->id)->delete();
DB::table('budget_transaction')->where('budget_id', (int) $budget->id)->delete();
DB::table('budget_transaction_journal')->where('budget_id', (int) $budget->id)->delete();
RecurrenceTransactionMeta::where('name', 'budget_id')->where('value', (string) $budget->id)->delete();
RuleAction::where('action_type', 'set_budget')->where('action_value', (string) $budget->id)->delete();
$budget->delete();
}
}
/**
* @return Collection
*/
public function getBudgets(): Collection
{
return $this->user->budgets()->orderBy('order', 'ASC')
->orderBy('name', 'ASC')->get();
}
/**
* @inheritDoc
*/
@ -117,18 +167,6 @@ class BudgetRepository implements BudgetRepositoryInterface
}
}
/**
* Find a budget or return NULL
*
* @param int|null $budgetId |null
*
* @return Budget|null
*/
public function find(int $budgetId = null): ?Budget
{
return $this->user->budgets()->find($budgetId);
}
/**
* @param int|null $budgetId
* @param string|null $budgetName
@ -139,10 +177,10 @@ class BudgetRepository implements BudgetRepositoryInterface
{
Log::debug('Now in findBudget()');
Log::debug(sprintf('Searching for budget with ID #%d...', $budgetId));
$result = $this->find((int)$budgetId);
$result = $this->find((int) $budgetId);
if (null === $result && null !== $budgetName && '' !== $budgetName) {
Log::debug(sprintf('Searching for budget with name %s...', $budgetName));
$result = $this->findByName((string)$budgetName);
$result = $this->findByName((string) $budgetName);
}
if (null !== $result) {
Log::debug(sprintf('Found budget #%d: %s', $result->id, $result->name));
@ -152,6 +190,18 @@ class BudgetRepository implements BudgetRepositoryInterface
return $result;
}
/**
* Find a budget or return NULL
*
* @param int|null $budgetId |null
*
* @return Budget|null
*/
public function find(int $budgetId = null): ?Budget
{
return $this->user->budgets()->find($budgetId);
}
/**
* Find budget by name.
*
@ -187,17 +237,6 @@ class BudgetRepository implements BudgetRepositoryInterface
return null;
}
/**
* @return Collection
*/
public function getActiveBudgets(): Collection
{
return $this->user->budgets()->where('active', true)
->orderBy('order', 'ASC')
->orderBy('name', 'ASC')
->get();
}
/**
* @inheritDoc
*/
@ -219,23 +258,6 @@ class BudgetRepository implements BudgetRepositoryInterface
);
}
/**
* @inheritDoc
*/
public function getAutoBudget(Budget $budget): ?AutoBudget
{
return $budget->autoBudgets()->first();
}
/**
* @return Collection
*/
public function getBudgets(): Collection
{
return $this->user->budgets()->orderBy('order', 'ASC')
->orderBy('name', 'ASC')->get();
}
/**
* Get all budgets with these ID's.
*
@ -258,9 +280,17 @@ class BudgetRepository implements BudgetRepositoryInterface
->orderBy('name', 'ASC')->where('active', 0)->get();
}
public function getMaxOrder(): int
/**
* @inheritDoc
*/
public function getNoteText(Budget $budget): ?string
{
return (int)$this->user->budgets()->max('order');
$note = $budget->notes()->first();
if (null === $note) {
return null;
}
return $note->text;
}
/**
@ -325,8 +355,8 @@ class BudgetRepository implements BudgetRepositoryInterface
}
// set notes
if(array_key_exists('notes', $data)) {
$this->setNoteText($newBudget, (string)$data['notes']);
if (array_key_exists('notes', $data)) {
$this->setNoteText($newBudget, (string) $data['notes']);
}
if (!array_key_exists('auto_budget_type', $data) || !array_key_exists('auto_budget_amount', $data) || !array_key_exists('auto_budget_period', $data)) {
@ -350,10 +380,10 @@ class BudgetRepository implements BudgetRepositoryInterface
$repos = app(CurrencyRepositoryInterface::class);
$currency = null;
if (array_key_exists('currency_id', $data)) {
$currency = $repos->find((int)$data['currency_id']);
$currency = $repos->find((int) $data['currency_id']);
}
if (array_key_exists('currency_code', $data)) {
$currency = $repos->findByCode((string)$data['currency_code']);
$currency = $repos->findByCode((string) $data['currency_code']);
}
if (null === $currency) {
$currency = app('amount')->getDefaultCurrencyByUser($this->user);
@ -387,6 +417,38 @@ class BudgetRepository implements BudgetRepositoryInterface
return $newBudget;
}
public function getMaxOrder(): int
{
return (int) $this->user->budgets()->max('order');
}
/**
* @param Budget $budget
* @param string $text
* @return void
*/
private function setNoteText(Budget $budget, string $text): void
{
$dbNote = $budget->notes()->first();
if ('' !== $text) {
if (null === $dbNote) {
$dbNote = new Note;
$dbNote->noteable()->associate($budget);
}
$dbNote->text = trim($text);
$dbNote->save();
return;
}
if (null !== $dbNote) {
try {
$dbNote->delete();
} catch (Exception $e) { // @phpstan-ignore-line
// @ignoreException
}
}
}
/**
* @param Budget $budget
* @param array $data
@ -406,8 +468,8 @@ class BudgetRepository implements BudgetRepositoryInterface
if (array_key_exists('active', $data)) {
$budget->active = $data['active'];
}
if(array_key_exists('notes', $data)) {
$this->setNoteText($budget, (string)$data['notes']);
if (array_key_exists('notes', $data)) {
$this->setNoteText($budget, (string) $data['notes']);
}
$budget->save();
@ -476,6 +538,14 @@ class BudgetRepository implements BudgetRepositoryInterface
}
}
/**
* @inheritDoc
*/
public function getAutoBudget(Budget $budget): ?AutoBudget
{
return $budget->autoBudgets()->first();
}
/**
* @param Budget $budget
* @param array $data
@ -499,8 +569,8 @@ class BudgetRepository implements BudgetRepositoryInterface
// set or update the currency.
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
$repos = app(CurrencyRepositoryInterface::class);
$currencyId = (int)($data['currency_id'] ?? 0);
$currencyCode = (string)($data['currency_code'] ?? '');
$currencyId = (int) ($data['currency_id'] ?? 0);
$currencyCode = (string) ($data['currency_code'] ?? '');
$currency = $repos->find($currencyId);
if (null === $currency) {
$currency = $repos->findByCodeNull($currencyCode);
@ -524,74 +594,4 @@ class BudgetRepository implements BudgetRepositoryInterface
$autoBudget->save();
}
/**
* @inheritDoc
*/
public function getNoteText(Budget $budget): ?string
{
$note = $budget->notes()->first();
if (null === $note) {
return null;
}
return $note->text;
}
/**
* @param Budget $budget
* @param string $text
* @return void
*/
private function setNoteText(Budget $budget, string $text): void
{
$dbNote = $budget->notes()->first();
if ('' !== $text) {
if (null === $dbNote) {
$dbNote = new Note;
$dbNote->noteable()->associate($budget);
}
$dbNote->text = trim($text);
$dbNote->save();
return;
}
if (null !== $dbNote) {
try {
$dbNote->delete();
} catch (Exception $e) { // @phpstan-ignore-line
// @ignoreException
}
}
}
/**
* @inheritDoc
*/
public function budgetEndsWith(string $query, int $limit): Collection
{
$search = $this->user->budgets();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%%%s', $query));
}
$search->orderBy('order', 'ASC')
->orderBy('name', 'ASC')->where('active', true);
return $search->take($limit)->get();
}
/**
* @inheritDoc
*/
public function budgetStartsWith(string $query, int $limit): Collection
{
$search = $this->user->budgets();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%s%%', $query));
}
$search->orderBy('order', 'ASC')
->orderBy('name', 'ASC')->where('active', true);
return $search->take($limit)->get();
}
}

View File

@ -34,17 +34,27 @@ use Illuminate\Support\Collection;
*/
interface BudgetRepositoryInterface
{
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function budgetEndsWith(string $query, int $limit): Collection;
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function budgetStartsWith(string $query, int $limit): Collection;
/**
* @return bool
*/
public function cleanupBudgets(): bool;
/**
* @param Budget $budget
* @return string|null
*/
public function getNoteText(Budget $budget): ?string;
/**
* @param Budget $budget
*
@ -140,6 +150,12 @@ interface BudgetRepositoryInterface
*/
public function getMaxOrder(): int;
/**
* @param Budget $budget
* @return string|null
*/
public function getNoteText(Budget $budget): ?string;
/**
* @param string $query
* @param int $limit
@ -175,20 +191,4 @@ interface BudgetRepositoryInterface
*/
public function update(Budget $budget, array $data): Budget;
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function budgetEndsWith(string $query, int $limit): Collection;
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function budgetStartsWith(string $query, int $limit): Collection;
}

View File

@ -61,7 +61,7 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
/** @var array $journal */
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$data[$currencyId] = $data[$currencyId] ?? [
'id' => 0,
@ -133,12 +133,12 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
/** @var TransactionCurrency $currency */
$currency = $currencies[$code];
$return[] = [
'currency_id' => (string)$currency['id'],
'currency_id' => (string) $currency['id'],
'currency_code' => $code,
'currency_name' => $currency['name'],
'currency_symbol' => $currency['symbol'],
'currency_decimal_places' => $currency['decimal_places'],
'amount' => number_format((float)$spent, $currency['decimal_places'], '.', ''),
'amount' => number_format((float) $spent, $currency['decimal_places'], '.', ''),
];
}
@ -176,7 +176,7 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'sum' => '0',
'currency_id' => $currencyId,

View File

@ -200,6 +200,19 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
/**
* @return Collection
*/
private function getBudgets(): Collection
{
/** @var BudgetRepositoryInterface $repos */
$repos = app(BudgetRepositoryInterface::class);
return $repos->getActiveBudgets();
}
/** @noinspection MoreThanThreeArgumentsInspection */
/**
* @param User $user
*/
@ -208,8 +221,6 @@ class OperationsRepository implements OperationsRepositoryInterface
$this->user = $user;
}
/** @noinspection MoreThanThreeArgumentsInspection */
/**
* @param Collection $budgets
* @param Collection $accounts
@ -371,17 +382,6 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
/**
* @return Collection
*/
private function getBudgets(): Collection
{
/** @var BudgetRepositoryInterface $repos */
$repos = app(BudgetRepositoryInterface::class);
return $repos->getActiveBudgets();
}
/**
* For now, simply refer to whichever repository holds this function.
* See reference nr. 14

View File

@ -46,6 +46,32 @@ class CategoryRepository implements CategoryRepositoryInterface
{
private User $user;
/**
* @inheritDoc
*/
public function categoryEndsWith(string $query, int $limit): Collection
{
$search = $this->user->categories();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%%%s', $query));
}
return $search->take($limit)->get();
}
/**
* @inheritDoc
*/
public function categoryStartsWith(string $query, int $limit): Collection
{
$search = $this->user->categories();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%s%%', $query));
}
return $search->take($limit)->get();
}
/**
* @param Category $category
*
@ -78,6 +104,44 @@ class CategoryRepository implements CategoryRepositoryInterface
}
}
/**
* Returns a list of all the categories belonging to a user.
*
* @return Collection
*/
public function getCategories(): Collection
{
return $this->user->categories()->with(['attachments'])->orderBy('name', 'ASC')->get();
}
/**
* @param int|null $categoryId
* @param string|null $categoryName
*
* @return Category|null
* @throws FireflyException
*/
public function findCategory(?int $categoryId, ?string $categoryName): ?Category
{
Log::debug('Now in findCategory()');
Log::debug(sprintf('Searching for category with ID #%d...', $categoryId));
$result = $this->find((int) $categoryId);
if (null === $result) {
Log::debug(sprintf('Searching for category with name %s...', $categoryName));
$result = $this->findByName((string) $categoryName);
if (null === $result && '' !== (string) $categoryName) {
// create it!
$result = $this->store(['name' => $categoryName]);
}
}
if (null !== $result) {
Log::debug(sprintf('Found category #%d: %s', $result->id, $result->name));
}
Log::debug(sprintf('Found category result is null? %s', var_export(null === $result, true)));
return $result;
}
/**
* Find a category or return NULL
*
@ -103,31 +167,54 @@ class CategoryRepository implements CategoryRepositoryInterface
}
/**
* @param int|null $categoryId
* @param string|null $categoryName
* @param array $data
*
* @return Category|null
* @return Category
* @throws FireflyException
*/
public function findCategory(?int $categoryId, ?string $categoryName): ?Category
public function store(array $data): Category
{
Log::debug('Now in findCategory()');
Log::debug(sprintf('Searching for category with ID #%d...', $categoryId));
$result = $this->find((int)$categoryId);
if (null === $result) {
Log::debug(sprintf('Searching for category with name %s...', $categoryName));
$result = $this->findByName((string)$categoryName);
if (null === $result && '' !== (string)$categoryName) {
// create it!
$result = $this->store(['name' => $categoryName]);
}
}
if (null !== $result) {
Log::debug(sprintf('Found category #%d: %s', $result->id, $result->name));
}
Log::debug(sprintf('Found category result is null? %s', var_export(null === $result, true)));
/** @var CategoryFactory $factory */
$factory = app(CategoryFactory::class);
$factory->setUser($this->user);
return $result;
$category = $factory->findOrCreate(null, $data['name']);
if (null === $category) {
throw new FireflyException(sprintf('400003: Could not store new category with name "%s"', $data['name']));
}
if (array_key_exists('notes', $data) && '' === $data['notes']) {
$this->removeNotes($category);
}
if (array_key_exists('notes', $data) && '' !== $data['notes']) {
$this->updateNotes($category, $data['notes']);
}
return $category;
}
/**
* @param Category $category
*/
public function removeNotes(Category $category): void
{
$category->notes()->delete();
}
/**
* @inheritDoc
*/
public function updateNotes(Category $category, string $notes): void
{
$dbNote = $category->notes()->first();
if (null === $dbNote) {
$dbNote = new Note;
$dbNote->noteable()->associate($category);
}
$dbNote->text = trim($notes);
$dbNote->save();
}
/**
@ -158,6 +245,43 @@ class CategoryRepository implements CategoryRepositoryInterface
return $firstJournalDate;
}
/**
* @param Category $category
*
* @return Carbon|null
*/
private function getFirstJournalDate(Category $category): ?Carbon
{
$query = $category->transactionJournals()->orderBy('date', 'ASC');
$result = $query->first(['transaction_journals.*']);
if (null !== $result) {
return $result->date;
}
return null;
}
/**
* @param Category $category
*
* @return Carbon|null
*/
private function getFirstTransactionDate(Category $category): ?Carbon
{
// check transactions:
$query = $category->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->orderBy('transaction_journals.date', 'ASC');
$lastTransaction = $query->first(['transaction_journals.*']);
if (null !== $lastTransaction) {
return new Carbon($lastTransaction->date);
}
return null;
}
/**
* @inheritDoc
*/
@ -191,16 +315,6 @@ class CategoryRepository implements CategoryRepositoryInterface
return $this->user->categories()->whereIn('id', $categoryIds)->get();
}
/**
* Returns a list of all the categories belonging to a user.
*
* @return Collection
*/
public function getCategories(): Collection
{
return $this->user->categories()->with(['attachments'])->orderBy('name', 'ASC')->get();
}
/**
* @inheritDoc
*/
@ -243,134 +357,6 @@ class CategoryRepository implements CategoryRepositoryInterface
return $lastJournalDate;
}
/**
* @param Category $category
*/
public function removeNotes(Category $category): void
{
$category->notes()->delete();
}
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function searchCategory(string $query, int $limit): Collection
{
$search = $this->user->categories();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%%%s%%', $query));
}
return $search->take($limit)->get();
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
/**
* @param array $data
*
* @return Category
* @throws FireflyException
*/
public function store(array $data): Category
{
/** @var CategoryFactory $factory */
$factory = app(CategoryFactory::class);
$factory->setUser($this->user);
$category = $factory->findOrCreate(null, $data['name']);
if (null === $category) {
throw new FireflyException(sprintf('400003: Could not store new category with name "%s"', $data['name']));
}
if (array_key_exists('notes', $data) && '' === $data['notes']) {
$this->removeNotes($category);
}
if (array_key_exists('notes', $data) && '' !== $data['notes']) {
$this->updateNotes($category, $data['notes']);
}
return $category;
}
/**
* @param Category $category
* @param array $data
*
* @return Category
* @throws Exception
*/
public function update(Category $category, array $data): Category
{
/** @var CategoryUpdateService $service */
$service = app(CategoryUpdateService::class);
$service->setUser($this->user);
return $service->update($category, $data);
}
/**
* @inheritDoc
*/
public function updateNotes(Category $category, string $notes): void
{
$dbNote = $category->notes()->first();
if (null === $dbNote) {
$dbNote = new Note;
$dbNote->noteable()->associate($category);
}
$dbNote->text = trim($notes);
$dbNote->save();
}
/**
* @param Category $category
*
* @return Carbon|null
*/
private function getFirstJournalDate(Category $category): ?Carbon
{
$query = $category->transactionJournals()->orderBy('date', 'ASC');
$result = $query->first(['transaction_journals.*']);
if (null !== $result) {
return $result->date;
}
return null;
}
/**
* @param Category $category
*
* @return Carbon|null
*/
private function getFirstTransactionDate(Category $category): ?Carbon
{
// check transactions:
$query = $category->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->orderBy('transaction_journals.date', 'ASC');
$lastTransaction = $query->first(['transaction_journals.*']);
if (null !== $lastTransaction) {
return new Carbon($lastTransaction->date);
}
return null;
}
/**
* @param Category $category
* @param Collection $accounts
@ -422,28 +408,42 @@ class CategoryRepository implements CategoryRepositoryInterface
}
/**
* @inheritDoc
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function categoryEndsWith(string $query, int $limit): Collection
public function searchCategory(string $query, int $limit): Collection
{
$search = $this->user->categories();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%%%s', $query));
$search->where('name', 'LIKE', sprintf('%%%s%%', $query));
}
return $search->take($limit)->get();
}
/**
* @inheritDoc
* @param User $user
*/
public function categoryStartsWith(string $query, int $limit): Collection
public function setUser(User $user): void
{
$search = $this->user->categories();
if ('' !== $query) {
$search->where('name', 'LIKE', sprintf('%s%%', $query));
}
$this->user = $user;
}
return $search->take($limit)->get();
/**
* @param Category $category
* @param array $data
*
* @return Category
* @throws Exception
*/
public function update(Category $category, array $data): Category
{
/** @var CategoryUpdateService $service */
$service = app(CategoryUpdateService::class);
$service->setUser($this->user);
return $service->update($category, $data);
}
}

View File

@ -34,6 +34,22 @@ use Illuminate\Support\Collection;
interface CategoryRepositoryInterface
{
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function categoryEndsWith(string $query, int $limit): Collection;
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function categoryStartsWith(string $query, int $limit): Collection;
/**
* @param Category $category
*
@ -134,22 +150,6 @@ interface CategoryRepositoryInterface
*/
public function searchCategory(string $query, int $limit): Collection;
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function categoryEndsWith(string $query, int $limit): Collection;
/**
* @param string $query
* @param int $limit
*
* @return Collection
*/
public function categoryStartsWith(string $query, int $limit): Collection;
/**
* @param User $user
*/

View File

@ -60,7 +60,7 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'categories' => [],
'currency_id' => $currencyId,
@ -72,13 +72,13 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
// info about the non-existent category:
$array[$currencyId]['categories'][0] = $array[$currencyId]['categories'][0] ?? [
'id' => 0,
'name' => (string)trans('firefly.noCategory'),
'name' => (string) trans('firefly.noCategory'),
'transaction_journals' => [],
];
// add journal to array:
// only a subset of the fields.
$journalId = (int)$journal['transaction_journal_id'];
$journalId = (int) $journal['transaction_journal_id'];
$array[$currencyId]['categories'][0]['transaction_journals'][$journalId]
= [
'amount' => app('steam')->negative($journal['amount']),
@ -113,7 +113,7 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'categories' => [],
'currency_id' => $currencyId,
@ -126,12 +126,12 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
// info about the non-existent category:
$array[$currencyId]['categories'][0] = $array[$currencyId]['categories'][0] ?? [
'id' => 0,
'name' => (string)trans('firefly.noCategory'),
'name' => (string) trans('firefly.noCategory'),
'transaction_journals' => [],
];
// add journal to array:
// only a subset of the fields.
$journalId = (int)$journal['transaction_journal_id'];
$journalId = (int) $journal['transaction_journal_id'];
$array[$currencyId]['categories'][0]['transaction_journals'][$journalId]
= [
'amount' => app('steam')->positive($journal['amount']),
@ -173,7 +173,7 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'sum' => '0',
'currency_id' => $currencyId,
@ -210,7 +210,7 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'sum' => '0',
'currency_id' => $currencyId,
@ -241,7 +241,7 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'sum' => '0',
'currency_id' => $currencyId,

View File

@ -70,9 +70,9 @@ class OperationsRepository implements OperationsRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$categoryId = (int)$journal['category_id'];
$categoryName = (string)$journal['category_name'];
$currencyId = (int) $journal['currency_id'];
$categoryId = (int) $journal['category_id'];
$categoryName = (string) $journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
@ -98,7 +98,7 @@ class OperationsRepository implements OperationsRepositoryInterface
// add journal to array:
// only a subset of the fields.
$journalId = (int)$journal['transaction_journal_id'];
$journalId = (int) $journal['transaction_journal_id'];
$array[$currencyId]['categories'][$categoryId]['transaction_journals'][$journalId] = [
'amount' => app('steam')->negative($journal['amount']),
'date' => $journal['date'],
@ -116,6 +116,16 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
/**
* Returns a list of all the categories belonging to a user.
*
* @return Collection
*/
private function getCategories(): Collection
{
return $this->user->categories()->get();
}
/**
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified category set to them. It's grouped per currency, with as few details in the array
@ -147,13 +157,13 @@ class OperationsRepository implements OperationsRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$categoryId = (int)$journal['category_id'];
$categoryName = (string)$journal['category_name'];
$currencyId = (int) $journal['currency_id'];
$categoryId = (int) $journal['category_id'];
$categoryName = (string) $journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
$categoryName = (string)trans('firefly.no_category');
$categoryName = (string) trans('firefly.no_category');
}
// info about the currency:
@ -175,7 +185,7 @@ class OperationsRepository implements OperationsRepositoryInterface
// add journal to array:
// only a subset of the fields.
$journalId = (int)$journal['transaction_journal_id'];
$journalId = (int) $journal['transaction_journal_id'];
$array[$currencyId]['categories'][$categoryId]['transaction_journals'][$journalId] = [
'amount' => app('steam')->positive($journal['amount']),
'date' => $journal['date'],
@ -192,6 +202,138 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
/**
* @inheritDoc
*/
public function listTransferredIn(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])
->setDestinationAccounts($accounts)->excludeSourceAccounts($accounts);
if (null !== $categories && $categories->count() > 0) {
$collector->setCategories($categories);
}
if (null === $categories || (null !== $categories && 0 === $categories->count())) {
$collector->setCategories($this->getCategories());
}
$collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation();
$journals = $collector->getExtractedJournals();
$array = [];
foreach ($journals as $journal) {
$currencyId = (int) $journal['currency_id'];
$categoryId = (int) $journal['category_id'];
$categoryName = (string) $journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
continue;
}
// info about the currency:
$array[$currencyId] = $array[$currencyId] ?? [
'categories' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
// info about the categories:
$array[$currencyId]['categories'][$categoryId] = $array[$currencyId]['categories'][$categoryId] ?? [
'id' => $categoryId,
'name' => $categoryName,
'transaction_journals' => [],
];
// add journal to array:
// only a subset of the fields.
$journalId = (int) $journal['transaction_journal_id'];
$array[$currencyId]['categories'][$categoryId]['transaction_journals'][$journalId] = [
'amount' => app('steam')->positive($journal['amount']),
'date' => $journal['date'],
'source_account_id' => $journal['source_account_id'],
'category_name' => $journal['category_name'],
'source_account_name' => $journal['source_account_name'],
'destination_account_id' => $journal['destination_account_id'],
'destination_account_name' => $journal['destination_account_name'],
'description' => $journal['description'],
'transaction_group_id' => $journal['transaction_group_id'],
];
}
return $array;
}
/**
* @inheritDoc
*/
public function listTransferredOut(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])
->setSourceAccounts($accounts)->excludeDestinationAccounts($accounts);
if (null !== $categories && $categories->count() > 0) {
$collector->setCategories($categories);
}
if (null === $categories || (null !== $categories && 0 === $categories->count())) {
$collector->setCategories($this->getCategories());
}
$collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation();
$journals = $collector->getExtractedJournals();
$array = [];
foreach ($journals as $journal) {
$currencyId = (int) $journal['currency_id'];
$categoryId = (int) $journal['category_id'];
$categoryName = (string) $journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
continue;
}
// info about the currency:
$array[$currencyId] = $array[$currencyId] ?? [
'categories' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
// info about the categories:
$array[$currencyId]['categories'][$categoryId] = $array[$currencyId]['categories'][$categoryId] ?? [
'id' => $categoryId,
'name' => $categoryName,
'transaction_journals' => [],
];
// add journal to array:
// only a subset of the fields.
$journalId = (int) $journal['transaction_journal_id'];
$array[$currencyId]['categories'][$categoryId]['transaction_journals'][$journalId] = [
'amount' => app('steam')->negative($journal['amount']),
'date' => $journal['date'],
'source_account_id' => $journal['source_account_id'],
'category_name' => $journal['category_name'],
'source_account_name' => $journal['source_account_name'],
'destination_account_id' => $journal['destination_account_id'],
'destination_account_name' => $journal['destination_account_name'],
'description' => $journal['description'],
'transaction_group_id' => $journal['transaction_group_id'],
];
}
return $array;
}
/**
* @param User $user
*/
@ -229,14 +371,14 @@ class OperationsRepository implements OperationsRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'sum' => '0',
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
'currency_decimal_places' => (int)$journal['currency_decimal_places'],
'currency_decimal_places' => (int) $journal['currency_decimal_places'],
];
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount']));
}
@ -272,7 +414,7 @@ class OperationsRepository implements OperationsRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'sum' => '0',
'currency_id' => $currencyId,
@ -315,7 +457,7 @@ class OperationsRepository implements OperationsRepositoryInterface
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'sum' => '0',
'currency_id' => $currencyId,
@ -329,146 +471,4 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
/**
* Returns a list of all the categories belonging to a user.
*
* @return Collection
*/
private function getCategories(): Collection
{
return $this->user->categories()->get();
}
/**
* @inheritDoc
*/
public function listTransferredIn(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])
->setDestinationAccounts($accounts)->excludeSourceAccounts($accounts);
if (null !== $categories && $categories->count() > 0) {
$collector->setCategories($categories);
}
if (null === $categories || (null !== $categories && 0 === $categories->count())) {
$collector->setCategories($this->getCategories());
}
$collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation();
$journals = $collector->getExtractedJournals();
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$categoryId = (int)$journal['category_id'];
$categoryName = (string)$journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
continue;
}
// info about the currency:
$array[$currencyId] = $array[$currencyId] ?? [
'categories' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
// info about the categories:
$array[$currencyId]['categories'][$categoryId] = $array[$currencyId]['categories'][$categoryId] ?? [
'id' => $categoryId,
'name' => $categoryName,
'transaction_journals' => [],
];
// add journal to array:
// only a subset of the fields.
$journalId = (int)$journal['transaction_journal_id'];
$array[$currencyId]['categories'][$categoryId]['transaction_journals'][$journalId] = [
'amount' => app('steam')->positive($journal['amount']),
'date' => $journal['date'],
'source_account_id' => $journal['source_account_id'],
'category_name' => $journal['category_name'],
'source_account_name' => $journal['source_account_name'],
'destination_account_id' => $journal['destination_account_id'],
'destination_account_name' => $journal['destination_account_name'],
'description' => $journal['description'],
'transaction_group_id' => $journal['transaction_group_id'],
];
}
return $array;
}
/**
* @inheritDoc
*/
public function listTransferredOut(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])
->setSourceAccounts($accounts)->excludeDestinationAccounts($accounts);
if (null !== $categories && $categories->count() > 0) {
$collector->setCategories($categories);
}
if (null === $categories || (null !== $categories && 0 === $categories->count())) {
$collector->setCategories($this->getCategories());
}
$collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation();
$journals = $collector->getExtractedJournals();
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$categoryId = (int)$journal['category_id'];
$categoryName = (string)$journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
continue;
}
// info about the currency:
$array[$currencyId] = $array[$currencyId] ?? [
'categories' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
// info about the categories:
$array[$currencyId]['categories'][$categoryId] = $array[$currencyId]['categories'][$categoryId] ?? [
'id' => $categoryId,
'name' => $categoryName,
'transaction_journals' => [],
];
// add journal to array:
// only a subset of the fields.
$journalId = (int)$journal['transaction_journal_id'];
$array[$currencyId]['categories'][$categoryId]['transaction_journals'][$journalId] = [
'amount' => app('steam')->negative($journal['amount']),
'date' => $journal['date'],
'source_account_id' => $journal['source_account_id'],
'category_name' => $journal['category_name'],
'source_account_name' => $journal['source_account_name'],
'destination_account_id' => $journal['destination_account_id'],
'destination_account_name' => $journal['destination_account_name'],
'description' => $journal['description'],
'transaction_group_id' => $journal['transaction_group_id'],
];
}
return $array;
}
}

View File

@ -47,6 +47,20 @@ interface OperationsRepositoryInterface
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array;
/**
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
*
* @param Carbon $start
* @param Carbon $end
* @param Collection|null $accounts
* @param Collection|null $categories
*
* @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array;
/**
* This method returns a list of all the transfer transaction journals (as arrays) set in that period
* which have the specified category set to them, transferred INTO the listed accounts.
@ -55,7 +69,7 @@ interface OperationsRepositoryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
* @param Collection $accounts
* @param Collection|null $categories
*
* @return array
@ -70,27 +84,13 @@ interface OperationsRepositoryInterface
*
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
* @param Collection $accounts
* @param Collection|null $categories
*
* @return array
*/
public function listTransferredOut(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array;
/**
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
*
* @param Carbon $start
* @param Carbon $end
* @param Collection|null $accounts
* @param Collection|null $categories
*
* @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array;
/**
* @param User $user
*/

View File

@ -48,19 +48,6 @@ class CurrencyRepository implements CurrencyRepositoryInterface
{
private User $user;
/**
* @param TransactionCurrency $currency
*
* @return int
*/
public function countJournals(TransactionCurrency $currency): int
{
$count = $currency->transactions()->whereNull('deleted_at')->count() + $currency->transactionJournals()->whereNull('deleted_at')->count();
// also count foreign:
return $count + Transaction::where('foreign_currency_id', $currency->id)->count();
}
/**
* @param TransactionCurrency $currency
*
@ -98,7 +85,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
}
// is being used in accounts:
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((string)$currency->id))->count();
$meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((string) $currency->id))->count();
if ($meta > 0) {
Log::info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
@ -127,7 +114,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface
$meta = AccountMeta
::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
->whereNull('accounts.deleted_at')
->where('account_meta.name', 'currency_id')->where('account_meta.data', json_encode((int)$currency->id))->count();
->where('account_meta.name', 'currency_id')->where('account_meta.data', json_encode((int) $currency->id))->count();
if ($meta > 0) {
Log::info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
@ -163,6 +150,27 @@ class CurrencyRepository implements CurrencyRepositoryInterface
return null;
}
/**
* @param TransactionCurrency $currency
*
* @return int
*/
public function countJournals(TransactionCurrency $currency): int
{
$count = $currency->transactions()->whereNull('deleted_at')->count() + $currency->transactionJournals()->whereNull('deleted_at')->count();
// also count foreign:
return $count + Transaction::where('foreign_currency_id', $currency->id)->count();
}
/**
* @return Collection
*/
public function getAll(): Collection
{
return TransactionCurrency::orderBy('code', 'ASC')->get();
}
/**
* @param TransactionCurrency $currency
*
@ -192,40 +200,6 @@ class CurrencyRepository implements CurrencyRepositoryInterface
$currency->save();
}
/**
* @param TransactionCurrency $currency
* Enables a currency
*/
public function enable(TransactionCurrency $currency): void
{
$currency->enabled = true;
$currency->save();
}
/**
* Find by ID, return NULL if not found.
*
* @param int $currencyId
*
* @return TransactionCurrency|null
*/
public function find(int $currencyId): ?TransactionCurrency
{
return TransactionCurrency::find($currencyId);
}
/**
* Find by currency code, return NULL if unfound.
*
* @param string $currencyCode
*
* @return TransactionCurrency|null
*/
public function findByCode(string $currencyCode): ?TransactionCurrency
{
return TransactionCurrency::where('code', $currencyCode)->first();
}
/**
* Find by currency code, return NULL if unfound.
* Used in Import Currency!
@ -333,10 +307,10 @@ class CurrencyRepository implements CurrencyRepositoryInterface
public function findCurrencyNull(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
{
Log::debug('Now in findCurrencyNull()');
$result = $this->find((int)$currencyId);
$result = $this->find((int) $currencyId);
if (null === $result) {
Log::debug(sprintf('Searching for currency with code %s...', $currencyCode));
$result = $this->findByCode((string)$currencyCode);
$result = $this->findByCode((string) $currencyCode);
}
if (null !== $result && false === $result->enabled) {
Log::debug(sprintf('Also enabled currency %s', $result->code));
@ -347,19 +321,45 @@ class CurrencyRepository implements CurrencyRepositoryInterface
}
/**
* @return Collection
* Find by ID, return NULL if not found.
*
* @param int $currencyId
*
* @return TransactionCurrency|null
*/
public function get(): Collection
public function find(int $currencyId): ?TransactionCurrency
{
return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
return TransactionCurrency::find($currencyId);
}
/**
* Find by currency code, return NULL if unfound.
*
* @param string $currencyCode
*
* @return TransactionCurrency|null
*/
public function findByCode(string $currencyCode): ?TransactionCurrency
{
return TransactionCurrency::where('code', $currencyCode)->first();
}
/**
* @param TransactionCurrency $currency
* Enables a currency
*/
public function enable(TransactionCurrency $currency): void
{
$currency->enabled = true;
$currency->save();
}
/**
* @return Collection
*/
public function getAll(): Collection
public function get(): Collection
{
return TransactionCurrency::orderBy('code', 'ASC')->get();
return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
}
/**

View File

@ -69,9 +69,9 @@ class JournalAPIRepository implements JournalAPIRepositoryInterface
return $set->each(
static function (Attachment $attachment) use ($disk) {
$notes = $attachment->notes()->first();
$notes = $attachment->notes()->first();
$attachment->file_exists = $disk->exists($attachment->fileName());
$attachment->notes = $notes ? $notes->text : '';
$attachment->notes = $notes ? $notes->text : '';
return $attachment;
}

View File

@ -190,7 +190,7 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
}
// return when something else:
$return = (string)$value;
$return = (string) $value;
try {
$cache->store($return);
} catch (Exception $e) { // @phpstan-ignore-line
@ -232,8 +232,8 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
$journalIds = [];
/** @var stdClass $row */
foreach ($result as $row) {
if ((int)$row->transaction_count > 2) {
$journalIds[] = (int)$row->id;
if ((int) $row->transaction_count > 2) {
$journalIds[] = (int) $row->id;
}
}
$journalIds = array_unique($journalIds);

View File

@ -143,7 +143,7 @@ class JournalRepository implements JournalRepositoryInterface
// saves on queries:
$amount = $journal->transactions()->where('amount', '>', 0)->get()->sum('amount');
$amount = (string)$amount;
$amount = (string) $amount;
$cache->store($amount);
return $amount;

View File

@ -80,30 +80,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return true;
}
/**
* @param int $linkTypeId
*
* @return LinkType|null
*/
public function find(int $linkTypeId): ?LinkType
{
return LinkType::find($linkTypeId);
}
/**
* @param string|null $name
*
* @return LinkType|null
*/
public function findByName(string $name = null): ?LinkType
{
if (null === $name) {
return null;
}
return LinkType::where('name', $name)->first();
}
/**
* Check if link exists between journals.
*
@ -121,24 +97,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $count + $opposingCount > 0;
}
/**
* See if such a link already exists (and get it).
*
* @param LinkType $linkType
* @param TransactionJournal $inward
* @param TransactionJournal $outward
*
* @return TransactionJournalLink|null
*/
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();
}
/**
* @return Collection
*/
@ -188,6 +146,16 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $query->get(['journal_links.*']);
}
public function getLink(TransactionJournal $one, TransactionJournal $two): ?TransactionJournalLink
{
$left = TransactionJournalLink::whereDestinationId($one->id)->whereSourceId($two->id)->first();
if (null !== $left) {
return $left;
}
return TransactionJournalLink::whereDestinationId($two->id)->whereSourceId($one->id)->first();
}
/**
* Return list of existing connections.
*
@ -245,7 +213,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
*/
public function storeLink(array $information, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink
{
$linkType = $this->find((int)($information['link_type_id'] ?? 0));
$linkType = $this->find((int) ($information['link_type_id'] ?? 0));
if (null === $linkType) {
$linkType = $this->findByName($information['link_type_name']);
@ -277,11 +245,96 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
$link->save();
// make note in noteable:
$this->setNoteText($link, (string)$information['notes']);
$this->setNoteText($link, (string) $information['notes']);
return $link;
}
/**
* @param int $linkTypeId
*
* @return LinkType|null
*/
public function find(int $linkTypeId): ?LinkType
{
return LinkType::find($linkTypeId);
}
/**
* @param string|null $name
*
* @return LinkType|null
*/
public function findByName(string $name = null): ?LinkType
{
if (null === $name) {
return null;
}
return LinkType::where('name', $name)->first();
}
/**
* See if such a link already exists (and get it).
*
* @param LinkType $linkType
* @param TransactionJournal $inward
* @param TransactionJournal $outward
*
* @return TransactionJournalLink|null
*/
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();
}
/**
* @param TransactionJournalLink $link
* @param string $text
*
* @throws Exception
*/
private function setNoteText(TransactionJournalLink $link, string $text): void
{
$dbNote = $link->notes()->first();
if ('' !== $text) {
if (null === $dbNote) {
$dbNote = new Note();
$dbNote->noteable()->associate($link);
}
$dbNote->text = trim($text);
$dbNote->save();
return;
}
if (null !== $dbNote && '' === $text) {
try {
$dbNote->delete();
} catch (Exception $e) { // @phpstan-ignore-line
// @ignoreException
}
}
}
/**
* @inheritDoc
*/
public function switchLinkById(int $linkId): bool
{
/** @var TransactionJournalLink $link */
$link = TransactionJournalLink::find($linkId);
if (null !== $link && $link->source->user->id === $this->user->id) {
$this->switchLink($link);
}
return true;
}
/**
* @param TransactionJournalLink $link
*
@ -305,13 +358,13 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
*/
public function update(LinkType $linkType, array $data): LinkType
{
if (array_key_exists('name', $data) && '' !== (string)$data['name']) {
if (array_key_exists('name', $data) && '' !== (string) $data['name']) {
$linkType->name = $data['name'];
}
if (array_key_exists('inward', $data) && '' !== (string)$data['inward']) {
if (array_key_exists('inward', $data) && '' !== (string) $data['inward']) {
$linkType->inward = $data['inward'];
}
if (array_key_exists('outward', $data) && '' !== (string)$data['outward']) {
if (array_key_exists('outward', $data) && '' !== (string) $data['outward']) {
$linkType->outward = $data['outward'];
}
$linkType->save();
@ -350,57 +403,4 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $journalLink;
}
/**
* @param TransactionJournalLink $link
* @param string $text
*
* @throws Exception
*/
private function setNoteText(TransactionJournalLink $link, string $text): void
{
$dbNote = $link->notes()->first();
if ('' !== $text) {
if (null === $dbNote) {
$dbNote = new Note();
$dbNote->noteable()->associate($link);
}
$dbNote->text = trim($text);
$dbNote->save();
return;
}
if (null !== $dbNote && '' === $text) {
try {
$dbNote->delete();
} catch (Exception $e) { // @phpstan-ignore-line
// @ignoreException
}
}
}
public function getLink(TransactionJournal $one, TransactionJournal $two): ?TransactionJournalLink
{
$left = TransactionJournalLink::whereDestinationId($one->id)->whereSourceId($two->id)->first();
if (null !== $left) {
return $left;
}
return TransactionJournalLink::whereDestinationId($two->id)->whereSourceId($one->id)->first();
}
/**
* @inheritDoc
*/
public function switchLinkById(int $linkId): bool
{
/** @var TransactionJournalLink $link */
$link = TransactionJournalLink::find($linkId);
if (null !== $link && $link->source->user->id === $this->user->id) {
$this->switchLink($link);
}
return true;
}
}

View File

@ -67,7 +67,7 @@ trait CreatesObjectGroups
*/
protected function getObjectGroupMaxOrder(): int
{
return (int)$this->user->objectGroups()->max('order');
return (int) $this->user->objectGroups()->max('order');
}
/**

View File

@ -52,6 +52,17 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
}
}
/**
* @inheritDoc
*/
public function get(): Collection
{
return $this->user->objectGroups()
->with(['piggyBanks', 'bills'])
->orderBy('order', 'ASC')
->orderBy('title', 'ASC')->get();
}
/**
* @inheritDoc
*/
@ -81,17 +92,6 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
$objectGroup->delete();
}
/**
* @inheritDoc
*/
public function get(): Collection
{
return $this->user->objectGroups()
->with(['piggyBanks', 'bills'])
->orderBy('order', 'ASC')
->orderBy('title', 'ASC')->get();
}
/**
* @inheritDoc
*/
@ -118,7 +118,7 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
$index = 1;
/** @var ObjectGroup $objectGroup */
foreach ($list as $objectGroup) {
if ($index !== (int)$objectGroup->order) {
if ($index !== (int) $objectGroup->order) {
Log::debug(
sprintf('objectGroup #%d ("%s"): order should %d be but is %d.', $objectGroup->id, $objectGroup->title, $index, $objectGroup->order)
);
@ -151,12 +151,38 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
return $dbQuery->take($limit)->get(['object_groups.*']);
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
/**
* @inheritDoc
*/
public function update(ObjectGroup $objectGroup, array $data): ObjectGroup
{
if (array_key_exists('title', $data)) {
$objectGroup->title = $data['title'];
}
if (array_key_exists('order', $data)) {
$this->setOrder($objectGroup, (int) $data['order']);
}
$objectGroup->save();
return $objectGroup;
}
/**
* @inheritDoc
*/
public function setOrder(ObjectGroup $objectGroup, int $newOrder): ObjectGroup
{
$oldOrder = (int)$objectGroup->order;
$oldOrder = (int) $objectGroup->order;
if ($newOrder > $oldOrder) {
$this->user->objectGroups()->where('object_groups.order', '<=', $newOrder)->where('object_groups.order', '>', $oldOrder)
@ -179,30 +205,4 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
return $objectGroup;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
/**
* @inheritDoc
*/
public function update(ObjectGroup $objectGroup, array $data): ObjectGroup
{
if (array_key_exists('title', $data)) {
$objectGroup->title = $data['title'];
}
if (array_key_exists('order', $data)) {
$this->setOrder($objectGroup, (int)$data['order']);
}
$objectGroup->save();
return $objectGroup;
}
}

View File

@ -127,21 +127,6 @@ trait ModifiesPiggyBanks
return bccomp($amount, $savedSoFar) <= 0;
}
/**
* @param PiggyBank $piggyBank
* @param string $amount
*
* @return PiggyBankEvent
*/
public function createEvent(PiggyBank $piggyBank, string $amount): PiggyBankEvent
{
if (0 === bccomp('0', $amount)) {
return new PiggyBankEvent;
}
return PiggyBankEvent::create(['date' => Carbon::now(), 'amount' => $amount, 'piggy_bank_id' => $piggyBank->id]);
}
/**
* @param PiggyBank $piggyBank
* @param string $amount
@ -195,6 +180,21 @@ trait ModifiesPiggyBanks
return true;
}
/**
* @param PiggyBank $piggyBank
* @param string $amount
*
* @return PiggyBankEvent
*/
public function createEvent(PiggyBank $piggyBank, string $amount): PiggyBankEvent
{
if (0 === bccomp('0', $amount)) {
return new PiggyBankEvent;
}
return PiggyBankEvent::create(['date' => Carbon::now(), 'amount' => $amount, 'piggy_bank_id' => $piggyBank->id]);
}
/**
* @inheritDoc
*/
@ -205,23 +205,6 @@ trait ModifiesPiggyBanks
return $piggyBank;
}
/**
* Correct order of piggies in case of issues.
*/
public function resetOrder(): void
{
$set = $this->user->piggyBanks()->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']);
$current = 1;
foreach ($set as $piggyBank) {
if ((int) $piggyBank->order !== $current) {
Log::debug(sprintf('Piggy bank #%d ("%s") was at place %d but should be on %d', $piggyBank->id, $piggyBank->name, $piggyBank->order, $current));
$piggyBank->order = $current;
$piggyBank->save();
}
$current++;
}
}
/**
* @param PiggyBank $piggyBank
* @param string $amount
@ -262,34 +245,6 @@ trait ModifiesPiggyBanks
}
/**
* @inheritDoc
*/
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool
{
$oldOrder = (int) $piggyBank->order;
Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
if ($newOrder > $oldOrder) {
$this->user->piggyBanks()->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder)
->where('piggy_banks.id', '!=', $piggyBank->id)
->decrement('piggy_banks.order');
$piggyBank->order = $newOrder;
Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder));
$piggyBank->save();
return true;
}
$this->user->piggyBanks()->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder)
->where('piggy_banks.id', '!=', $piggyBank->id)
->increment('piggy_banks.order');
$piggyBank->order = $newOrder;
Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder));
$piggyBank->save();
return true;
}
/**
* @param array $data
*
@ -349,6 +304,82 @@ trait ModifiesPiggyBanks
return $piggyBank;
}
/**
* Correct order of piggies in case of issues.
*/
public function resetOrder(): void
{
$set = $this->user->piggyBanks()->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']);
$current = 1;
foreach ($set as $piggyBank) {
if ((int) $piggyBank->order !== $current) {
Log::debug(sprintf('Piggy bank #%d ("%s") was at place %d but should be on %d', $piggyBank->id, $piggyBank->name, $piggyBank->order, $current));
$piggyBank->order = $current;
$piggyBank->save();
}
$current++;
}
}
/**
* @inheritDoc
*/
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool
{
$oldOrder = (int) $piggyBank->order;
Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
if ($newOrder > $oldOrder) {
$this->user->piggyBanks()->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder)
->where('piggy_banks.id', '!=', $piggyBank->id)
->decrement('piggy_banks.order');
$piggyBank->order = $newOrder;
Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder));
$piggyBank->save();
return true;
}
$this->user->piggyBanks()->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder)
->where('piggy_banks.id', '!=', $piggyBank->id)
->increment('piggy_banks.order');
$piggyBank->order = $newOrder;
Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder));
$piggyBank->save();
return true;
}
/**
* @param PiggyBank $piggyBank
* @param string $note
*
* @return bool
*/
private function updateNote(PiggyBank $piggyBank, string $note): bool
{
if ('' === $note) {
$dbNote = $piggyBank->notes()->first();
if (null !== $dbNote) {
try {
$dbNote->delete();
} catch (Exception $e) { // @phpstan-ignore-line
// @ignoreException
}
}
return true;
}
$dbNote = $piggyBank->notes()->first();
if (null === $dbNote) {
$dbNote = new Note;
$dbNote->noteable()->associate($piggyBank);
}
$dbNote->text = trim($note);
$dbNote->save();
return true;
}
/**
* @param PiggyBank $piggyBank
* @param array $data
@ -416,37 +447,6 @@ trait ModifiesPiggyBanks
return $piggyBank;
}
/**
* @param PiggyBank $piggyBank
* @param string $note
*
* @return bool
*/
private function updateNote(PiggyBank $piggyBank, string $note): bool
{
if ('' === $note) {
$dbNote = $piggyBank->notes()->first();
if (null !== $dbNote) {
try {
$dbNote->delete();
} catch (Exception $e) { // @phpstan-ignore-line
// @ignoreException
}
}
return true;
}
$dbNote = $piggyBank->notes()->first();
if (null === $dbNote) {
$dbNote = new Note;
$dbNote->noteable()->associate($piggyBank);
}
$dbNote->text = trim($note);
$dbNote->save();
return true;
}
/**
* @param PiggyBank $piggyBank
* @param array $data

View File

@ -54,6 +54,37 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
$this->user->piggyBanks()->delete();
}
/**
* @param int|null $piggyBankId
* @param string|null $piggyBankName
*
* @return PiggyBank|null
*/
public function findPiggyBank(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank
{
Log::debug('Searching for piggy information.');
if (null !== $piggyBankId) {
$searchResult = $this->find((int) $piggyBankId);
if (null !== $searchResult) {
Log::debug(sprintf('Found piggy based on #%d, will return it.', $piggyBankId));
return $searchResult;
}
}
if (null !== $piggyBankName) {
$searchResult = $this->findByName((string) $piggyBankName);
if (null !== $searchResult) {
Log::debug(sprintf('Found piggy based on "%s", will return it.', $piggyBankName));
return $searchResult;
}
}
Log::debug('Found nothing');
return null;
}
/**
* @param int $piggyBankId
*
@ -76,37 +107,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return $this->user->piggyBanks()->where('piggy_banks.name', $name)->first(['piggy_banks.*']);
}
/**
* @param int|null $piggyBankId
* @param string|null $piggyBankName
*
* @return PiggyBank|null
*/
public function findPiggyBank(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank
{
Log::debug('Searching for piggy information.');
if (null !== $piggyBankId) {
$searchResult = $this->find((int)$piggyBankId);
if (null !== $searchResult) {
Log::debug(sprintf('Found piggy based on #%d, will return it.', $piggyBankId));
return $searchResult;
}
}
if (null !== $piggyBankName) {
$searchResult = $this->findByName((string)$piggyBankName);
if (null !== $searchResult) {
Log::debug(sprintf('Found piggy based on "%s", will return it.', $piggyBankName));
return $searchResult;
}
}
Log::debug('Found nothing');
return null;
}
/**
* @inheritDoc
*/
@ -142,7 +142,17 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return '0';
}
return (string)$rep->currentamount;
return (string) $rep->currentamount;
}
/**
* @param PiggyBank $piggyBank
*
* @return PiggyBankRepetition|null
*/
public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition
{
return $piggyBank->piggyBankRepetitions()->first();
}
/**
@ -210,11 +220,11 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
// currency of the account + the piggy bank currency are almost the same.
// which amount from the transaction matches?
$amount = null;
if ((int)$source->transaction_currency_id === (int)$currency->id) {
if ((int) $source->transaction_currency_id === (int) $currency->id) {
Log::debug('Use normal amount');
$amount = app('steam')->$operator($source->amount);
}
if ((int)$source->foreign_currency_id === (int)$currency->id) {
if ((int) $source->foreign_currency_id === (int) $currency->id) {
Log::debug('Use foreign amount');
$amount = app('steam')->$operator($source->foreign_amount);
}
@ -225,7 +235,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
}
Log::debug(sprintf('The currency is %s and the amount is %s', $currency->code, $amount));
$room = bcsub((string)$piggyBank->targetamount, (string)$repetition->currentamount);
$room = bcsub((string) $piggyBank->targetamount, (string) $repetition->currentamount);
$compare = bcmul($repetition->currentamount, '-1');
Log::debug(sprintf('Will add/remove %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
@ -248,7 +258,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return $compare;
}
return (string)$amount;
return (string) $amount;
}
/**
@ -256,7 +266,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
*/
public function getMaxOrder(): int
{
return (int)$this->user->piggyBanks()->max('piggy_banks.order');
return (int) $this->user->piggyBanks()->max('piggy_banks.order');
}
/**
@ -277,14 +287,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return $note->text;
}
/**
* @return Collection
*/
public function getPiggyBanks(): Collection
{
return $this->user->piggyBanks()->with(['account', 'objectGroups'])->orderBy('order', 'ASC')->get();
}
/**
* Also add amount in name.
*
@ -307,13 +309,11 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
}
/**
* @param PiggyBank $piggyBank
*
* @return PiggyBankRepetition|null
* @return Collection
*/
public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition
public function getPiggyBanks(): Collection
{
return $piggyBank->piggyBankRepetitions()->first();
return $this->user->piggyBanks()->with(['account', 'objectGroups'])->orderBy('order', 'ASC')->get();
}
/**
@ -338,7 +338,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
// more than 1 month to go and still need money to save:
if ($diffInMonths > 0 && 1 === bccomp($remainingAmount, '0')) {
$savePerMonth = bcdiv($remainingAmount, (string)$diffInMonths);
$savePerMonth = bcdiv($remainingAmount, (string) $diffInMonths);
}
// less than 1 month to go but still need money to save:

View File

@ -107,6 +107,22 @@ class RecurringRepository implements RecurringRepositoryInterface
->get();
}
/**
* @inheritDoc
*/
public function getBillId(RecurrenceTransaction $recTransaction): ?int
{
$return = null;
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('bill_id' === $meta->name) {
$return = (int) $meta->value;
}
}
return $return;
}
/**
* Get the budget ID from a recurring transaction transaction.
*
@ -120,7 +136,7 @@ class RecurringRepository implements RecurringRepositoryInterface
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('budget_id' === $meta->name) {
$return = (int)$meta->value;
$return = (int) $meta->value;
}
}
@ -140,7 +156,7 @@ class RecurringRepository implements RecurringRepositoryInterface
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('category_id' === $meta->name) {
$return = (int)$meta->value;
$return = (int) $meta->value;
}
}
@ -160,7 +176,7 @@ class RecurringRepository implements RecurringRepositoryInterface
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('category_name' === $meta->name) {
$return = (string)$meta->value;
$return = (string) $meta->value;
}
}
@ -206,7 +222,7 @@ class RecurringRepository implements RecurringRepositoryInterface
return TransactionJournalMeta::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
->where('transaction_journals.user_id', $this->user->id)
->where('journal_meta.name', '=', 'recurrence_id')
->where('journal_meta.data', '=', json_encode((string)$recurrence->id))
->where('journal_meta.data', '=', json_encode((string) $recurrence->id))
->get(['journal_meta.transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
}
@ -222,51 +238,12 @@ class RecurringRepository implements RecurringRepositoryInterface
/** @var Note $note */
$note = $recurrence->notes()->first();
if (null !== $note) {
return (string)$note->text;
return (string) $note->text;
}
return '';
}
/**
* Generate events in the date range.
*
* @param RecurrenceRepetition $repetition
* @param Carbon $start
* @param Carbon $end
*
* @return array
*
*/
public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array
{
$occurrences = [];
$mutator = clone $start;
$mutator->startOfDay();
$skipMod = $repetition->repetition_skip + 1;
Log::debug(sprintf('Calculating occurrences for rep type "%s"', $repetition->repetition_type));
Log::debug(sprintf('Mutator is now: %s', $mutator->format('Y-m-d')));
if ('daily' === $repetition->repetition_type) {
$occurrences = $this->getDailyInRange($mutator, $end, $skipMod);
}
if ('weekly' === $repetition->repetition_type) {
$occurrences = $this->getWeeklyInRange($mutator, $end, $skipMod, $repetition->repetition_moment);
}
if ('monthly' === $repetition->repetition_type) {
$occurrences = $this->getMonthlyInRange($mutator, $end, $skipMod, $repetition->repetition_moment);
}
if ('ndom' === $repetition->repetition_type) {
$occurrences = $this->getNdomInRange($mutator, $end, $skipMod, $repetition->repetition_moment);
}
if ('yearly' === $repetition->repetition_type) {
$occurrences = $this->getYearlyInRange($mutator, $end, $skipMod, $repetition->repetition_moment);
}
// filter out all the weekend days:
return $this->filterWeekends($repetition, $occurrences);
}
/**
* @param RecurrenceTransaction $transaction
*
@ -278,7 +255,7 @@ class RecurringRepository implements RecurringRepositoryInterface
/** @var RecurrenceTransactionMeta $metaEntry */
foreach ($meta as $metaEntry) {
if ('piggy_bank_id' === $metaEntry->name) {
return (int)$metaEntry->value;
return (int) $metaEntry->value;
}
}
@ -320,11 +297,11 @@ class RecurringRepository implements RecurringRepositoryInterface
->whereNull('transaction_journals.deleted_at')
->where('transaction_journals.user_id', $this->user->id)
->where('name', 'recurrence_id')
->where('data', json_encode((string)$recurrence->id))
->where('data', json_encode((string) $recurrence->id))
->get()->pluck('transaction_journal_id')->toArray();
$search = [];
foreach ($journalMeta as $journalId) {
$search[] = (int)$journalId;
$search[] = (int) $journalId;
}
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
@ -349,12 +326,12 @@ class RecurringRepository implements RecurringRepositoryInterface
->whereNull('transaction_journals.deleted_at')
->where('transaction_journals.user_id', $this->user->id)
->where('name', 'recurrence_id')
->where('data', json_encode((string)$recurrence->id))
->where('data', json_encode((string) $recurrence->id))
->get()->pluck('transaction_journal_id')->toArray();
$search = [];
foreach ($journalMeta as $journalId) {
$search[] = (int)$journalId;
$search[] = (int) $journalId;
}
if (empty($search)) {
@ -449,6 +426,27 @@ class RecurringRepository implements RecurringRepositoryInterface
return $this->filterMaxDate($repeatUntil, $occurrences);
}
/**
* @param Carbon|null $max
* @param array $occurrences
*
* @return array
*/
private function filterMaxDate(?Carbon $max, array $occurrences): array
{
if (null === $max) {
return $occurrences;
}
$filtered = [];
foreach ($occurrences as $date) {
if ($date->lte($max)) {
$filtered[] = $date;
}
}
return $filtered;
}
/**
* Parse the repetition in a string that is user readable.
*
@ -464,25 +462,25 @@ class RecurringRepository implements RecurringRepositoryInterface
$pref = app('preferences')->getForUser($this->user, 'language', config('firefly.default_language', 'en_US'));
$language = $pref->data;
if ('daily' === $repetition->repetition_type) {
return (string)trans('firefly.recurring_daily', [], $language);
return (string) trans('firefly.recurring_daily', [], $language);
}
if ('weekly' === $repetition->repetition_type) {
$dayOfWeek = trans(sprintf('config.dow_%s', $repetition->repetition_moment), [], $language);
if ($repetition->repetition_skip > 0) {
return (string)trans('firefly.recurring_weekly_skip', ['weekday' => $dayOfWeek, 'skip' => $repetition->repetition_skip + 1], $language);
return (string) trans('firefly.recurring_weekly_skip', ['weekday' => $dayOfWeek, 'skip' => $repetition->repetition_skip + 1], $language);
}
return (string)trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek], $language);
return (string) trans('firefly.recurring_weekly', ['weekday' => $dayOfWeek], $language);
}
if ('monthly' === $repetition->repetition_type) {
if ($repetition->repetition_skip > 0) {
return (string)trans(
return (string) trans(
'firefly.recurring_monthly_skip', ['dayOfMonth' => $repetition->repetition_moment, 'skip' => $repetition->repetition_skip + 1], $language
);
}
return (string)trans(
return (string) trans(
'firefly.recurring_monthly', ['dayOfMonth' => $repetition->repetition_moment, 'skip' => $repetition->repetition_skip - 1], $language
);
}
@ -491,7 +489,7 @@ class RecurringRepository implements RecurringRepositoryInterface
// first part is number of week, second is weekday.
$dayOfWeek = trans(sprintf('config.dow_%s', $parts[1]), [], $language);
return (string)trans('firefly.recurring_ndom', ['weekday' => $dayOfWeek, 'dayOfMonth' => $parts[0]], $language);
return (string) trans('firefly.recurring_ndom', ['weekday' => $dayOfWeek, 'dayOfMonth' => $parts[0]], $language);
}
if ('yearly' === $repetition->repetition_type) {
//
@ -499,9 +497,9 @@ class RecurringRepository implements RecurringRepositoryInterface
$repDate = Carbon::createFromFormat('Y-m-d', $repetition->repetition_moment);
$diffInYears = $today->diffInYears($repDate);
$repDate->addYears($diffInYears); // technically not necessary.
$string = $repDate->isoFormat((string)trans('config.month_and_day_no_year_js'));
$string = $repDate->isoFormat((string) trans('config.month_and_day_no_year_js'));
return (string)trans('firefly.recurring_yearly', ['date' => $string], $language);
return (string) trans('firefly.recurring_yearly', ['date' => $string], $language);
}
return '';
@ -558,16 +556,16 @@ class RecurringRepository implements RecurringRepositoryInterface
public function totalTransactions(Recurrence $recurrence, RecurrenceRepetition $repetition): int
{
// if repeat = null just return 0.
if (null === $recurrence->repeat_until && 0 === (int)$recurrence->repetitions) {
if (null === $recurrence->repeat_until && 0 === (int) $recurrence->repetitions) {
return 0;
}
// expect X transactions then stop. Return that number
if (null === $recurrence->repeat_until && 0 !== (int)$recurrence->repetitions) {
return (int)$recurrence->repetitions;
if (null === $recurrence->repeat_until && 0 !== (int) $recurrence->repetitions) {
return (int) $recurrence->repetitions;
}
// need to calculate, this depends on the repetition:
if (null !== $recurrence->repeat_until && 0 === (int)$recurrence->repetitions) {
if (null !== $recurrence->repeat_until && 0 === (int) $recurrence->repetitions) {
$occurrences = $this->getOccurrencesInRange($repetition, $recurrence->first_date ?? today(), $recurrence->repeat_until);
return count($occurrences);
@ -576,6 +574,45 @@ class RecurringRepository implements RecurringRepositoryInterface
return 0;
}
/**
* Generate events in the date range.
*
* @param RecurrenceRepetition $repetition
* @param Carbon $start
* @param Carbon $end
*
* @return array
*
*/
public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array
{
$occurrences = [];
$mutator = clone $start;
$mutator->startOfDay();
$skipMod = $repetition->repetition_skip + 1;
Log::debug(sprintf('Calculating occurrences for rep type "%s"', $repetition->repetition_type));
Log::debug(sprintf('Mutator is now: %s', $mutator->format('Y-m-d')));
if ('daily' === $repetition->repetition_type) {
$occurrences = $this->getDailyInRange($mutator, $end, $skipMod);
}
if ('weekly' === $repetition->repetition_type) {
$occurrences = $this->getWeeklyInRange($mutator, $end, $skipMod, $repetition->repetition_moment);
}
if ('monthly' === $repetition->repetition_type) {
$occurrences = $this->getMonthlyInRange($mutator, $end, $skipMod, $repetition->repetition_moment);
}
if ('ndom' === $repetition->repetition_type) {
$occurrences = $this->getNdomInRange($mutator, $end, $skipMod, $repetition->repetition_moment);
}
if ('yearly' === $repetition->repetition_type) {
$occurrences = $this->getYearlyInRange($mutator, $end, $skipMod, $repetition->repetition_moment);
}
// filter out all the weekend days:
return $this->filterWeekends($repetition, $occurrences);
}
/**
* Update a recurring transaction.
*
@ -592,41 +629,4 @@ class RecurringRepository implements RecurringRepositoryInterface
return $service->update($recurrence, $data);
}
/**
* @param Carbon|null $max
* @param array $occurrences
*
* @return array
*/
private function filterMaxDate(?Carbon $max, array $occurrences): array
{
if (null === $max) {
return $occurrences;
}
$filtered = [];
foreach ($occurrences as $date) {
if ($date->lte($max)) {
$filtered[] = $date;
}
}
return $filtered;
}
/**
* @inheritDoc
*/
public function getBillId(RecurrenceTransaction $recTransaction): ?int
{
$return = null;
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('bill_id' === $meta->name) {
$return = (int)$meta->value;
}
}
return $return;
}
}

View File

@ -64,6 +64,15 @@ interface RecurringRepositoryInterface
*/
public function getAll(): Collection;
/**
* Get the category from a recurring transaction transaction.
*
* @param RecurrenceTransaction $recTransaction
*
* @return null|int
*/
public function getBillId(RecurrenceTransaction $recTransaction): ?int;
/**
* Get the budget ID from a recurring transaction transaction.
*
@ -82,15 +91,6 @@ interface RecurringRepositoryInterface
*/
public function getCategoryId(RecurrenceTransaction $recTransaction): ?int;
/**
* Get the category from a recurring transaction transaction.
*
* @param RecurrenceTransaction $recTransaction
*
* @return null|int
*/
public function getBillId(RecurrenceTransaction $recTransaction): ?int;
/**
* Get the category from a recurring transaction transaction.
*

View File

@ -76,7 +76,7 @@ class RuleRepository implements RuleRepositoryInterface
public function duplicate(Rule $rule): Rule
{
$newRule = $rule->replicate();
$newRule->title = (string)trans('firefly.rule_copy_of', ['title' => $rule->title]);
$newRule->title = (string) trans('firefly.rule_copy_of', ['title' => $rule->title]);
$newRule->save();
// replicate all triggers
@ -135,7 +135,7 @@ class RuleRepository implements RuleRepositoryInterface
*/
public function getHighestOrderInRuleGroup(RuleGroup $ruleGroup): int
{
return (int)$ruleGroup->rules()->max('order');
return (int) $ruleGroup->rules()->max('order');
}
/**
@ -253,43 +253,6 @@ class RuleRepository implements RuleRepositoryInterface
return $filtered;
}
/**
* @inheritDoc
*/
public function maxOrder(RuleGroup $ruleGroup): int
{
return (int)$ruleGroup->rules()->max('order');
}
/**
* @inheritDoc
*/
public function moveRule(Rule $rule, RuleGroup $ruleGroup, int $order): Rule
{
if ($rule->rule_group_id !== $ruleGroup->id) {
$rule->rule_group_id = $ruleGroup->id;
}
$rule->save();
$rule->refresh();
$this->setOrder($rule, $order);
return $rule;
}
/**
* @param RuleGroup $ruleGroup
*
* @return bool
*/
public function resetRuleOrder(RuleGroup $ruleGroup): bool
{
$groupRepository = app(RuleGroupRepositoryInterface::class);
$groupRepository->setUser($ruleGroup->user);
$groupRepository->resetRuleOrder($ruleGroup);
return true;
}
/**
* @inheritDoc
*/
@ -305,42 +268,6 @@ class RuleRepository implements RuleRepositoryInterface
return $search->take($limit)->get(['id', 'title', 'description']);
}
/**
* @inheritDoc
*/
public function setOrder(Rule $rule, int $newOrder): void
{
$oldOrder = (int)$rule->order;
$groupId = (int)$rule->rule_group_id;
$maxOrder = $this->maxOrder($rule->ruleGroup);
$newOrder = $newOrder > $maxOrder ? $maxOrder + 1 : $newOrder;
Log::debug(sprintf('New order will be %d', $newOrder));
if ($newOrder > $oldOrder) {
$this->user->rules()
->where('rules.rule_group_id', $groupId)
->where('rules.order', '<=', $newOrder)
->where('rules.order', '>', $oldOrder)
->where('rules.id', '!=', $rule->id)
->decrement('rules.order');
$rule->order = $newOrder;
Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder));
$rule->save();
return;
}
$this->user->rules()
->where('rules.rule_group_id', $groupId)
->where('rules.order', '>=', $newOrder)
->where('rules.order', '<', $oldOrder)
->where('rules.id', '!=', $rule->id)
->increment('rules.order');
$rule->order = $newOrder;
Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder));
$rule->save();
}
/**
* @param User $user
*/
@ -403,104 +330,6 @@ class RuleRepository implements RuleRepositoryInterface
return $rule;
}
/**
* @param Rule $rule
* @param array $values
*
* @return RuleAction
*/
public function storeAction(Rule $rule, array $values): RuleAction
{
$ruleAction = new RuleAction;
$ruleAction->rule()->associate($rule);
$ruleAction->order = $values['order'];
$ruleAction->active = $values['active'];
$ruleAction->stop_processing = $values['stop_processing'];
$ruleAction->action_type = $values['action'];
$ruleAction->action_value = $values['value'] ?? '';
$ruleAction->save();
return $ruleAction;
}
/**
* @param Rule $rule
* @param array $values
*
* @return RuleTrigger
*/
public function storeTrigger(Rule $rule, array $values): RuleTrigger
{
$ruleTrigger = new RuleTrigger;
$ruleTrigger->rule()->associate($rule);
$ruleTrigger->order = $values['order'];
$ruleTrigger->active = $values['active'];
$ruleTrigger->stop_processing = $values['stop_processing'];
$ruleTrigger->trigger_type = $values['action'];
$ruleTrigger->trigger_value = $values['value'] ?? '';
$ruleTrigger->save();
return $ruleTrigger;
}
/**
* @param Rule $rule
* @param array $data
*
* @return Rule
*/
public function update(Rule $rule, array $data): Rule
{
// update rule:
$fields = [
'title',
'description',
'strict',
'rule_group_id',
'active',
'stop_processing',
];
foreach ($fields as $field) {
if (array_key_exists($field, $data)) {
$rule->$field = $data[$field];
}
}
$rule->save();
$rule->refresh();
$group = $rule->ruleGroup;
// update the order:
$this->resetRuleOrder($group);
if (array_key_exists('order', $data)) {
$this->moveRule($rule, $group, (int)$data['order']);
}
// update the triggers:
if (array_key_exists('trigger', $data) && 'update-journal' === $data['trigger']) {
$this->setRuleTrigger('update-journal', $rule);
}
if (array_key_exists('trigger', $data) && 'store-journal' === $data['trigger']) {
$this->setRuleTrigger('store-journal', $rule);
}
if (array_key_exists('triggers', $data)) {
// delete triggers:
$rule->ruleTriggers()->where('trigger_type', '!=', 'user_action')->delete();
// recreate triggers:
$this->storeTriggers($rule, $data);
}
if (array_key_exists('actions', $data)) {
// delete triggers:
$rule->ruleActions()->delete();
// recreate actions:
$this->storeActions($rule, $data);
}
return $rule;
}
/**
* @param string $moment
* @param Rule $rule
@ -525,6 +354,64 @@ class RuleRepository implements RuleRepositoryInterface
$trigger->save();
}
/**
* @param RuleGroup $ruleGroup
*
* @return bool
*/
public function resetRuleOrder(RuleGroup $ruleGroup): bool
{
$groupRepository = app(RuleGroupRepositoryInterface::class);
$groupRepository->setUser($ruleGroup->user);
$groupRepository->resetRuleOrder($ruleGroup);
return true;
}
/**
* @inheritDoc
*/
public function setOrder(Rule $rule, int $newOrder): void
{
$oldOrder = (int) $rule->order;
$groupId = (int) $rule->rule_group_id;
$maxOrder = $this->maxOrder($rule->ruleGroup);
$newOrder = $newOrder > $maxOrder ? $maxOrder + 1 : $newOrder;
Log::debug(sprintf('New order will be %d', $newOrder));
if ($newOrder > $oldOrder) {
$this->user->rules()
->where('rules.rule_group_id', $groupId)
->where('rules.order', '<=', $newOrder)
->where('rules.order', '>', $oldOrder)
->where('rules.id', '!=', $rule->id)
->decrement('rules.order');
$rule->order = $newOrder;
Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder));
$rule->save();
return;
}
$this->user->rules()
->where('rules.rule_group_id', $groupId)
->where('rules.order', '>=', $newOrder)
->where('rules.order', '<', $oldOrder)
->where('rules.id', '!=', $rule->id)
->increment('rules.order');
$rule->order = $newOrder;
Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder));
$rule->save();
}
/**
* @inheritDoc
*/
public function maxOrder(RuleGroup $ruleGroup): int
{
return (int) $ruleGroup->rules()->max('order');
}
/**
* @param Rule $rule
* @param array $data
@ -553,6 +440,26 @@ class RuleRepository implements RuleRepositoryInterface
return true;
}
/**
* @param Rule $rule
* @param array $values
*
* @return RuleTrigger
*/
public function storeTrigger(Rule $rule, array $values): RuleTrigger
{
$ruleTrigger = new RuleTrigger;
$ruleTrigger->rule()->associate($rule);
$ruleTrigger->order = $values['order'];
$ruleTrigger->active = $values['active'];
$ruleTrigger->stop_processing = $values['stop_processing'];
$ruleTrigger->trigger_type = $values['action'];
$ruleTrigger->trigger_value = $values['value'] ?? '';
$ruleTrigger->save();
return $ruleTrigger;
}
/**
* @param Rule $rule
* @param array $data
@ -579,4 +486,97 @@ class RuleRepository implements RuleRepositoryInterface
return true;
}
/**
* @param Rule $rule
* @param array $values
*
* @return RuleAction
*/
public function storeAction(Rule $rule, array $values): RuleAction
{
$ruleAction = new RuleAction;
$ruleAction->rule()->associate($rule);
$ruleAction->order = $values['order'];
$ruleAction->active = $values['active'];
$ruleAction->stop_processing = $values['stop_processing'];
$ruleAction->action_type = $values['action'];
$ruleAction->action_value = $values['value'] ?? '';
$ruleAction->save();
return $ruleAction;
}
/**
* @param Rule $rule
* @param array $data
*
* @return Rule
*/
public function update(Rule $rule, array $data): Rule
{
// update rule:
$fields = [
'title',
'description',
'strict',
'rule_group_id',
'active',
'stop_processing',
];
foreach ($fields as $field) {
if (array_key_exists($field, $data)) {
$rule->$field = $data[$field];
}
}
$rule->save();
$rule->refresh();
$group = $rule->ruleGroup;
// update the order:
$this->resetRuleOrder($group);
if (array_key_exists('order', $data)) {
$this->moveRule($rule, $group, (int) $data['order']);
}
// update the triggers:
if (array_key_exists('trigger', $data) && 'update-journal' === $data['trigger']) {
$this->setRuleTrigger('update-journal', $rule);
}
if (array_key_exists('trigger', $data) && 'store-journal' === $data['trigger']) {
$this->setRuleTrigger('store-journal', $rule);
}
if (array_key_exists('triggers', $data)) {
// delete triggers:
$rule->ruleTriggers()->where('trigger_type', '!=', 'user_action')->delete();
// recreate triggers:
$this->storeTriggers($rule, $data);
}
if (array_key_exists('actions', $data)) {
// delete triggers:
$rule->ruleActions()->delete();
// recreate actions:
$this->storeActions($rule, $data);
}
return $rule;
}
/**
* @inheritDoc
*/
public function moveRule(Rule $rule, RuleGroup $ruleGroup, int $order): Rule
{
if ($rule->rule_group_id !== $ruleGroup->id) {
$rule->rule_group_id = $ruleGroup->id;
}
$rule->save();
$rule->refresh();
$this->setOrder($rule, $order);
return $rule;
}
}

View File

@ -99,6 +99,108 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return true;
}
/**
* @return bool
*/
public function resetOrder(): bool
{
$set = $this->user
->ruleGroups()
->whereNull('deleted_at')
->orderBy('order', 'ASC')
->orderBy('title', 'DESC')
->get();
$count = 1;
/** @var RuleGroup $entry */
foreach ($set as $entry) {
if ($entry->order !== $count) {
$entry->order = $count;
$entry->save();
}
// also update rules in group.
$this->resetRuleOrder($entry);
++$count;
}
return true;
}
/**
* @param RuleGroup $ruleGroup
*
* @return bool
*/
public function resetRuleOrder(RuleGroup $ruleGroup): bool
{
$set = $ruleGroup->rules()
->orderBy('order', 'ASC')
->orderBy('title', 'DESC')
->orderBy('updated_at', 'DESC')
->get(['rules.*']);
$count = 1;
/** @var Rule $entry */
foreach ($set as $entry) {
if ((int) $entry->order !== $count) {
Log::debug(sprintf('Rule #%d was on spot %d but must be on spot %d', $entry->id, $entry->order, $count));
$entry->order = $count;
$entry->save();
}
$this->resetRuleActionOrder($entry);
$this->resetRuleTriggerOrder($entry);
++$count;
}
return true;
}
/**
* @param Rule $rule
*/
private function resetRuleActionOrder(Rule $rule): void
{
$actions = $rule->ruleActions()
->orderBy('order', 'ASC')
->orderBy('active', 'DESC')
->orderBy('action_type', 'ASC')
->get();
$index = 1;
/** @var RuleAction $action */
foreach ($actions as $action) {
if ((int) $action->order !== $index) {
$action->order = $index;
$action->save();
Log::debug(sprintf('Rule action #%d was on spot %d but must be on spot %d', $action->id, $action->order, $index));
}
$index++;
}
}
/**
* @param Rule $rule
*/
private function resetRuleTriggerOrder(Rule $rule): void
{
$triggers = $rule->ruleTriggers()
->orderBy('order', 'ASC')
->orderBy('active', 'DESC')
->orderBy('trigger_type', 'ASC')
->get();
$index = 1;
/** @var RuleTrigger $trigger */
foreach ($triggers as $trigger) {
$order = (int) $trigger->order;
if ($order !== $index) {
$trigger->order = $index;
$trigger->save();
Log::debug(sprintf('Rule trigger #%d was on spot %d but must be on spot %d', $trigger->id, $order, $index));
}
$index++;
}
}
/**
* @inheritDoc
*/
@ -112,6 +214,14 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
}
}
/**
* @return Collection
*/
public function get(): Collection
{
return $this->user->ruleGroups()->orderBy('order', 'ASC')->get();
}
/**
* @param int $ruleGroupId
*
@ -132,14 +242,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return $this->user->ruleGroups()->where('title', $title)->first();
}
/**
* @return Collection
*/
public function get(): Collection
{
return $this->user->ruleGroups()->orderBy('order', 'ASC')->get();
}
/**
* @return Collection
*/
@ -249,7 +351,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
{
$entry = $this->user->ruleGroups()->max('order');
return (int)$entry;
return (int) $entry;
}
/**
@ -321,64 +423,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
*/
public function maxOrder(): int
{
return (int)$this->user->ruleGroups()->where('active', true)->max('order');
}
/**
* @return bool
*/
public function resetOrder(): bool
{
$set = $this->user
->ruleGroups()
->whereNull('deleted_at')
->orderBy('order', 'ASC')
->orderBy('title', 'DESC')
->get();
$count = 1;
/** @var RuleGroup $entry */
foreach ($set as $entry) {
if ($entry->order !== $count) {
$entry->order = $count;
$entry->save();
}
// also update rules in group.
$this->resetRuleOrder($entry);
++$count;
}
return true;
}
/**
* @param RuleGroup $ruleGroup
*
* @return bool
*/
public function resetRuleOrder(RuleGroup $ruleGroup): bool
{
$set = $ruleGroup->rules()
->orderBy('order', 'ASC')
->orderBy('title', 'DESC')
->orderBy('updated_at', 'DESC')
->get(['rules.*']);
$count = 1;
/** @var Rule $entry */
foreach ($set as $entry) {
if ((int)$entry->order !== $count) {
Log::debug(sprintf('Rule #%d was on spot %d but must be on spot %d', $entry->id, $entry->order, $count));
$entry->order = $count;
$entry->save();
}
$this->resetRuleActionOrder($entry);
$this->resetRuleTriggerOrder($entry);
++$count;
}
return true;
return (int) $this->user->ruleGroups()->where('active', true)->max('order');
}
/**
@ -396,32 +441,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return $search->take($limit)->get(['id', 'title', 'description']);
}
/**
* @inheritDoc
*/
public function setOrder(RuleGroup $ruleGroup, int $newOrder): void
{
$oldOrder = (int)$ruleGroup->order;
if ($newOrder > $oldOrder) {
$this->user->ruleGroups()->where('rule_groups.order', '<=', $newOrder)->where('rule_groups.order', '>', $oldOrder)
->where('rule_groups.id', '!=', $ruleGroup->id)
->decrement('order');
$ruleGroup->order = $newOrder;
Log::debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
$ruleGroup->save();
return;
}
$this->user->ruleGroups()->where('rule_groups.order', '>=', $newOrder)->where('rule_groups.order', '<', $oldOrder)
->where('rule_groups.id', '!=', $ruleGroup->id)
->increment('order');
$ruleGroup->order = $newOrder;
Log::debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
$ruleGroup->save();
}
/**
* @param User $user
*/
@ -455,6 +474,32 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return $newRuleGroup;
}
/**
* @inheritDoc
*/
public function setOrder(RuleGroup $ruleGroup, int $newOrder): void
{
$oldOrder = (int) $ruleGroup->order;
if ($newOrder > $oldOrder) {
$this->user->ruleGroups()->where('rule_groups.order', '<=', $newOrder)->where('rule_groups.order', '>', $oldOrder)
->where('rule_groups.id', '!=', $ruleGroup->id)
->decrement('order');
$ruleGroup->order = $newOrder;
Log::debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
$ruleGroup->save();
return;
}
$this->user->ruleGroups()->where('rule_groups.order', '>=', $newOrder)->where('rule_groups.order', '<', $oldOrder)
->where('rule_groups.id', '!=', $ruleGroup->id)
->increment('order');
$ruleGroup->order = $newOrder;
Log::debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
$ruleGroup->save();
}
/**
* @param RuleGroup $ruleGroup
* @param array $data
@ -476,56 +521,11 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
// order
if (array_key_exists('order', $data) && $ruleGroup->order !== $data['order']) {
$this->resetOrder();
$this->setOrder($ruleGroup, (int)$data['order']);
$this->setOrder($ruleGroup, (int) $data['order']);
}
$ruleGroup->save();
return $ruleGroup;
}
/**
* @param Rule $rule
*/
private function resetRuleActionOrder(Rule $rule): void
{
$actions = $rule->ruleActions()
->orderBy('order', 'ASC')
->orderBy('active', 'DESC')
->orderBy('action_type', 'ASC')
->get();
$index = 1;
/** @var RuleAction $action */
foreach ($actions as $action) {
if ((int)$action->order !== $index) {
$action->order = $index;
$action->save();
Log::debug(sprintf('Rule action #%d was on spot %d but must be on spot %d', $action->id, $action->order, $index));
}
$index++;
}
}
/**
* @param Rule $rule
*/
private function resetRuleTriggerOrder(Rule $rule): void
{
$triggers = $rule->ruleTriggers()
->orderBy('order', 'ASC')
->orderBy('active', 'DESC')
->orderBy('trigger_type', 'ASC')
->get();
$index = 1;
/** @var RuleTrigger $trigger */
foreach ($triggers as $trigger) {
$order = (int)$trigger->order;
if ($order !== $index) {
$trigger->order = $index;
$trigger->save();
Log::debug(sprintf('Rule trigger #%d was on spot %d but must be on spot %d', $trigger->id, $order, $index));
}
$index++;
}
}
}

View File

@ -70,7 +70,7 @@ class OperationsRepository implements OperationsRepositoryInterface
$array = [];
$listedJournals = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'tags' => [],
'currency_id' => $currencyId,
@ -82,9 +82,9 @@ class OperationsRepository implements OperationsRepositoryInterface
// may have multiple tags:
foreach ($journal['tags'] as $tag) {
$tagId = (int)$tag['id'];
$tagName = (string)$tag['name'];
$journalId = (int)$journal['transaction_journal_id'];
$tagId = (int) $tag['id'];
$tagName = (string) $tag['name'];
$journalId = (int) $journal['transaction_journal_id'];
if (in_array($journalId, $listedJournals, true)) {
continue;
@ -114,6 +114,16 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
/**
* @return Collection
*/
private function getTags(): Collection
{
$repository = app(TagRepositoryInterface::class);
return $repository->get();
}
/**
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array
@ -146,7 +156,7 @@ class OperationsRepository implements OperationsRepositoryInterface
$listedJournals = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$array[$currencyId] = $array[$currencyId] ?? [
'tags' => [],
'currency_id' => $currencyId,
@ -158,9 +168,9 @@ class OperationsRepository implements OperationsRepositoryInterface
// may have multiple tags:
foreach ($journal['tags'] as $tag) {
$tagId = (int)$tag['id'];
$tagName = (string)$tag['name'];
$journalId = (int)$journal['transaction_journal_id'];
$tagId = (int) $tag['id'];
$tagName = (string) $tag['name'];
$journalId = (int) $journal['transaction_journal_id'];
if (in_array($journalId, $listedJournals, true)) {
continue;
@ -172,7 +182,7 @@ class OperationsRepository implements OperationsRepositoryInterface
'name' => $tagName,
'transaction_journals' => [],
];
$journalId = (int)$journal['transaction_journal_id'];
$journalId = (int) $journal['transaction_journal_id'];
$array[$currencyId]['tags'][$tagId]['transaction_journals'][$journalId] = [
'amount' => app('steam')->positive($journal['amount']),
'date' => $journal['date'],
@ -229,14 +239,4 @@ class OperationsRepository implements OperationsRepositoryInterface
{
throw new FireflyException(sprintf('%s is not yet implemented.', __METHOD__));
}
/**
* @return Collection
*/
private function getTags(): Collection
{
$repository = app(TagRepositoryInterface::class);
return $repository->get();
}
}

View File

@ -81,6 +81,14 @@ class TagRepository implements TagRepositoryInterface
}
}
/**
* @return Collection
*/
public function get(): Collection
{
return $this->user->tags()->orderBy('tag', 'ASC')->get();
}
/**
* @param Tag $tag
* @param Carbon $start
@ -134,14 +142,6 @@ class TagRepository implements TagRepositoryInterface
return null;
}
/**
* @return Collection
*/
public function get(): Collection
{
return $this->user->tags()->orderBy('tag', 'ASC')->get();
}
/**
* @inheritDoc
*/
@ -162,14 +162,6 @@ class TagRepository implements TagRepositoryInterface
);
}
/**
* @inheritDoc
*/
public function getLocation(Tag $tag): ?Location
{
return $tag->locations()->first();
}
/**
* @param int|null $year
*
@ -338,7 +330,7 @@ class TagRepository implements TagRepositoryInterface
/** @var array $journal */
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
$currencyId = (int) $journal['currency_id'];
$sums[$currencyId] = $sums[$currencyId] ?? [
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@ -352,7 +344,7 @@ class TagRepository implements TagRepositoryInterface
];
// add amount to correct type:
$amount = app('steam')->positive((string)$journal['amount']);
$amount = app('steam')->positive((string) $journal['amount']);
$type = $journal['transaction_type_type'];
if (TransactionType::WITHDRAWAL === $type) {
$amount = bcmul($amount, '-1');
@ -373,7 +365,7 @@ class TagRepository implements TagRepositoryInterface
TransactionType::OPENING_BALANCE => '0',
];
// add foreign amount to correct type:
$amount = app('steam')->positive((string)$journal['foreign_amount']);
$amount = app('steam')->positive((string) $journal['foreign_amount']);
$type = $journal['transaction_type_type'];
if (TransactionType::WITHDRAWAL === $type) {
$amount = bcmul($amount, '-1');
@ -458,4 +450,12 @@ class TagRepository implements TagRepositoryInterface
return $tag;
}
/**
* @inheritDoc
*/
public function getLocation(Tag $tag): ?Location
{
return $tag->locations()->first();
}
}

View File

@ -56,6 +56,18 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
{
private User $user;
/**
* @inheritDoc
*/
public function countAttachments(int $journalId): int
{
/** @var TransactionJournal $journal */
$journal = $this->user->transactionJournals()->find($journalId);
return $journal->attachments()->count();
}
/**
* @param TransactionGroup $group
*/
@ -80,6 +92,56 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $result;
}
/**
* @param TransactionJournal $journal
*
* @return array
*/
private function expandJournal(TransactionJournal $journal): array
{
$array = $journal->toArray();
$array['transactions'] = [];
$array['meta'] = $journal->transactionJournalMeta->toArray();
$array['tags'] = $journal->tags->toArray();
$array['categories'] = $journal->categories->toArray();
$array['budgets'] = $journal->budgets->toArray();
$array['notes'] = $journal->notes->toArray();
$array['locations'] = [];
$array['attachments'] = $journal->attachments->toArray();
$array['links'] = [];
$array['piggy_bank_events'] = $journal->piggyBankEvents->toArray();
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
$array['transactions'][] = $this->expandTransaction($transaction);
}
return $array;
}
/**
* @param Transaction $transaction
*
* @return array
*/
private function expandTransaction(Transaction $transaction): array
{
$array = $transaction->toArray();
$array['account'] = $transaction->account->toArray();
$array['budgets'] = [];
$array['categories'] = [];
foreach ($transaction->categories as $category) {
$array['categories'][] = $category->toArray();
}
foreach ($transaction->budgets as $budget) {
$array['budgets'][] = $budget->toArray();
}
return $array;
}
/**
* Find a transaction group by its ID.
*
@ -112,11 +174,11 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
$result = [];
/** @var Attachment $attachment */
foreach ($set as $attachment) {
$journalId = (int)$attachment->attachable_id;
$journalId = (int) $attachment->attachable_id;
$result[$journalId] = $result[$journalId] ?? [];
$current = $attachment->toArray();
$current['file_exists'] = true;
$current['notes'] = $repository->getNoteText($attachment);
$current['notes'] = $repository->getNoteText($attachment);
$current['journal_title'] = $attachment->attachable->description; // @phpstan-ignore-line
$result[$journalId][] = $current;
@ -159,7 +221,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
'link' => $entry->outward,
'group' => $entry->destination->transaction_group_id,
'description' => $entry->destination->description,
'editable' => 1===$entry->editable,
'editable' => 1 === $entry->editable,
'amount' => $amount,
'foreign_amount' => $foreignAmount,
];
@ -172,7 +234,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
'link' => $entry->inward,
'group' => $entry->source->transaction_group_id,
'description' => $entry->source->description,
'editable' => 1===$entry->editable,
'editable' => 1 === $entry->editable,
'amount' => $amount,
'foreign_amount' => $foreignAmount,
];
@ -182,6 +244,56 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $return;
}
/**
* @param TransactionJournal $journal
*
* @return string
*/
private function getFormattedAmount(TransactionJournal $journal): string
{
/** @var Transaction $transaction */
$transaction = $journal->transactions->first();
$currency = $transaction->transactionCurrency;
$type = $journal->transactionType->type;
$amount = app('steam')->positive($transaction->amount);
$return = '';
if (TransactionType::WITHDRAWAL === $type) {
$return = app('amount')->formatAnything($currency, app('steam')->negative($amount));
}
if (TransactionType::WITHDRAWAL !== $type) {
$return = app('amount')->formatAnything($currency, $amount);
}
return $return;
}
/**
* @param TransactionJournal $journal
*
* @return string
*/
private function getFormattedForeignAmount(TransactionJournal $journal): string
{
/** @var Transaction $transaction */
$transaction = $journal->transactions->first();
if (null === $transaction->foreign_amount) {
return '';
}
$currency = $transaction->foreignCurrency;
$type = $journal->transactionType->type;
$amount = app('steam')->positive($transaction->foreign_amount);
$return = '';
if (TransactionType::WITHDRAWAL === $type) {
$return = app('amount')->formatAnything($currency, app('steam')->negative($amount));
}
if (TransactionType::WITHDRAWAL !== $type) {
$return = app('amount')->formatAnything($currency, $amount);
}
return $return;
}
/**
* @inheritDoc
*/
@ -299,7 +411,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
$currencyCode = app('preferences')->getForUser($this->user, 'currencyPreference', 'EUR')->data;
$currency = TransactionCurrency::where('code', $currencyCode)->first();
}
$journalId = (int)$row->transaction_journal_id;
$journalId = (int) $row->transaction_journal_id;
$return[$journalId] = $return[$journalId] ?? [];
$return[$journalId][] = [
@ -390,116 +502,4 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $service->update($transactionGroup, $data);
}
/**
* @param TransactionJournal $journal
*
* @return array
*/
private function expandJournal(TransactionJournal $journal): array
{
$array = $journal->toArray();
$array['transactions'] = [];
$array['meta'] = $journal->transactionJournalMeta->toArray();
$array['tags'] = $journal->tags->toArray();
$array['categories'] = $journal->categories->toArray();
$array['budgets'] = $journal->budgets->toArray();
$array['notes'] = $journal->notes->toArray();
$array['locations'] = [];
$array['attachments'] = $journal->attachments->toArray();
$array['links'] = [];
$array['piggy_bank_events'] = $journal->piggyBankEvents->toArray();
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
$array['transactions'][] = $this->expandTransaction($transaction);
}
return $array;
}
/**
* @param Transaction $transaction
*
* @return array
*/
private function expandTransaction(Transaction $transaction): array
{
$array = $transaction->toArray();
$array['account'] = $transaction->account->toArray();
$array['budgets'] = [];
$array['categories'] = [];
foreach ($transaction->categories as $category) {
$array['categories'][] = $category->toArray();
}
foreach ($transaction->budgets as $budget) {
$array['budgets'][] = $budget->toArray();
}
return $array;
}
/**
* @param TransactionJournal $journal
*
* @return string
*/
private function getFormattedAmount(TransactionJournal $journal): string
{
/** @var Transaction $transaction */
$transaction = $journal->transactions->first();
$currency = $transaction->transactionCurrency;
$type = $journal->transactionType->type;
$amount = app('steam')->positive($transaction->amount);
$return = '';
if (TransactionType::WITHDRAWAL === $type) {
$return = app('amount')->formatAnything($currency, app('steam')->negative($amount));
}
if (TransactionType::WITHDRAWAL !== $type) {
$return = app('amount')->formatAnything($currency, $amount);
}
return $return;
}
/**
* @param TransactionJournal $journal
*
* @return string
*/
private function getFormattedForeignAmount(TransactionJournal $journal): string
{
/** @var Transaction $transaction */
$transaction = $journal->transactions->first();
if (null === $transaction->foreign_amount) {
return '';
}
$currency = $transaction->foreignCurrency;
$type = $journal->transactionType->type;
$amount = app('steam')->positive($transaction->foreign_amount);
$return = '';
if (TransactionType::WITHDRAWAL === $type) {
$return = app('amount')->formatAnything($currency, app('steam')->negative($amount));
}
if (TransactionType::WITHDRAWAL !== $type) {
$return = app('amount')->formatAnything($currency, $amount);
}
return $return;
}
/**
* @inheritDoc
*/
public function countAttachments(int $journalId): int
{
/** @var TransactionJournal $journal */
$journal = $this->user->transactionJournals()->find($journalId);
return $journal->attachments()->count();
}
}

View File

@ -36,6 +36,13 @@ use Illuminate\Support\Collection;
*/
interface TransactionGroupRepositoryInterface
{
/**
* @param int $journalId
*
* @return int
*/
public function countAttachments(int $journalId): int;
/**
* @param TransactionGroup $group
*/
@ -86,13 +93,6 @@ interface TransactionGroupRepositoryInterface
*/
public function getLocation(int $journalId): ?Location;
/**
* @param int $journalId
*
* @return int
*/
public function countAttachments(int $journalId): int;
/**
* Return object with all found meta field things as Carbon objects.
*

View File

@ -33,18 +33,6 @@ use Log;
class TransactionTypeRepository implements TransactionTypeRepositoryInterface
{
/**
* @param string $type
*
* @return TransactionType|null
*/
public function findByType(string $type): ?TransactionType
{
$search = ucfirst($type);
return TransactionType::whereType($search)->first();
}
/**
* @param TransactionType|null $type
* @param string|null $typeString
@ -69,6 +57,18 @@ class TransactionTypeRepository implements TransactionTypeRepositoryInterface
return $search;
}
/**
* @param string $type
*
* @return TransactionType|null
*/
public function findByType(string $type): ?TransactionType
{
$search = ucfirst($type);
return TransactionType::whereType($search)->first();
}
/**
* @param string $query
* @param int $limit

View File

@ -39,39 +39,6 @@ use Str;
*/
class UserRepository implements UserRepositoryInterface
{
/**
* @return Collection
*/
public function all(): Collection
{
return User::orderBy('id', 'DESC')->get(['users.*']);
}
/**
* @param User $user
* @param string $role
*
* @return bool
*/
public function attachRole(User $user, string $role): bool
{
$roleObject = Role::where('name', $role)->first();
if (null === $roleObject) {
Log::error(sprintf('Could not find role "%s" in attachRole()', $role));
return false;
}
try {
$user->roles()->attach($roleObject);
} catch (QueryException $e) {
// don't care
Log::error(sprintf('Query exception when giving user a role: %s', $e->getMessage()));
}
return true;
}
/**
* This updates the users email address and records some things so it can be confirmed or undone later.
* The user is blocked until the change is confirmed.
@ -144,6 +111,14 @@ class UserRepository implements UserRepositoryInterface
return $this->all()->count();
}
/**
* @return Collection
*/
public function all(): Collection
{
return User::orderBy('id', 'DESC')->get(['users.*']);
}
/**
* @param string $name
* @param string $displayName
@ -173,6 +148,22 @@ class UserRepository implements UserRepositoryInterface
return true;
}
/**
* @inheritDoc
*/
public function deleteEmptyGroups(): void
{
$groups = UserGroup::get();
/** @var UserGroup $group */
foreach ($groups as $group) {
$count = $group->groupMemberships()->count();
if (0 === $count) {
Log::info(sprintf('Deleted empty group #%d ("%s")', $group->id, $group->title));
$group->delete();
}
}
}
/**
* @param int $userId
*
@ -203,16 +194,6 @@ class UserRepository implements UserRepositoryInterface
return User::orderBy('id', 'ASC')->first();
}
/**
* @param string $role
*
* @return Role|null
*/
public function getRole(string $role): ?Role
{
return Role::where('name', $role)->first();
}
/**
* @param User $user
*
@ -243,7 +224,7 @@ class UserRepository implements UserRepositoryInterface
// two factor:
$return['has_2fa'] = $user->mfa_secret !== null;
$return['is_admin'] = $this->hasRole($user, 'owner');
$return['blocked'] = 1 === (int)$user->blocked;
$return['blocked'] = 1 === (int) $user->blocked;
$return['blocked_code'] = $user->blocked_code;
$return['accounts'] = $user->accounts()->count();
$return['journals'] = $user->transactionJournals()->count();
@ -284,21 +265,6 @@ class UserRepository implements UserRepositoryInterface
return false;
}
/**
* Remove any role the user has.
*
* @param User $user
* @param string $role
*/
public function removeRole(User $user, string $role): void
{
$roleObj = $this->getRole($role);
if (null === $roleObj) {
return;
}
$user->roles()->detach($roleObj->id);
}
/**
* Set MFA code.
*
@ -334,6 +300,31 @@ class UserRepository implements UserRepositoryInterface
return $user;
}
/**
* @param User $user
* @param string $role
*
* @return bool
*/
public function attachRole(User $user, string $role): bool
{
$roleObject = Role::where('name', $role)->first();
if (null === $roleObject) {
Log::error(sprintf('Could not find role "%s" in attachRole()', $role));
return false;
}
try {
$user->roles()->attach($roleObject);
} catch (QueryException $e) {
// don't care
Log::error(sprintf('Query exception when giving user a role: %s', $e->getMessage()));
}
return true;
}
/**
* @param User $user
*/
@ -402,18 +393,27 @@ class UserRepository implements UserRepositoryInterface
}
/**
* @inheritDoc
* Remove any role the user has.
*
* @param User $user
* @param string $role
*/
public function deleteEmptyGroups(): void
public function removeRole(User $user, string $role): void
{
$groups = UserGroup::get();
/** @var UserGroup $group */
foreach ($groups as $group) {
$count = $group->groupMemberships()->count();
if (0 === $count) {
Log::info(sprintf('Deleted empty group #%d ("%s")', $group->id, $group->title));
$group->delete();
}
$roleObj = $this->getRole($role);
if (null === $roleObj) {
return;
}
$user->roles()->detach($roleObj->id);
}
/**
* @param string $role
*
* @return Role|null
*/
public function getRole(string $role): ?Role
{
return Role::where('name', $role)->first();
}
}

View File

@ -39,11 +39,6 @@ interface UserRepositoryInterface
*/
public function all(): Collection;
/**
*
*/
public function deleteEmptyGroups(): void;
/**
* Gives a user a role.
*
@ -100,6 +95,11 @@ interface UserRepositoryInterface
*/
public function createRole(string $name, string $displayName, string $description): Role;
/**
*
*/
public function deleteEmptyGroups(): void;
/**
* @param User $user
*

View File

@ -58,7 +58,7 @@ class BelongsUser implements Rule
*/
public function message(): string
{
return (string)trans('validation.belongs_user');
return (string) trans('validation.belongs_user');
}
/**
@ -77,19 +77,19 @@ class BelongsUser implements Rule
if (!auth()->check()) {
return true;
}
$attribute = (string)$attribute;
$attribute = (string) $attribute;
Log::debug(sprintf('Going to validate %s', $attribute));
return match ($attribute) {
'piggy_bank_id' => $this->validatePiggyBankId((int)$value),
'piggy_bank_id' => $this->validatePiggyBankId((int) $value),
'piggy_bank_name' => $this->validatePiggyBankName($value),
'bill_id' => $this->validateBillId((int)$value),
'transaction_journal_id' => $this->validateJournalId((int)$value),
'bill_id' => $this->validateBillId((int) $value),
'transaction_journal_id' => $this->validateJournalId((int) $value),
'bill_name' => $this->validateBillName($value),
'budget_id' => $this->validateBudgetId((int)$value),
'category_id' => $this->validateCategoryId((int)$value),
'budget_id' => $this->validateBudgetId((int) $value),
'category_id' => $this->validateCategoryId((int) $value),
'budget_name' => $this->validateBudgetName($value),
'source_id', 'destination_id' => $this->validateAccountId((int)$value),
'source_id', 'destination_id' => $this->validateAccountId((int) $value),
default => throw new FireflyException(sprintf('Rule BelongUser cannot handle "%s"', $attribute)),
};
}
@ -161,7 +161,7 @@ class BelongsUser implements Rule
}
$count = 0;
foreach ($objects as $object) {
$objectValue = trim((string)$object->$field);
$objectValue = trim((string) $object->$field);
Log::debug(sprintf('Comparing object "%s" with value "%s"', $objectValue, $value));
if ($objectValue === $value) {
$count++;

View File

@ -53,7 +53,7 @@ class IsAssetAccountId implements Rule
*/
public function passes($attribute, $value): bool
{
$accountId = (int)$value;
$accountId = (int) $value;
$account = Account::with('accountType')->find($accountId);
if (null === $account) {
return false;

View File

@ -39,7 +39,7 @@ class IsBoolean implements Rule
*/
public function message(): string
{
return (string)trans('validation.boolean');
return (string) trans('validation.boolean');
}
/**

View File

@ -44,7 +44,7 @@ class IsDateOrTime implements Rule
*/
public function message()
{
return (string)trans('validation.date_or_time');
return (string) trans('validation.date_or_time');
}
/**
@ -57,7 +57,7 @@ class IsDateOrTime implements Rule
*/
public function passes($attribute, $value): bool
{
$value = (string)$value;
$value = (string) $value;
if ('' === $value) {
return false;
}

View File

@ -41,7 +41,7 @@ class IsTransferAccount implements Rule
*/
public function message(): string
{
return (string)trans('validation.not_transfer_account');
return (string) trans('validation.not_transfer_account');
}
/**
@ -60,15 +60,15 @@ class IsTransferAccount implements Rule
$validator->setTransactionType(TransactionType::TRANSFER);
$validator->setUser(auth()->user());
$validAccount = $validator->validateSource(['name' => (string)$value,]);
$validAccount = $validator->validateSource(['name' => (string) $value,]);
if (true === $validAccount) {
Log::debug('Found account based on name. Return true.');
// found by name, use repos to return.
return true;
}
$validAccount = $validator->validateSource(['id' => (int)$value,]);
Log::debug(sprintf('Search by id (%d), result is %s.', (int)$value, var_export($validAccount, true)));
$validAccount = $validator->validateSource(['id' => (int) $value,]);
Log::debug(sprintf('Search by id (%d), result is %s.', (int) $value, var_export($validAccount, true)));
return false !== $validAccount;
}

View File

@ -85,7 +85,7 @@ class IsValidAttachmentModel implements Rule
*/
public function message(): string
{
return (string)trans('validation.model_id_invalid');
return (string) trans('validation.model_id_invalid');
}
/**
@ -118,7 +118,7 @@ class IsValidAttachmentModel implements Rule
}
$method = $methods[$this->model];
return $this->$method((int)$value);
return $this->$method((int) $value);
}
/**
@ -229,6 +229,6 @@ class IsValidAttachmentModel implements Rule
$repository = app(JournalAPIRepositoryInterface::class);
$repository->setUser(auth()->user());
return null !== $repository->findTransaction((int)$value);
return null !== $repository->findTransaction((int) $value);
}
}

View File

@ -42,7 +42,7 @@ class IsValidBulkClause implements Rule
public function __construct(string $type)
{
$this->rules = config(sprintf('bulk.%s', $type));
$this->error = (string)trans('firefly.belongs_user');
$this->error = (string) trans('firefly.belongs_user');
}
/**
@ -61,7 +61,7 @@ class IsValidBulkClause implements Rule
*/
public function passes($attribute, $value): bool
{
$result = $this->basicValidation((string)$value);
$result = $this->basicValidation((string) $value);
if (false === $result) {
return false;
}
@ -81,14 +81,14 @@ class IsValidBulkClause implements Rule
try {
$array = json_decode($value, true, 8, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
$this->error = (string)trans('validation.json');
$this->error = (string) trans('validation.json');
return false;
}
$clauses = ['where', 'update'];
foreach ($clauses as $clause) {
if (!array_key_exists($clause, $array)) {
$this->error = (string)trans(sprintf('validation.missing_%s', $clause));
$this->error = (string) trans(sprintf('validation.missing_%s', $clause));
return false;
}
@ -98,7 +98,7 @@ class IsValidBulkClause implements Rule
*/
foreach ($array[$clause] as $arrayKey => $arrayValue) {
if (!array_key_exists($arrayKey, $this->rules[$clause])) {
$this->error = (string)trans(sprintf('validation.invalid_%s_key', $clause));
$this->error = (string) trans(sprintf('validation.invalid_%s_key', $clause));
return false;
}

View File

@ -38,7 +38,7 @@ class LessThanPiggyTarget implements Rule
*/
public function message(): string
{
return (string)trans('validation.current_target_amount');
return (string) trans('validation.current_target_amount');
}
/**

View File

@ -72,7 +72,7 @@ class UniqueAccountNumber implements Rule
*/
public function message(): string
{
return (string)trans('validation.unique_account_number_for_user');
return (string) trans('validation.unique_account_number_for_user');
}
/**

View File

@ -69,7 +69,7 @@ class UniqueIban implements Rule
*/
public function message(): string
{
return (string)trans('validation.unique_iban_for_user');
return (string) trans('validation.unique_iban_for_user');
}
/**

View File

@ -42,7 +42,7 @@ class ValidJournals implements Rule
*/
public function message(): string
{
return (string)trans('validation.invalid_selection');
return (string) trans('validation.invalid_selection');
}
/**

View File

@ -40,7 +40,7 @@ class ValidRecurrenceRepetitionType implements Rule
*/
public function message(): string
{
return (string)trans('validation.valid_recurrence_rep_type');
return (string) trans('validation.valid_recurrence_rep_type');
}
/**
@ -54,7 +54,7 @@ class ValidRecurrenceRepetitionType implements Rule
*/
public function passes($attribute, $value): bool
{
$value = (string)$value;
$value = (string) $value;
if ('daily' === $value) {
return true;
}

View File

@ -43,7 +43,7 @@ class ValidRecurrenceRepetitionValue implements Rule
*/
public function message(): string
{
return (string)trans('validation.valid_recurrence_rep_type');
return (string) trans('validation.valid_recurrence_rep_type');
}
/**
@ -57,7 +57,7 @@ class ValidRecurrenceRepetitionValue implements Rule
*/
public function passes($attribute, $value): bool
{
$value = (string)$value;
$value = (string) $value;
if ('daily' === $value) {
return true;
@ -93,7 +93,7 @@ class ValidRecurrenceRepetitionValue implements Rule
*/
private function validateMonthly(string $value): bool
{
$dayOfMonth = (int)substr($value, 8);
$dayOfMonth = (int) substr($value, 8);
return $dayOfMonth > 0 && $dayOfMonth < 32;
}
@ -110,8 +110,8 @@ class ValidRecurrenceRepetitionValue implements Rule
if (2 !== count($parameters)) {
return false;
}
$nthDay = (int)($parameters[0] ?? 0.0);
$dayOfWeek = (int)($parameters[1] ?? 0.0);
$nthDay = (int) ($parameters[0] ?? 0.0);
$dayOfWeek = (int) ($parameters[1] ?? 0.0);
if ($nthDay < 1 || $nthDay > 5) {
return false;
}
@ -126,7 +126,7 @@ class ValidRecurrenceRepetitionValue implements Rule
*/
private function validateWeekly(string $value): bool
{
$dayOfWeek = (int)substr($value, 7);
$dayOfWeek = (int) substr($value, 7);
return $dayOfWeek > 0 && $dayOfWeek < 8;
}

View File

@ -46,7 +46,7 @@ class UpdateRequest implements UpdateRequestInterface
Log::debug(sprintf('Now in getUpdateInformation(%s)', $channel));
$information = [
'level' => 'error',
'message' => (string)trans('firefly.unknown_error'),
'message' => (string) trans('firefly.unknown_error'),
];
// try get array from update server:
@ -76,7 +76,7 @@ class UpdateRequest implements UpdateRequestInterface
'version' => config('firefly.version'),
'date' => Carbon::today()->startOfDay(),
'level' => 'error',
'message' => (string)trans('firefly.unknown_error'),
'message' => (string) trans('firefly.unknown_error'),
];
$uri = config('firefly.update_endpoint');
@ -101,12 +101,12 @@ class UpdateRequest implements UpdateRequestInterface
if (200 !== $res->getStatusCode()) {
Log::error(sprintf('Response status from server is %d.', $res->getStatusCode()));
Log::error((string)$res->getBody());
Log::error((string) $res->getBody());
$return['message'] = sprintf('Error: %d', $res->getStatusCode());
return $return;
}
$body = (string)$res->getBody();
$body = (string) $res->getBody();
try {
$json = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
@ -144,7 +144,7 @@ class UpdateRequest implements UpdateRequestInterface
Log::debug('Now in parseResult()', $information);
$return = [
'level' => 'error',
'message' => (string)trans('firefly.unknown_error'),
'message' => (string) trans('firefly.unknown_error'),
];
$current = config('firefly.version');
$latest = $information['version'];
@ -155,7 +155,7 @@ class UpdateRequest implements UpdateRequestInterface
// -1: you're running a newer version:
if (-1 === $compare) {
$return['level'] = 'info';
$return['message'] = (string)trans('firefly.update_newer_version_alert', ['your_version' => $current, 'new_version' => $latest]);
$return['message'] = (string) trans('firefly.update_newer_version_alert', ['your_version' => $current, 'new_version' => $latest]);
Log::debug('User is running a newer version', $return);
return $return;
@ -163,7 +163,7 @@ class UpdateRequest implements UpdateRequestInterface
// running the current version:
if (0 === $compare) {
$return['level'] = 'info';
$return['message'] = (string)trans('firefly.update_current_version_alert', ['version' => $current]);
$return['message'] = (string) trans('firefly.update_current_version_alert', ['version' => $current]);
Log::debug('User is the current version.', $return);
return $return;
@ -177,10 +177,10 @@ class UpdateRequest implements UpdateRequestInterface
// it's still very fresh, and user wants a stable release:
if ($diff <= $expectedDiff) {
$return['level'] = 'info';
$return['message'] = (string)trans(
$return['message'] = (string) trans(
'firefly.just_new_release',
['version' => $latest,
'date' => $released->isoFormat((string)trans('config.month_and_day_js')),
'date' => $released->isoFormat((string) trans('config.month_and_day_js')),
'days' => $expectedDiff,
]
);
@ -191,12 +191,12 @@ class UpdateRequest implements UpdateRequestInterface
// its been around for a while:
$return['level'] = 'success';
$return['message'] = (string)trans(
$return['message'] = (string) trans(
'firefly.update_new_version_alert',
[
'your_version' => $current,
'new_version' => $latest,
'date' => $released->isoFormat((string)trans('config.month_and_day_js'))]
'date' => $released->isoFormat((string) trans('config.month_and_day_js'))]
);
Log::debug('New release is old enough.');

View File

@ -41,7 +41,7 @@ use stdClass;
class AccountDestroyService
{
/**
* @param Account $account
* @param Account $account
* @param Account|null $moveTo
*
* @return void
@ -87,7 +87,7 @@ class AccountDestroyService
->where('transaction_types.type', TransactionType::OPENING_BALANCE)
->get(['transactions.transaction_journal_id']);
if ($set->count() > 0) {
$journalId = (int)$set->first()->transaction_journal_id;
$journalId = (int) $set->first()->transaction_journal_id;
Log::debug(sprintf('Found opening balance journal with ID #%d', $journalId));
// get transactions with this journal (should be just one):
@ -133,8 +133,8 @@ class AccountDestroyService
$user = $account->user;
/** @var stdClass $row */
foreach ($collection as $row) {
if ((int)$row->the_count > 1) {
$journalId = (int)$row->transaction_journal_id;
if ((int) $row->the_count > 1) {
$journalId = (int) $row->transaction_journal_id;
$journal = $user->transactionJournals()->find($journalId);
if (null !== $journal) {
Log::debug(sprintf('Deleted journal #%d because it has the same source as destination.', $journal->id));
@ -192,7 +192,7 @@ class AccountDestroyService
/** @var RecurrenceDestroyService $destroyService */
$destroyService = app(RecurrenceDestroyService::class);
foreach ($recurrences as $recurrenceId) {
$destroyService->destroyById((int)$recurrenceId);
$destroyService->destroyById((int) $recurrenceId);
}
}

View File

@ -52,10 +52,10 @@ class BudgetDestroyService
}
// also delete all relations between categories and transaction journals:
DB::table('budget_transaction_journal')->where('budget_id', (int)$budget->id)->delete();
DB::table('budget_transaction_journal')->where('budget_id', (int) $budget->id)->delete();
// also delete all relations between categories and transactions:
DB::table('budget_transaction')->where('budget_id', (int)$budget->id)->delete();
DB::table('budget_transaction')->where('budget_id', (int) $budget->id)->delete();
// also delete all budget limits
$budget->budgetlimits()->delete();

View File

@ -46,9 +46,9 @@ class CategoryDestroyService
}
// also delete all relations between categories and transaction journals:
DB::table('category_transaction_journal')->where('category_id', (int)$category->id)->delete();
DB::table('category_transaction_journal')->where('category_id', (int) $category->id)->delete();
// also delete all relations between categories and transactions:
DB::table('category_transaction')->where('category_id', (int)$category->id)->delete();
DB::table('category_transaction')->where('category_id', (int) $category->id)->delete();
}
}

View File

@ -146,7 +146,7 @@ trait AccountServiceTrait
$data[$field] = 1;
}
$factory->crud($account, $field, (string)$data[$field]);
$factory->crud($account, $field, (string) $data[$field]);
}
}
}
@ -192,7 +192,7 @@ trait AccountServiceTrait
*/
public function validOBData(array $data): bool
{
$data['opening_balance'] = (string)($data['opening_balance'] ?? '');
$data['opening_balance'] = (string) ($data['opening_balance'] ?? '');
if ('' !== $data['opening_balance'] && 0 === bccomp($data['opening_balance'], '0')) {
$data['opening_balance'] = '';
}
@ -512,6 +512,63 @@ trait AccountServiceTrait
return $group;
}
/**
* See reference nr. 99
*
* @param TransactionGroup $group
*
* @return TransactionJournal
* @throws FireflyException
*/
private function getObJournal(TransactionGroup $group): TransactionJournal
{
/** @var TransactionJournal $journal */
$journal = $group->transactionJournals()->first();
if (null === $journal) {
throw new FireflyException(sprintf('Group #%d has no OB journal', $group->id));
}
return $journal;
}
/**
* See reference nr. 98
*
* @param TransactionJournal $journal
* @param Account $account
*
* @return Transaction
* @throws FireflyException
*/
private function getOBTransaction(TransactionJournal $journal, Account $account): Transaction
{
/** @var Transaction $transaction */
$transaction = $journal->transactions()->where('account_id', '!=', $account->id)->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Could not get OB transaction for journal #%d', $journal->id));
}
return $transaction;
}
/**
* @param TransactionJournal $journal
* @param Account $account
*
* @return Transaction
* @throws FireflyException
*/
private function getNotOBTransaction(TransactionJournal $journal, Account $account): Transaction
{
/** @var Transaction $transaction */
$transaction = $journal->transactions()->where('account_id', $account->id)->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Could not get non-OB transaction for journal #%d', $journal->id));
}
return $transaction;
}
/**
* Update or create the opening balance group.
* Since opening balance and date can still be empty strings, it may fail.
@ -667,61 +724,4 @@ trait AccountServiceTrait
return $group;
}
/**
* See reference nr. 99
*
* @param TransactionGroup $group
*
* @return TransactionJournal
* @throws FireflyException
*/
private function getObJournal(TransactionGroup $group): TransactionJournal
{
/** @var TransactionJournal $journal */
$journal = $group->transactionJournals()->first();
if (null === $journal) {
throw new FireflyException(sprintf('Group #%d has no OB journal', $group->id));
}
return $journal;
}
/**
* See reference nr. 98
*
* @param TransactionJournal $journal
* @param Account $account
*
* @return Transaction
* @throws FireflyException
*/
private function getOBTransaction(TransactionJournal $journal, Account $account): Transaction
{
/** @var Transaction $transaction */
$transaction = $journal->transactions()->where('account_id', '!=', $account->id)->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Could not get OB transaction for journal #%d', $journal->id));
}
return $transaction;
}
/**
* @param TransactionJournal $journal
* @param Account $account
*
* @return Transaction
* @throws FireflyException
*/
private function getNotOBTransaction(TransactionJournal $journal, Account $account): Transaction
{
/** @var Transaction $transaction */
$transaction = $journal->transactions()->where('account_id', $account->id)->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Could not get non-OB transaction for journal #%d', $journal->id));
}
return $transaction;
}
}

View File

@ -205,7 +205,7 @@ class CreditRecalculateService
$factory->crud($account, 'start_of_debt', $startOfDebt);
// get direction of liability:
$direction = (string)$this->repository->getMetaValue($account, 'liability_direction');
$direction = (string) $this->repository->getMetaValue($account, 'liability_direction');
// now loop all transactions (except opening balance and credit thing)
$transactions = $account->transactions()->get();
@ -246,7 +246,7 @@ class CreditRecalculateService
// to a credit-liability doesn't increase the amount (yet)
if (
$type === TransactionType::WITHDRAWAL
&& (int)$account->id === (int)$transaction->account_id
&& (int) $account->id === (int) $transaction->account_id
&& 1 === bccomp($transaction->amount, '0')
&& 'credit' === $direction
) {
@ -258,7 +258,7 @@ class CreditRecalculateService
// likewise deposit into a credit debt does not change the amount
if (
$type === TransactionType::DEPOSIT
&& (int)$account->id === (int)$transaction->account_id
&& (int) $account->id === (int) $transaction->account_id
&& -1 === bccomp($transaction->amount, '0')
&& 'credit' === $direction
) {

View File

@ -98,7 +98,7 @@ trait JournalServiceTrait
$search = null;
// first attempt, find by ID.
if (null !== $data['id']) {
$search = $this->accountRepository->find((int)$data['id']);
$search = $this->accountRepository->find((int) $data['id']);
if (null !== $search && in_array($search->accountType->type, $types, true)) {
Log::debug(
sprintf('Found "account_id" object: #%d, "%s" of type %s', $search->id, $search->name, $search->accountType->type)
@ -109,32 +109,6 @@ trait JournalServiceTrait
return $search;
}
/**
* @param Account|null $account
* @param array $data
* @param array $types
*
* @return Account|null
*/
private function findAccountByName(?Account $account, array $data, array $types): ?Account
{
// second attempt, find by name.
if (null === $account && null !== $data['name']) {
// find by preferred type.
$source = $this->accountRepository->findByName($data['name'], [$types[0]]);
// or any expected type.
$source = $source ?? $this->accountRepository->findByName($data['name'], $types);
if (null !== $source) {
Log::debug(sprintf('Found "account_name" object: #%d, %s', $source->id, $source->name));
$account = $source;
}
}
return $account;
}
/**
* @param Account|null $account
* @param array $data
@ -175,10 +149,10 @@ trait JournalServiceTrait
if (null === $account && null !== $data['number'] && '' !== (string) $data['number']) {
Log::debug(sprintf('Searching for account number "%s".', $data['number']));
// find by preferred type.
$source = $this->accountRepository->findByAccountNumber((string)$data['number'], [$types[0]]);
$source = $this->accountRepository->findByAccountNumber((string) $data['number'], [$types[0]]);
// or any expected type.
$source = $source ?? $this->accountRepository->findByAccountNumber((string)$data['number'], $types);
$source = $source ?? $this->accountRepository->findByAccountNumber((string) $data['number'], $types);
if (null !== $source) {
Log::debug(sprintf('Found account: #%d, %s', $source->id, $source->name));
@ -190,6 +164,32 @@ trait JournalServiceTrait
return $account;
}
/**
* @param Account|null $account
* @param array $data
* @param array $types
*
* @return Account|null
*/
private function findAccountByName(?Account $account, array $data, array $types): ?Account
{
// second attempt, find by name.
if (null === $account && null !== $data['name']) {
// find by preferred type.
$source = $this->accountRepository->findByName($data['name'], [$types[0]]);
// or any expected type.
$source = $source ?? $this->accountRepository->findByName($data['name'], $types);
if (null !== $source) {
Log::debug(sprintf('Found "account_name" object: #%d, %s', $source->id, $source->name));
$account = $source;
}
}
return $account;
}
/**
* @param Account|null $account
* @param array $data
@ -218,12 +218,12 @@ trait JournalServiceTrait
throw new FireflyException(sprintf('TransactionFactory: Cannot create asset account with these values: %s', json_encode($data)));
}
// fix name of account if only IBAN is given:
if ('' === (string)$data['name'] && '' !== (string)$data['iban']) {
if ('' === (string) $data['name'] && '' !== (string) $data['iban']) {
Log::debug(sprintf('Account name is now IBAN ("%s")', $data['iban']));
$data['name'] = $data['iban'];
}
// fix name of account if only number is given:
if ('' === (string)$data['name'] && '' !== (string)$data['number']) {
if ('' === (string) $data['name'] && '' !== (string) $data['number']) {
Log::debug(sprintf('Account name is now account number ("%s")', $data['number']));
$data['name'] = $data['number'];
}
@ -379,7 +379,7 @@ trait JournalServiceTrait
*/
protected function storeNotes(TransactionJournal $journal, ?string $notes): void
{
$notes = (string)$notes;
$notes = (string) $notes;
$note = $journal->notes()->first();
if ('' !== $notes) {
if (null === $note) {
@ -422,7 +422,7 @@ trait JournalServiceTrait
}
Log::debug('Start of loop.');
foreach ($tags as $string) {
$string = (string)$string;
$string = (string) $string;
Log::debug(sprintf('Now at tag "%s"', $string));
if ('' !== $string) {
$tag = $this->tagFactory->findOrCreate($string);

View File

@ -144,7 +144,7 @@ trait RecurringTransactionTrait
if (!$validator->validateDestination(['id' => $destination->id])) {
throw new FireflyException(sprintf('Destination invalid: %s', $validator->destError));
}
if (array_key_exists('foreign_amount', $array) && '' === (string)$array['foreign_amount']) {
if (array_key_exists('foreign_amount', $array) && '' === (string) $array['foreign_amount']) {
unset($array['foreign_amount']);
}
// See reference nr. 100
@ -156,25 +156,25 @@ trait RecurringTransactionTrait
'source_id' => $source->id,
'destination_id' => $destination->id,
'amount' => $array['amount'],
'foreign_amount' => array_key_exists('foreign_amount', $array) ? (string)$array['foreign_amount'] : null,
'foreign_amount' => array_key_exists('foreign_amount', $array) ? (string) $array['foreign_amount'] : null,
'description' => $array['description'],
]
);
$transaction->save();
if (array_key_exists('budget_id', $array)) {
$this->setBudget($transaction, (int)$array['budget_id']);
$this->setBudget($transaction, (int) $array['budget_id']);
}
if (array_key_exists('bill_id', $array)) {
$this->setBill($transaction, (int)$array['bill_id']);
$this->setBill($transaction, (int) $array['bill_id']);
}
if (array_key_exists('category_id', $array)) {
$this->setCategory($transaction, (int)$array['category_id']);
$this->setCategory($transaction, (int) $array['category_id']);
}
// same for piggy bank
if (array_key_exists('piggy_bank_id', $array)) {
$this->updatePiggyBank($transaction, (int)$array['piggy_bank_id']);
$this->updatePiggyBank($transaction, (int) $array['piggy_bank_id']);
}
if (array_key_exists('tags', $array) && is_array($array['tags'])) {
@ -194,14 +194,14 @@ trait RecurringTransactionTrait
protected function findAccount(array $expectedTypes, ?int $accountId, ?string $accountName): Account
{
$result = null;
$accountId = (int)$accountId;
$accountName = (string)$accountName;
$accountId = (int) $accountId;
$accountName = (string) $accountName;
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($this->user);
// if user has submitted an account ID, search for it.
$result = $repository->find((int)$accountId);
$result = $repository->find((int) $accountId);
if (null !== $result) {
return $result;
}

View File

@ -89,7 +89,7 @@ class AccountUpdateService
// find currency, or use default currency instead.
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
$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'], $data['currency_id']);
$data['currency_id'] = $currency->id;
}
@ -108,7 +108,7 @@ class AccountUpdateService
// update note:
if (array_key_exists('notes', $data) && null !== $data['notes']) {
$this->updateNote($account, (string)$data['notes']);
$this->updateNote($account, (string) $data['notes']);
}
// update preferences if inactive:
@ -135,7 +135,7 @@ class AccountUpdateService
$account->active = $data['active'];
}
if (array_key_exists('iban', $data)) {
$account->iban = app('steam')->filterSpaces((string)$data['iban']);
$account->iban = app('steam')->filterSpaces((string) $data['iban']);
}
// set liability, but account must already be a liability.
@ -149,7 +149,7 @@ class AccountUpdateService
// set liability, alternative method used in v1 layout:
if ($this->isLiability($account) && array_key_exists('account_type_id', $data)) {
$type = AccountType::find((int)$data['account_type_id']);
$type = AccountType::find((int) $data['account_type_id']);
if (null !== $type && in_array($type->type, config('firefly.valid_liabilities'), true)) {
$account->account_type_id = $type->id;
@ -210,7 +210,7 @@ class AccountUpdateService
return $account;
}
// get account type ID's because a join and an update is hard:
$oldOrder = (int)$account->order;
$oldOrder = (int) $account->order;
$newOrder = $data['order'];
Log::debug(sprintf('Order is set to be updated from %s to %s', $oldOrder, $newOrder));
$list = $this->getTypeIds([AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT]);
@ -248,7 +248,7 @@ class AccountUpdateService
foreach ($array as $type) {
/** @var AccountType $type */
$type = AccountType::whereType($type)->first();
$return[] = (int)$type->id;
$return[] = (int) $type->id;
}
return $return;
@ -357,12 +357,12 @@ class AccountUpdateService
$array = $preference->data;
Log::debug('Old array is: ', $array);
Log::debug(sprintf('Must remove : %d', $account->id));
$removeAccountId = (int)$account->id;
$removeAccountId = (int) $account->id;
$new = [];
foreach ($array as $value) {
if ((int)$value !== $removeAccountId) {
if ((int) $value !== $removeAccountId) {
Log::debug(sprintf('Will include: %d', $value));
$new[] = (int)$value;
$new[] = (int) $value;
}
}
Log::debug('Final new array is', $new);

View File

@ -56,7 +56,7 @@ class BillUpdateService
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
$factory = app(TransactionCurrencyFactory::class);
$currency = $factory->find((int)($data['currency_id'] ?? null), $data['currency_code'] ?? null) ??
$currency = $factory->find((int) ($data['currency_id'] ?? null), $data['currency_code'] ?? null) ??
app('amount')->getDefaultCurrencyByUser($bill->user);
// enable the currency if it isn't.
@ -78,14 +78,14 @@ class BillUpdateService
];
// update note:
if (array_key_exists('notes', $data)) {
$this->updateNote($bill, (string)$data['notes']);
$this->updateNote($bill, (string) $data['notes']);
}
// update order.
if (array_key_exists('order', $data)) {
// update the order of the piggy bank:
$oldOrder = (int)$bill->order;
$newOrder = (int)($data['order'] ?? $oldOrder);
$oldOrder = (int) $bill->order;
$newOrder = (int) ($data['order'] ?? $oldOrder);
if ($oldOrder !== $newOrder) {
$this->updateOrder($bill, $oldOrder, $newOrder);
}
@ -117,7 +117,7 @@ class BillUpdateService
}
if (array_key_exists('object_group_id', $data)) {
// try also with ID:
$objectGroupId = (int)($data['object_group_id'] ?? 0);
$objectGroupId = (int) ($data['object_group_id'] ?? 0);
if (0 !== $objectGroupId) {
$objectGroup = $this->findObjectGroupById($objectGroupId);
if (null !== $objectGroup) {
@ -144,20 +144,20 @@ class BillUpdateService
*/
private function updateBillProperties(Bill $bill, array $data): Bill
{
if (array_key_exists('name', $data) && '' !== (string)$data['name']) {
if (array_key_exists('name', $data) && '' !== (string) $data['name']) {
$bill->name = $data['name'];
}
if (array_key_exists('amount_min', $data) && '' !== (string)$data['amount_min']) {
if (array_key_exists('amount_min', $data) && '' !== (string) $data['amount_min']) {
$bill->amount_min = $data['amount_min'];
}
if (array_key_exists('amount_max', $data) && '' !== (string)$data['amount_max']) {
if (array_key_exists('amount_max', $data) && '' !== (string) $data['amount_max']) {
$bill->amount_max = $data['amount_max'];
}
if (array_key_exists('date', $data) && '' !== (string)$data['date']) {
if (array_key_exists('date', $data) && '' !== (string) $data['date']) {
$bill->date = $data['date'];
}
if (array_key_exists('repeat_freq', $data) && '' !== (string)$data['repeat_freq']) {
if (array_key_exists('repeat_freq', $data) && '' !== (string) $data['repeat_freq']) {
$bill->repeat_freq = $data['repeat_freq'];
}
if (array_key_exists('skip', $data)) {
@ -166,10 +166,10 @@ class BillUpdateService
if (array_key_exists('active', $data)) {
$bill->active = $data['active'];
}
if(array_key_exists('end_date', $data)) {
if (array_key_exists('end_date', $data)) {
$bill->end_date = $data['end_date'];
}
if(array_key_exists('extension_date', $data)) {
if (array_key_exists('extension_date', $data)) {
$bill->extension_date = $data['extension_date'];
}

View File

@ -40,15 +40,15 @@ class CurrencyUpdateService
*/
public function update(TransactionCurrency $currency, array $data): TransactionCurrency
{
if (array_key_exists('code', $data) && '' !== (string)$data['code']) {
if (array_key_exists('code', $data) && '' !== (string) $data['code']) {
$currency->code = $data['code'];
}
if (array_key_exists('symbol', $data) && '' !== (string)$data['symbol']) {
if (array_key_exists('symbol', $data) && '' !== (string) $data['symbol']) {
$currency->symbol = $data['symbol'];
}
if (array_key_exists('name', $data) && '' !== (string)$data['name']) {
if (array_key_exists('name', $data) && '' !== (string) $data['name']) {
$currency->name = $data['name'];
}

View File

@ -48,7 +48,7 @@ class GroupCloneService
$newGroup = $group->replicate();
$newGroup->save();
foreach ($group->transactionJournals as $journal) {
$this->cloneJournal($journal, $newGroup, (int)$group->id);
$this->cloneJournal($journal, $newGroup, (int) $group->id);
}
return $newGroup;

View File

@ -215,7 +215,7 @@ class JournalUpdateService
$validator->setTransactionType($expectedType);
$validator->setUser($this->transactionJournal->user);
$result = $validator->validateSource(['id' =>$sourceId]);
$result = $validator->validateSource(['id' => $sourceId]);
Log::debug(sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true)));
// See reference nr. 95
@ -359,7 +359,7 @@ class JournalUpdateService
}
$sourceInfo = [
'id' => (int)($this->data['source_id'] ?? null),
'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,
@ -424,7 +424,7 @@ class JournalUpdateService
}
$destInfo = [
'id' => (int)($this->data['destination_id'] ?? null),
'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,
@ -487,8 +487,8 @@ class JournalUpdateService
)
&& TransactionType::WITHDRAWAL === $type
) {
$billId = (int)($this->data['bill_id'] ?? 0);
$billName = (string)($this->data['bill_name'] ?? '');
$billId = (int) ($this->data['bill_id'] ?? 0);
$billName = (string) ($this->data['bill_name'] ?? '');
$bill = $this->billRepository->findBill($billId, $billName);
$this->transactionJournal->bill_id = $bill?->id;
Log::debug('Updated bill ID');
@ -502,7 +502,7 @@ class JournalUpdateService
*/
private function updateField(string $fieldName): void
{
if (array_key_exists($fieldName, $this->data) && '' !== (string)$this->data[$fieldName]) {
if (array_key_exists($fieldName, $this->data) && '' !== (string) $this->data[$fieldName]) {
$value = $this->data[$fieldName];
if ('date' === $fieldName) {
@ -579,7 +579,7 @@ class JournalUpdateService
{
// update notes.
if ($this->hasFields(['notes'])) {
$notes = '' === (string)$this->data['notes'] ? null : $this->data['notes'];
$notes = '' === (string) $this->data['notes'] ? null : $this->data['notes'];
$this->storeNotes($this->transactionJournal, $notes);
}
}
@ -636,7 +636,7 @@ class JournalUpdateService
foreach ($this->metaDate as $field) {
if ($this->hasFields([$field])) {
try {
$value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
$value = '' === (string) $this->data[$field] ? null : new Carbon($this->data[$field]);
} catch (Exception $e) { // @phpstan-ignore-line
Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));

Some files were not shown because too many files have changed in this diff Show More