Exemple #1
0
 /**
  *
  * @param array          $ids
  * @param \Carbon\Carbon $date
  *
  * @return float
  */
 public function balancesById(array $ids, Carbon $date)
 {
     // abuse chart properties:
     $cache = new CacheProperties();
     $cache->addProperty($ids);
     $cache->addProperty('balances');
     $cache->addProperty($date);
     if ($cache->has()) {
         return $cache->get();
         // @codeCoverageIgnore
     }
     bcscale(2);
     $balances = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->groupBy('transactions.account_id')->whereIn('transactions.account_id', $ids)->get(['transactions.account_id', DB::Raw('sum(`transactions`.`amount`) as aggregate')]);
     $result = [];
     foreach ($balances as $entry) {
         $accountId = intval($entry->account_id);
         $balance = round($entry->aggregate, 2);
         $result[$accountId] = $balance;
     }
     $cache->store($result);
     return $result;
 }
 /**
  * @param TransactionJournal $journal
  * @param array              $transaction
  *
  * @return Collection
  */
 public function storeTransaction(TransactionJournal $journal, array $transaction) : Collection
 {
     // store accounts (depends on type)
     list($sourceAccount, $destinationAccount) = $this->storeAccounts($journal->transactionType->type, $transaction);
     // store transaction one way:
     /** @var Transaction $one */
     $one = Transaction::create(['account_id' => $sourceAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $transaction['amount'] * -1, 'description' => $transaction['description']]);
     $two = Transaction::create(['account_id' => $destinationAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $transaction['amount'], 'description' => $transaction['description']]);
     if (strlen($transaction['category']) > 0) {
         $category = Category::firstOrCreateEncrypted(['name' => $transaction['category'], 'user_id' => $journal->user_id]);
         $one->categories()->save($category);
         $two->categories()->save($category);
     }
     if (intval($transaction['budget_id']) > 0) {
         $budget = Budget::find($transaction['budget_id']);
         $one->budgets()->save($budget);
         $two->budgets()->save($budget);
     }
     if ($transaction['piggy_bank_id'] > 0) {
         $transaction['date'] = $journal->date->format('Y-m-d');
         event(new TransactionStored($transaction));
     }
     return new Collection([$one, $two]);
 }
 /**
  * @param Carbon $date
  *
  * @return TransactionJournal
  */
 protected function createSavings(Carbon $date)
 {
     $date = new Carbon($date->format('Y-m') . '-24');
     // paid on 24th.
     $toAccount = $this->findAccount('Savings');
     $fromAccount = $this->findAccount('MyBank Checking Account');
     $category = Category::firstOrCreateEncrypted(['name' => 'Money management', 'user_id' => $this->user->id]);
     // create journal:
     $journal = TransactionJournal::create(['user_id' => $this->user->id, 'transaction_type_id' => 3, 'transaction_currency_id' => 1, 'description' => 'Save money', 'completed' => 1, 'date' => $date]);
     Transaction::create(['account_id' => $fromAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => -150]);
     Transaction::create(['account_id' => $toAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => 150]);
     $journal->categories()->save($category);
     return $journal;
 }
