/** * EntryAccount constructor. * * @param Account $account */ public function __construct(Account $account) { $this->accountId = $account->id; $this->name = $account->name; $this->iban = $account->iban; $this->type = $account->accountType->type; $this->number = $account->getMeta('accountNumber'); }
/** * */ public function createAccount() { $user = FactoryMuffin::create('FireflyIII\\User'); $this->be($user); if (is_null($this->account)) { $this->account = FactoryMuffin::create('FireflyIII\\Models\\Account'); $this->account->user_id = $user->id; $this->account->save(); } }
/** * * @param \FireflyIII\Models\Account $account * @param \Carbon\Carbon $date * * @return string */ public function balanceIgnoreVirtual(Account $account, Carbon $date) : string { // abuse chart properties: $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty('balance-no-virtual'); $cache->addProperty($date); if ($cache->has()) { return $cache->get(); } $balance = strval($account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount')); $cache->store($balance); return $balance; }
/** * * @param \FireflyIII\Models\Account $account * @param \Carbon\Carbon $date * @param bool $ignoreVirtualBalance * * @return float */ public function balance(Account $account, Carbon $date, $ignoreVirtualBalance = false) { // abuse chart properties: $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty('balance'); $cache->addProperty($date); $cache->addProperty($ignoreVirtualBalance); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } bcscale(2); $balance = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount'); if (!$ignoreVirtualBalance) { $balance = bcadd($balance, $account->virtual_balance); } $cache->store(round($balance, 2)); return round($balance, 2); }
/** * @covers FireflyIII\Models\Account::firstOrNullEncrypted */ public function testFirstOrNullEncryptedNew() { // create account: $account = FactoryMuffin::create('FireflyIII\\Models\\Account'); FactoryMuffin::create('FireflyIII\\User'); // search for account with the same properties: $search = ['name' => 'Some new account', 'account_type_id' => $account->account_type_id, 'user_id' => $account->user_id, 'active' => 1]; $result = Account::firstOrNullEncrypted($search); // should not be the same account: $this->assertNull($result); }
/** * @param $value * @param $route * * @return mixed */ public static function routeBinder($value, $route) { if (Auth::check()) { $ids = explode(',', $value); /** @var \Illuminate\Support\Collection $object */ $object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')->where('account_types.editable', 1)->whereIn('accounts.id', $ids)->where('user_id', Auth::user()->id)->get(['accounts.*']); if ($object->count() > 0) { return $object; } } throw new NotFoundHttpException(); }
/** * @return array */ public function rules() { $accountRoles = join(',', array_keys(Config::get('firefly.accountRoles'))); $types = join(',', array_keys(Config::get('firefly.subTitlesByIdentifier'))); $ccPaymentTypes = join(',', array_keys(Config::get('firefly.ccTypes'))); $nameRule = 'required|min:1|uniqueAccountForUser'; $idRule = ''; if (Account::find(Input::get('id'))) { $idRule = 'belongsToUser:accounts'; $nameRule = 'required|min:1|uniqueAccountForUser:'******'id'); } return ['id' => $idRule, 'name' => $nameRule, 'openingBalance' => 'numeric', 'iban' => 'iban', 'virtualBalance' => 'numeric', 'openingBalanceDate' => 'date', 'accountRole' => 'in:' . $accountRoles, 'active' => 'boolean', 'ccType' => 'in:' . $ccPaymentTypes, 'ccMonthlyPaymentDate' => 'date', 'balance_currency_id' => 'exists:transaction_currencies,id', 'what' => 'in:' . $types]; }
/** * @param User $user */ public static function createAssetAccounts(User $user) { $assets = ['TestData Checking Account', 'TestData Savings', 'TestData Shared', 'TestData Creditcard', 'Emergencies', 'STE']; // first two ibans match test-upload.csv $ibans = ['NL11XOLA6707795988', 'NL96DZCO4665940223', 'NL81RCQZ7160379858', 'NL19NRAP2367994221', 'NL40UKBK3619908726', 'NL38SRMN4325934708']; $assetMeta = [['accountRole' => 'defaultAsset'], ['accountRole' => 'savingAsset'], ['accountRole' => 'sharedAsset'], ['accountRole' => 'ccAsset', 'ccMonthlyPaymentDate' => '2015-05-27', 'ccType' => 'monthlyFull'], ['accountRole' => 'savingAsset'], ['accountRole' => 'savingAsset']]; foreach ($assets as $index => $name) { // create account: $account = Account::create(['user_id' => $user->id, 'account_type_id' => 3, 'name' => $name, 'active' => 1, 'encrypted' => 1, 'iban' => $ibans[$index]]); foreach ($assetMeta[$index] as $name => $value) { AccountMeta::create(['account_id' => $account->id, 'name' => $name, 'data' => $value]); } } }
/** * @param $value * @param $route * * @return Collection */ public static function routeBinder($value, $route) : Collection { if (auth()->check()) { $ids = explode(',', $value); // filter ids: $ids = self::filterIds($ids); /** @var \Illuminate\Support\Collection $object */ $object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')->whereIn('accounts.id', $ids)->where('user_id', auth()->user()->id)->get(['accounts.*']); if ($object->count() > 0) { return $object; } } throw new NotFoundHttpException(); }
/** * @covers FireflyIII\Repositories\Account\AccountRepository::destroy * @covers FireflyIII\Providers\EventServiceProvider::boot * @covers FireflyIII\Providers\EventServiceProvider::registerDeleteEvents */ public function testDestroy() { // create account: $account = FactoryMuffin::create('FireflyIII\\Models\\Account'); // create some transactions and attach them to the account: for ($i = 0; $i < 5; $i++) { $transaction = FactoryMuffin::create('FireflyIII\\Models\\Transaction'); $transaction->account_id = $account->id; $transaction->save(); } $accountId = $account->id; $this->be($account->user); $this->object->destroy($account); // cannot find account: $this->assertCount(0, Account::whereId($accountId)->whereNotNull('deleted_at')->get()); }
/** * */ protected function registerDeleteEvents() { TransactionJournal::deleted(function (TransactionJournal $journal) { /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { $transaction->delete(); } }); Account::deleted(function (Account $account) { /** @var Transaction $transaction */ foreach ($account->transactions()->get() as $transaction) { $journal = $transaction->transactionJournal()->first(); $journal->delete(); } }); }
/** * This method generates a full report for the given period on all * given accounts * * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return AccountCollection */ public function getAccountReport(Carbon $start, Carbon $end, Collection $accounts) { $startAmount = '0'; $endAmount = '0'; $diff = '0'; $ids = $accounts->pluck('id')->toArray(); $yesterday = clone $start; $yesterday->subDay(); bcscale(2); // get balances for start. $startSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->whereIn('accounts.id', $ids)->whereNull('transaction_journals.deleted_at')->whereNull('transactions.deleted_at')->where('transaction_journals.date', '<=', $yesterday->format('Y-m-d'))->groupBy('accounts.id')->get(['accounts.id', DB::Raw('SUM(`transactions`.`amount`) as `balance`')]); // and end: $endSet = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->whereIn('accounts.id', $ids)->whereNull('transaction_journals.deleted_at')->whereNull('transactions.deleted_at')->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->groupBy('accounts.id')->get(['accounts.id', DB::Raw('SUM(`transactions`.`amount`) as `balance`')]); $accounts->each(function (Account $account) use($startSet, $endSet) { /** * The balance for today always incorporates transactions * made on today. So to get todays "start" balance, we sub one * day. */ // $currentStart = $startSet->filter(function (Account $entry) use($account) { return $account->id == $entry->id; }); if ($currentStart->first()) { $account->startBalance = $currentStart->first()->balance; } $currentEnd = $endSet->filter(function (Account $entry) use($account) { return $account->id == $entry->id; }); if ($currentEnd->first()) { $account->endBalance = $currentEnd->first()->balance; } }); // summarize: foreach ($accounts as $account) { $startAmount = bcadd($startAmount, $account->startBalance); $endAmount = bcadd($endAmount, $account->endBalance); $diff = bcadd($diff, bcsub($account->endBalance, $account->startBalance)); } $object = new AccountCollection(); $object->setStart($startAmount); $object->setEnd($endAmount); $object->setDifference($diff); $object->setAccounts($accounts); return $object; }
/** * @param array $fields * * @return Account|null */ public static function firstOrNullEncrypted(array $fields) { // everything but the name: $query = Account::orderBy('id'); $search = $fields; unset($search['name']); foreach ($search as $name => $value) { $query->where($name, $value); } $set = $query->get(['accounts.*']); /** @var Account $account */ foreach ($set as $account) { if ($account->name == $fields['name']) { return $account; } } return null; }
/** * @return Account|null */ public function convert() { // is mapped? Then it's easy! if (isset($this->mapped[$this->index][$this->value])) { $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); return $account; } if (strlen($this->value) > 0) { // find or create new account: $account = $this->findAccount(); $accountType = AccountType::where('type', 'Asset account')->first(); if (is_null($account)) { // create it if doesn't exist. $account = Account::firstOrCreateEncrypted(['name' => $this->value, 'iban' => $this->value, 'user_id' => Auth::user()->id, 'account_type_id' => $accountType->id, 'active' => 1]); } return $account; } return null; }
/** * @return Account|null */ public function convert() { // is mapped? Then it's easy! if (isset($this->mapped[$this->index][$this->value])) { $account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]); return $account; } // find or create new account: $accountType = AccountType::where('type', 'Asset account')->first(); $set = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get(); /** @var Account $entry */ foreach ($set as $entry) { if ($entry->name == $this->value) { return $entry; } } // create it if doesnt exist. $account = Account::firstOrCreateEncrypted(['name' => $this->value, 'iban' => '', 'user_id' => Auth::user()->id, 'account_type_id' => $accountType->id, 'active' => 1]); return $account; }
/** * */ protected function registerDeleteEvents() { Account::deleted(function (Account $account) { Log::debug('Now trigger account delete response #' . $account->id); /** @var Transaction $transaction */ foreach ($account->transactions()->get() as $transaction) { Log::debug('Now at transaction #' . $transaction->id); $journal = $transaction->transactionJournal()->first(); if (!is_null($journal)) { Log::debug('Call for deletion of journal #' . $journal->id); $journal->delete(); } } }); TransactionJournal::deleted(function (TransactionJournal $journal) { Log::debug('Now triggered journal delete response #' . $journal->id); /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { Log::debug('Will now delete transaction #' . $transaction->id); $transaction->delete(); } }); }
/** * */ protected function createRevenueAccounts() { $revenues = ['Job', 'Belastingdienst', 'Bank', 'KPN', 'Google']; foreach ($revenues as $name) { // create account: Account::create(['user_id' => $this->user->id, 'account_type_id' => 5, 'name' => $name, 'active' => 1, 'encrypted' => 1]); } }
/** * @param array $data * * @return array */ private function storeWithdrawalAccounts(array $data) : array { $sourceAccount = Account::where('user_id', $this->user->id)->where('id', $data['source_account_id'])->first(['accounts.*']); if (strlen($data['destination_account_name']) > 0) { $destinationType = AccountType::where('type', 'Expense account')->first(); $destinationAccount = Account::firstOrCreateEncrypted(['user_id' => $data['user'], 'account_type_id' => $destinationType->id, 'name' => $data['destination_account_name'], 'active' => 1]); return [$sourceAccount, $destinationAccount]; } $destinationType = AccountType::where('type', 'Cash account')->first(); $destinationAccount = Account::firstOrCreateEncrypted(['user_id' => $data['user'], 'account_type_id' => $destinationType->id, 'name' => 'Cash account', 'active' => 1]); return [$sourceAccount, $destinationAccount]; }
/** * @return Account|null */ protected function parseNameString() { $accountType = $this->getAccountType(); $accounts = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get(); foreach ($accounts as $entry) { if ($entry->name == $this->data['asset-account-name']) { Log::debug('Found an asset account with this name (#' . $entry->id . ': ******)'); return $entry; } } // create if not exists: $account = Account::firstOrCreateEncrypted(['user_id' => Auth::user()->id, 'account_type_id' => $accountType->id, 'name' => $this->data['asset-account-name'], 'iban' => '', 'active' => true]); return $account; }
/** * @param $value * * @return bool * @internal param $parameters * */ protected function validateByAccountId($value) { /** @var Account $existingAccount */ $existingAccount = Account::find($this->data['id']); $type = $existingAccount->accountType; $ignore = $existingAccount->id; $value = $this->tryDecrypt($value); $set = Auth::user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)->get(); /** @var Account $entry */ foreach ($set as $entry) { if ($entry->name == $value) { return false; } } return true; }
/** * @param array $ids * @param Carbon $date * * @return Collection */ private function getSet(array $ids, Carbon $date) : Collection { return Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->whereIn('accounts.id', $ids)->whereNull('transaction_journals.deleted_at')->whereNull('transactions.deleted_at')->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->groupBy('accounts.id')->get(['accounts.id', DB::raw('SUM(`transactions`.`amount`) as `balance`')]); }
/** * @param User $user */ private function openingBalanceSavings(User $user) { // opposing account for opening balance: $opposing = Account::create(['user_id' => $user->id, 'account_type_id' => 6, 'name' => 'Opposing for savings', 'active' => 1, 'encrypted' => 1]); // savings $savings = TestData::findAccount($user, 'TestData Savings'); $journal = TransactionJournal::create(['user_id' => $user->id, 'transaction_type_id' => 4, 'transaction_currency_id' => 1, 'description' => 'Opening balance for savings account', 'completed' => 1, 'date' => $this->start->format('Y-m-d')]); // transactions Transaction::create(['account_id' => $opposing->id, 'transaction_journal_id' => $journal->id, 'amount' => -10000]); Transaction::create(['account_id' => $savings->id, 'transaction_journal_id' => $journal->id, 'amount' => 10000]); }
/** * @param Account $account * * @return Carbon */ public function firstUseDate(Account $account) : Carbon { $first = new Carbon('1900-01-01'); /** @var Transaction $first */ $date = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->orderBy('transaction_journals.date', 'ASC')->orderBy('transaction_journals.order', 'DESC')->orderBy('transaction_journals.id', 'ASC')->first(['transaction_journals.date']); if (!is_null($date)) { $first = new Carbon($date->date); } return $first; }
use FireflyIII\Models\Account; use FireflyIII\Models\Attachment; use FireflyIII\Models\Bill; use FireflyIII\Models\Budget; use FireflyIII\Models\Category; use FireflyIII\Models\LimitRepetition; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Tag; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; // models Route::bind('account', function ($value) { if (Auth::check()) { $object = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')->where('account_types.editable', 1)->where('accounts.id', $value)->where('user_id', Auth::user()->id)->first(['accounts.*']); if ($object) { return $object; } } throw new NotFoundHttpException(); }); Route::bind('tj', function ($value) { if (Auth::check()) { $object = TransactionJournal::where('id', $value)->where('user_id', Auth::user()->id)->first(); if ($object) { return $object; } } throw new NotFoundHttpException(); });
/** * Reports on deleted accounts that still have not deleted transactions or journals attached to them. */ private function reportDeletedAccounts() { $set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->whereNotNull('accounts.deleted_at')->whereNotNull('transactions.id')->where(function (Builder $q) { $q->whereNull('transactions.deleted_at'); $q->orWhereNull('transaction_journals.deleted_at'); })->get(['accounts.id as account_id', 'accounts.deleted_at as account_deleted_at', 'transactions.id as transaction_id', 'transactions.deleted_at as transaction_deleted_at', 'transaction_journals.id as journal_id', 'transaction_journals.deleted_at as journal_deleted_at']); /** @var stdClass $entry */ foreach ($set as $entry) { $date = is_null($entry->transaction_deleted_at) ? $entry->journal_deleted_at : $entry->transaction_deleted_at; $this->error('Error: Account #' . $entry->account_id . ' should have been deleted, but has not.' . ' Find it in the table called `accounts` and change the `deleted_at` field to: "' . $date . '"'); } }
/** * @param array $data * * @return array */ protected function storeDepositAccounts(array $data) { $toAccount = Account::find($data['account_id']); if (strlen($data['revenue_account']) > 0) { $fromType = AccountType::where('type', 'Revenue account')->first(); $fromAccount = Account::firstOrCreateEncrypted(['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => $data['revenue_account'], 'active' => 1]); } else { $toType = AccountType::where('type', 'Cash account')->first(); $fromAccount = Account::firstOrCreateEncrypted(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]); } return [$fromAccount, $toAccount]; }
/** * */ public function createRevenueAccounts() { $user = User::whereEmail('*****@*****.**')->first(); $revenueType = AccountType::whereType('Revenue account')->first(); Account::create(['user_id' => $user->id, 'account_type_id' => $revenueType->id, 'name' => 'Employer', 'active' => 1]); Account::create(['user_id' => $user->id, 'account_type_id' => $revenueType->id, 'name' => 'IRS', 'active' => 1]); Account::create(['user_id' => $user->id, 'account_type_id' => $revenueType->id, 'name' => 'Second job employer', 'active' => 1]); }
/** * @param Account $account * @param array $data * * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function updateMetadata(Account $account, array $data) { $validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType']; foreach ($validFields as $field) { $entry = $account->accountMeta()->where('name', $field)->first(); // update if new data is present: if ($entry && isset($data[$field])) { $entry->data = $data[$field]; $entry->save(); } // no entry but data present? if (!$entry && isset($data[$field])) { $metaData = new AccountMeta(['account_id' => $account->id, 'name' => $field, 'data' => $data[$field]]); $metaData->save(); } } }
/** * @param $name * * @return Account|null */ protected function findAccount($name) { /** @var Account $account */ foreach (Account::get() as $account) { if ($account->name == $name && $this->user->id == $account->user_id) { return $account; break; } } return null; }
/** * @param Account $account * @param array $data * */ protected function updateMetadata(Account $account, array $data) { foreach ($this->validFields as $field) { $entry = $account->accountMeta()->where('name', $field)->first(); if (isset($data[$field])) { // update if new data is present: if (!is_null($entry)) { $entry->data = $data[$field]; $entry->save(); continue; } $metaData = new AccountMeta(['account_id' => $account->id, 'name' => $field, 'data' => $data[$field]]); $metaData->save(); } } }