/**
  * 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();
     }
 }
Beispiel #3
0
 /**
  *
  * @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;
 }
Beispiel #4
0
 /**
  *
  * @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);
 }
Beispiel #5
0
 /**
  * @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);
 }
Beispiel #6
0
 /**
  * @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];
 }
Beispiel #8
0
 /**
  * @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;
 }
Beispiel #13
0
 /**
  * @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`')]);
 }
Beispiel #22
0
 /**
  * @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;
 }
Beispiel #24
0
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 . '"');
     }
 }
Beispiel #26
0
 /**
  * @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];
 }
Beispiel #27
0
 /**
  *
  */
 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();
         }
     }
 }