Exemple #4
0
 /**
  * @param array $data
  *
  * @return TransactionJournal
  */
 public function createJournal(array $data)
 {
     $user = User::whereEmail('*****@*****.**')->first();
     $billID = isset($data['bill']) ? $data['bill']->id : null;
     /** @var TransactionJournal $journal */
     $journal = TransactionJournal::create(['user_id' => $user->id, 'transaction_type_id' => $data['transactionType']->id, 'transaction_currency_id' => $data['transactionCurrency']->id, 'bill_id' => $billID, 'description' => $data['description'], 'completed' => 1, 'date' => $data['date']]);
     Transaction::create(['account_id' => $data['from']->id, 'transaction_journal_id' => $journal->id, 'amount' => $data['amount'] * -1]);
     Transaction::create(['account_id' => $data['to']->id, 'transaction_journal_id' => $journal->id, 'amount' => $data['amount']]);
     if (isset($data['budget'])) {
         $journal->budgets()->save($data['budget']);
     }
     if (isset($data['category'])) {
         $journal->categories()->save($data['category']);
     }
     return $journal;
 }
 /**
  * @param        $description
  * @param Carbon $date
  * @param        $amount
  *
  * @return TransactionJournal
  */
 protected function createWater($description, Carbon $date, $amount)
 {
     $date = new Carbon($date->format('Y-m') . '-10');
     // paid on 10th
     $fromAccount = TestData::findAccount($this->user, 'TestData Checking Account');
     $toAccount = TestData::findAccount($this->user, 'Vitens');
     $category = Category::firstOrCreateEncrypted(['name' => 'House', 'user_id' => $this->user->id]);
     $budget = Budget::firstOrCreateEncrypted(['name' => 'Bills', 'user_id' => $this->user->id]);
     $journal = TransactionJournal::create(['user_id' => $this->user->id, 'transaction_type_id' => 1, 'transaction_currency_id' => 1, 'description' => $description, 'completed' => 1, 'date' => $date]);
     Transaction::create(['account_id' => $fromAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $amount * -1]);
     Transaction::create(['account_id' => $toAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $amount]);
     $journal->categories()->save($category);
     $journal->budgets()->save($budget);
     return $journal;
 }
 /**
  * @covers FireflyIII\Repositories\Bill\BillRepository::scan
  * @covers FireflyIII\Repositories\Bill\BillRepository::doWordMatch
  * @covers FireflyIII\Repositories\Bill\BillRepository::doAmountMatch
  */
 public function testScanNoMatchButAttached()
 {
     $bill = FactoryMuffin::create('FireflyIII\\Models\\Bill');
     $bill->date = new Carbon('2012-01-07');
     $bill->match = 'blablabla';
     $bill->repeat_freq = 'monthly';
     $bill->save();
     $this->be($bill->user);
     // journal:
     $journal = FactoryMuffin::create('FireflyIII\\Models\\TransactionJournal');
     $journal->date = Carbon::now()->format('Y-m-d');
     $journal->user_id = $bill->user_id;
     $journal->bill_id = $bill->id;
     $journal->save();
     // two transactions:
     $account1 = FactoryMuffin::create('FireflyIII\\Models\\Account');
     $account2 = FactoryMuffin::create('FireflyIII\\Models\\Account');
     Transaction::create(['account_id' => $account1->id, 'transaction_journal_id' => $journal->id, 'amount' => 100]);
     Transaction::create(['account_id' => $account2->id, 'transaction_journal_id' => $journal->id, 'amount' => 100]);
     $this->object->scan($bill, $journal);
     $newJournal = TransactionJournal::find($journal->id);
     $this->assertNull($newJournal->bill_id);
 }
Exemple #7
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
  * @param Account $opposing
  * @param array   $data
  *
  * @return TransactionJournal
  */
 protected function storeInitialBalance(Account $account, Account $opposing, array $data)
 {
     $transactionType = TransactionType::whereType('Opening balance')->first();
     $journal = TransactionJournal::create(['user_id' => $data['user'], 'transaction_type_id' => $transactionType->id, 'bill_id' => null, 'transaction_currency_id' => $data['openingBalanceCurrency'], 'description' => 'Initial balance for "' . $account->name . '"', 'completed' => true, 'date' => $data['openingBalanceDate'], 'encrypted' => true]);
     if ($data['openingBalance'] < 0) {
         $firstAccount = $opposing;
         $secondAccount = $account;
         $firstAmount = $data['openingBalance'] * -1;
         $secondAmount = $data['openingBalance'];
     } else {
         $firstAccount = $account;
         $secondAccount = $opposing;
         $firstAmount = $data['openingBalance'];
         $secondAmount = $data['openingBalance'] * -1;
     }
     $one = new Transaction(['account_id' => $firstAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $firstAmount]);
     $one->save();
     // first transaction: from
     $two = new Transaction(['account_id' => $secondAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $secondAmount]);
     $two->save();
     // second transaction: to
     return $journal;
 }
