mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Reformat various code.
This commit is contained in:
parent
29bed2547c
commit
d1a09ff33b
@ -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;
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ class PiggyBankEvent extends Model
|
||||
*/
|
||||
public function setAmountAttribute($value): void
|
||||
{
|
||||
$this->attributes['amount'] = (string)$value;
|
||||
$this->attributes['amount'] = (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -236,7 +236,7 @@ class Transaction extends Model
|
||||
*/
|
||||
public function setAmountAttribute($value): void
|
||||
{
|
||||
$this->attributes['amount'] = (string)$value;
|
||||
$this->attributes['amount'] = (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
= [
|
||||
|
@ -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'];
|
||||
|
||||
/**
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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');
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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.');
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ trait CreatesObjectGroups
|
||||
*/
|
||||
protected function getObjectGroupMaxOrder(): int
|
||||
{
|
||||
return (int)$this->user->objectGroups()->max('order');
|
||||
return (int) $this->user->objectGroups()->max('order');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -39,7 +39,7 @@ class IsBoolean implements Rule
|
||||
*/
|
||||
public function message(): string
|
||||
{
|
||||
return (string)trans('validation.boolean');
|
||||
return (string) trans('validation.boolean');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,7 +42,7 @@ class ValidJournals implements Rule
|
||||
*/
|
||||
public function message(): string
|
||||
{
|
||||
return (string)trans('validation.invalid_selection');
|
||||
return (string) trans('validation.invalid_selection');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.');
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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'];
|
||||
}
|
||||
|
||||
|
@ -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'];
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user