Exemple #9
0
 /**
  *
  * @return TransactionJournal|string
  */
 protected function createTransactionJournal()
 {
     bcscale(2);
     $date = $this->importData['date'];
     if (is_null($this->importData['date'])) {
         $date = $this->importData['date-rent'];
     }
     $transactionType = $this->getTransactionType();
     // defaults to deposit
     $errors = new MessageBag();
     $journal = TransactionJournal::create(['user_id' => Auth::user()->id, 'transaction_type_id' => $transactionType->id, 'transaction_currency_id' => $this->importData['currency']->id, 'description' => $this->importData['description'], 'completed' => 0, 'date' => $date, 'bill_id' => $this->importData['bill-id']]);
     if ($journal->getErrors()->count() == 0) {
         // first transaction
         $accountId = $this->importData['asset-account-object']->id;
         // create first transaction:
         $amount = $this->importData['amount'];
         $transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]);
         $errors = $transaction->getErrors();
         // second transaction
         $accountId = $this->importData['opposing-account-object']->id;
         // create second transaction:
         $amount = bcmul($this->importData['amount'], -1);
         $transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]);
         $errors = $transaction->getErrors()->merge($errors);
     }
     if ($errors->count() == 0) {
         $journal->completed = 1;
         $journal->save();
     } else {
         $text = join(',', $errors->all());
         return $text;
     }
     $this->saveBudget($journal);
     $this->saveCategory($journal);
     $this->saveTags($journal);
     // some debug info:
     $journalId = $journal->id;
     $type = $journal->getTransactionType();
     /** @var Account $asset */
     $asset = $this->importData['asset-account-object'];
     /** @var Account $opposing */
     $opposing = $this->importData['opposing-account-object'];
     Log::info('Created journal #' . $journalId . ' of type ' . $type . '!');
     Log::info('Asset account ****** (#' . $asset->id . ') lost/gained: ' . $this->importData['amount']);
     Log::info($opposing->accountType->type . ' ****** (#' . $opposing->id . ') lost/gained: ' . bcmul($this->importData['amount'], -1));
     return $journal;
 }
 /**
  * @param int         $index
  * @param ImportEntry $entry
  *
  * @return TransactionJournal
  * @throws FireflyException
  */
 private function storeSingle(int $index, ImportEntry $entry) : TransactionJournal
 {
     if ($entry->valid === false) {
         Log::warning(sprintf('Cannot import row %d, because the entry is not valid.', $index));
         $errors = join(', ', $entry->errors->all());
         $errorText = sprintf('Row #%d: ' . $errors, $index);
         $extendedStatus = $this->job->extended_status;
         $extendedStatus['errors'][] = $errorText;
         $this->job->extended_status = $extendedStatus;
         $this->job->save();
         return new TransactionJournal();
     }
     $alreadyImported = $this->alreadyImported($entry->hash);
     if (!is_null($alreadyImported->id)) {
         Log::warning(sprintf('Cannot import row %d, because it has already been imported (journal #%d).', $index, $alreadyImported->id));
         $errorText = trans('firefly.import_double', ['row' => $index, 'link' => route('transactions.show', [$alreadyImported->id]), 'description' => $alreadyImported->description]);
         $extendedStatus = $this->job->extended_status;
         $extendedStatus['errors'][] = $errorText;
         $this->job->extended_status = $extendedStatus;
         $this->job->save();
         return new TransactionJournal();
     }
     Log::debug(sprintf('Going to store row %d', $index));
     $journal = $this->storeJournal($entry);
     $amount = $this->makePositive($entry->fields['amount']);
     $accounts = $this->storeAccounts($entry);
     // create new transactions. This is something that needs a rewrite for multiple/split transactions.
     $sourceData = ['account_id' => $accounts['source']->id, 'transaction_journal_id' => $journal->id, 'description' => $journal->description, 'amount' => bcmul($amount, '-1')];
     $destinationData = ['account_id' => $accounts['destination']->id, 'transaction_journal_id' => $journal->id, 'description' => $journal->description, 'amount' => $amount];
     $one = Transaction::create($sourceData);
     $two = Transaction::create($destinationData);
     $error = false;
     if (is_null($one->id)) {
         Log::error('Could not create transaction 1.', $one->getErrors()->all());
         $error = true;
     }
     if (is_null($two->id)) {
         Log::error('Could not create transaction 1.', $two->getErrors()->all());
         $error = true;
     }
     // respond to error
     if ($error === true) {
         $errorText = sprintf('Cannot import row %d, because an error occured when storing data.', $index);
         Log::error($errorText);
         $extendedStatus = $this->job->extended_status;
         $extendedStatus['errors'][] = $errorText;
         $this->job->extended_status = $extendedStatus;
         $this->job->save();
         return new TransactionJournal();
     }
     Log::debug('Created transaction 1', ['id' => $one->id, 'account' => $one->account_id, 'account_name' => $accounts['source']->name]);
     Log::debug('Created transaction 2', ['id' => $two->id, 'account' => $two->account_id, 'account_name' => $accounts['destination']->name]);
     $journal->completed = 1;
     $journal->save();
     // attach import tag.
     $journal->tags()->save($this->importTag);
     // now attach budget and so on.
     $this->storeBudget($journal, $entry);
     $this->storeCategory($journal, $entry);
     $this->storeBill($journal, $entry);
     return $journal;
 }
 /**
  * @param array $data
  *
  * @return TransactionJournal
  */
 public function store(array $data) : TransactionJournal
 {
     // find transaction type.
     $transactionType = TransactionType::where('type', ucfirst($data['what']))->first();
     // store actual journal.
     $journal = new TransactionJournal(['user_id' => $data['user'], 'transaction_type_id' => $transactionType->id, 'transaction_currency_id' => $data['amount_currency_id_amount'], 'description' => $data['description'], 'completed' => 0, 'date' => $data['date'], 'interest_date' => $data['interest_date'], 'book_date' => $data['book_date'], 'process_date' => $data['process_date']]);
     $journal->save();
     // store or get category
     if (strlen($data['category']) > 0) {
         $category = Category::firstOrCreateEncrypted(['name' => $data['category'], 'user_id' => $data['user']]);
         $journal->categories()->save($category);
     }
     // store or get budget
     if (intval($data['budget_id']) > 0 && $transactionType->type !== TransactionType::TRANSFER) {
         /** @var \FireflyIII\Models\Budget $budget */
         $budget = Budget::find($data['budget_id']);
         $journal->budgets()->save($budget);
     }
     // store accounts (depends on type)
     list($sourceAccount, $destinationAccount) = $this->storeAccounts($transactionType, $data);
     // store accompanying transactions.
     Transaction::create(['account_id' => $sourceAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $data['amount'] * -1]);
     Transaction::create(['account_id' => $destinationAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $data['amount']]);
     $journal->completed = 1;
     $journal->save();
     // store tags
     if (isset($data['tags']) && is_array($data['tags'])) {
         $this->saveTags($journal, $data['tags']);
     }
     foreach ($data as $key => $value) {
         if (in_array($key, $this->validMetaFields)) {
             $journal->setMeta($key, $value);
             continue;
         }
         Log::debug(sprintf('Could not store meta field "%s" with value "%s" for journal #%d', json_encode($key), json_encode($value), $journal->id));
     }
     return $journal;
 }
 /**
  * Reports on deleted transactions that are connected to a not deleted journal.
  */
 private function reportTransactions()
 {
     $set = Transaction::leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')->whereNotNull('transactions.deleted_at')->whereNull('transaction_journals.deleted_at')->get(['transactions.id as transaction_id', 'transactions.deleted_at as transaction_deleted', 'transaction_journals.id as journal_id', 'transaction_journals.deleted_at']);
     /** @var stdClass $entry */
     foreach ($set as $entry) {
         $this->error('Error: Transaction journal #' . $entry->journal_id . ' should have been deleted, but has not.' . ' Find it in the table called `transaction_journals` and change the `deleted_at` field to: "' . $entry->transaction_deleted . '"');
     }
 }
 /**
  * @param array $data
  *
  * @return TransactionJournal
  */
 public function store(array $data)
 {
     // find transaction type.
     $transactionType = TransactionType::where('type', ucfirst($data['what']))->first();
     // store actual journal.
     $journal = new TransactionJournal(['user_id' => $data['user'], 'transaction_type_id' => $transactionType->id, 'transaction_currency_id' => $data['amount_currency_id'], 'description' => $data['description'], 'completed' => 0, 'date' => $data['date']]);
     $journal->save();
     // store or get category
     if (strlen($data['category']) > 0) {
         $category = Category::firstOrCreateEncrypted(['name' => $data['category'], 'user_id' => $data['user']]);
         $journal->categories()->save($category);
     }
     // store or get budget
     if (intval($data['budget_id']) > 0) {
         /** @var \FireflyIII\Models\Budget $budget */
         $budget = Budget::find($data['budget_id']);
         $journal->budgets()->save($budget);
     }
     // store accounts (depends on type)
     list($from, $to) = $this->storeAccounts($transactionType, $data);
     // store accompanying transactions.
     Transaction::create(['account_id' => $from->id, 'transaction_journal_id' => $journal->id, 'amount' => $data['amount'] * -1]);
     Transaction::create(['account_id' => $to->id, 'transaction_journal_id' => $journal->id, 'amount' => $data['amount']]);
     $journal->completed = 1;
     $journal->save();
     // store tags
     if (isset($data['tags']) && is_array($data['tags'])) {
         $this->saveTags($journal, $data['tags']);
     }
     return $journal;
 }
Exemple #14
0
    return $email;
}, 'password' => bcrypt('james')]);
FactoryMuffin::define('FireflyIII\\Models\\Transaction', ['transaction_journal_id' => 'factory|FireflyIII\\Models\\TransactionJournal', 'amount' => function () {
    return rand(1, 100);
}, 'description' => 'sentence', 'account_id' => 'factory|FireflyIII\\Models\\Account']);
FactoryMuffin::define('FireflyIII\\Models\\PiggyBank', ['account_id' => 'factory|FireflyIII\\Models\\Account', 'name' => 'sentence', 'targetamount' => function () {
    return rand(1, 100);
}, 'startdate' => 'date', 'targetdate' => 'date', 'remind_me' => false, 'reminder_skip' => 0, 'order' => 0]);
FactoryMuffin::define('FireflyIII\\Models\\PiggyBankRepetition', ['piggy_bank_id' => 'factory|FireflyIII\\Models\\PiggyBank', 'startdate' => 'date', 'targetdate' => 'date', 'currentamount' => function () {
    return rand(1, 100);
}]);
FactoryMuffin::define('FireflyIII\\Models\\PiggyBankEvent', ['piggy_bank_id' => 'factory|FireflyIII\\Models\\PiggyBank', 'transaction_journal_id' => 'factory|FireflyIII\\Models\\TransactionJournal', 'date' => 'date', 'amount' => function () {
    return rand(1, 100);
}]);
FactoryMuffin::define('FireflyIII\\Models\\TransactionType', ['type' => function () {
    $types = ['Withdrawal', 'Deposit', 'Transfer'];
    $count = DB::table('transaction_types')->count();
    if ($count < 3) {
        return $types[$count];
    } else {
        return RandomString::generateRandomString(10);
    }
}]);
FactoryMuffin::define('FireflyIII\\Models\\TransactionJournal', ['user_id' => 'factory|FireflyIII\\User', 'transaction_type_id' => 'factory|FireflyIII\\Models\\TransactionType', 'transaction_currency_id' => 'factory|FireflyIII\\Models\\TransactionCurrency', 'description' => 'sentence', 'completed' => '1', 'date' => 'date', 'encrypted' => '1', 'order' => '0'], function (TransactionJournal $object, $saved) {
    if ($saved) {
        $one = FactoryMuffin::create('FireflyIII\\Models\\Account');
        $two = FactoryMuffin::create('FireflyIII\\Models\\Account');
        Transaction::create(['account_id' => $one->id, 'transaction_journal_id' => $object->id, 'amount' => 100]);
        Transaction::create(['account_id' => $two->id, 'transaction_journal_id' => $object->id, 'amount' => -100]);
    }
});
 /**
  * @covers FireflyIII\Repositories\Journal\JournalRepository::update
  * @covers FireflyIII\Repositories\Journal\JournalRepository::updateTags
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 public function testUpdateNoTags()
 {
     $user = FactoryMuffin::create('FireflyIII\\User');
     $this->be($user);
     for ($i = 0; $i < 4; $i++) {
         FactoryMuffin::create('FireflyIII\\Models\\AccountType');
     }
     FactoryMuffin::create('FireflyIII\\Models\\TransactionType');
     FactoryMuffin::create('FireflyIII\\Models\\TransactionType');
     $journal = FactoryMuffin::create('FireflyIII\\Models\\TransactionJournal');
     $currency = FactoryMuffin::create('FireflyIII\\Models\\TransactionCurrency');
     $budget = FactoryMuffin::create('FireflyIII\\Models\\Budget');
     $account1 = FactoryMuffin::create('FireflyIII\\Models\\Account');
     $account2 = FactoryMuffin::create('FireflyIII\\Models\\Account');
     // two transactions
     Transaction::create(['account_id' => $account1->id, 'transaction_journal_id' => $journal->id, 'amount' => 100]);
     Transaction::create(['account_id' => $account1->id, 'transaction_journal_id' => $journal->id, 'amount' => -100]);
     $data = ['amount_currency_id' => $currency->id, 'description' => 'New description ' . rand(1, 100), 'date' => '2015-01-01', 'category' => 'SomenewCat', 'amount' => 50, 'user' => $journal->user_id, 'budget_id' => $budget->id, 'account_from_id' => $account1->id, 'account_to_id' => $account2->id, 'revenue_account' => 'Some revenue account', 'expense_account' => 'Some expense account', 'tags' => []];
     $result = $this->object->update($journal, $data);
     $this->assertEquals($result->description, $data['description']);
     $this->assertEquals($result->amount, 50);
 }
 /**
  * @param Account $account
  * @param array   $data
  *
  * @return TransactionJournal
  */
 protected function storeInitialBalance(Account $account, array $data) : TransactionJournal
 {
     $amount = $data['openingBalance'];
     $user = $data['user'];
     $name = $data['name'];
     $opposing = $this->storeOpposingAccount($amount, $user, $name);
     $transactionType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
     $journal = TransactionJournal::create(['user_id' => $data['user'], 'transaction_type_id' => $transactionType->id, 'transaction_currency_id' => $data['openingBalanceCurrency'], 'description' => 'Initial balance for "' . $account->name . '"', 'completed' => true, 'date' => $data['openingBalanceDate'], 'encrypted' => true]);
     $firstAccount = $account;
     $secondAccount = $opposing;
     $firstAmount = $amount;
     $secondAmount = $amount * -1;
     if ($data['openingBalance'] < 0) {
         $firstAccount = $opposing;
         $secondAccount = $account;
         $firstAmount = $amount * -1;
         $secondAmount = $amount;
     }
     $one = new Transaction(['account_id' => $firstAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $firstAmount]);
     $one->save();
     // first transaction: from
     $two = new Transaction(['account_id' => $secondAccount->id, 'transaction_journal_id' => $journal->id, 'amount' => $secondAmount]);
     $two->save();
     // second transaction: to
     return $journal;
 }