mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Updates to transactions.
This commit is contained in:
64
app/Http/Controllers/Transaction/SplitController.php
Normal file
64
app/Http/Controllers/Transaction/SplitController.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* SplitController.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Http\Controllers\Transaction;
|
||||
|
||||
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||
|
||||
/**
|
||||
* Class SplitController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers\Transaction
|
||||
*/
|
||||
class SplitController extends Controller
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function journalFromStore()
|
||||
{
|
||||
/** @var CurrencyRepositoryInterface $currencyRepository */
|
||||
$currencyRepository = app(CurrencyRepositoryInterface::class);
|
||||
/** @var AccountRepositoryInterface $accountRepository */
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
|
||||
/** @var BudgetRepositoryInterface $budgetRepository */
|
||||
$budgetRepository = app(BudgetRepositoryInterface::class);
|
||||
|
||||
// expect data to be in session or in post?
|
||||
$journalData = session('temporary_split_data');
|
||||
$currency = $currencyRepository->find(intval($journalData['amount_currency_id_amount']));
|
||||
$assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccounts(['Default account', 'Asset account']));
|
||||
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
|
||||
if (!is_array($journalData)) {
|
||||
throw new FireflyException('Could not find transaction data in your session. Please go back and try again.'); // translate me.
|
||||
}
|
||||
// echo '<pre>';
|
||||
// var_dump($journalData);
|
||||
// echo '</pre>';
|
||||
// exit;
|
||||
|
||||
return view('split.journals.from-store', compact('currency', 'assetAccounts', 'budgets'))->with('data', $journalData);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function postJournalFromStore()
|
||||
{
|
||||
// forget temp journal data
|
||||
// Session::forget('temporary_split_data');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,28 +54,26 @@ class TransactionController extends Controller
|
||||
*/
|
||||
public function create(ARI $repository, string $what = TransactionType::DEPOSIT)
|
||||
{
|
||||
$what = strtolower($what);
|
||||
$maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
|
||||
$maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
|
||||
$uploadSize = min($maxFileSize, $maxPostSize);
|
||||
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account']));
|
||||
$budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get());
|
||||
$budgets[0] = trans('firefly.no_budget');
|
||||
$piggyBanks = Auth::user()->piggyBanks()->orderBy('order', 'ASC')->get();
|
||||
/** @var BudgetRepositoryInterface $budgetRepository */
|
||||
$budgetRepository = app(BudgetRepositoryInterface::class);
|
||||
|
||||
/** @var PiggyBankRepositoryInterface $piggyRepository */
|
||||
$piggyRepository = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
$what = strtolower($what);
|
||||
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
|
||||
$assetAccounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account']));
|
||||
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
|
||||
$piggyBanks = $piggyRepository->getPiggyBanks();
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($piggyBanks as $piggy) {
|
||||
$piggy->name = $piggy->name . ' (' . Amount::format($piggy->currentRelevantRep()->currentamount, false) . ')';
|
||||
}
|
||||
|
||||
$piggies = ExpandedForm::makeSelectList($piggyBanks);
|
||||
$piggies[0] = trans('form.noPiggybank');
|
||||
$preFilled = Session::has('preFilled') ? session('preFilled') : [];
|
||||
$respondTo = ['account_id', 'account_from_id'];
|
||||
$subTitle = trans('form.add_new_' . $what);
|
||||
$piggies = ExpandedForm::makeSelectListWithEmpty($piggyBanks);
|
||||
$preFilled = Session::has('preFilled') ? session('preFilled') : [];
|
||||
$subTitle = trans('form.add_new_' . $what);
|
||||
|
||||
foreach ($respondTo as $r) {
|
||||
$preFilled[$r] = Input::get($r);
|
||||
}
|
||||
Session::put('preFilled', $preFilled);
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
@@ -89,7 +87,7 @@ class TransactionController extends Controller
|
||||
asort($piggies);
|
||||
|
||||
|
||||
return view('transactions.create', compact('accounts', 'uploadSize', 'budgets', 'what', 'piggies', 'subTitle'));
|
||||
return view('transactions.create', compact('assetAccounts', 'uploadSize', 'budgets', 'what', 'piggies', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,7 +428,14 @@ class TransactionController extends Controller
|
||||
*/
|
||||
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository, AttachmentHelperInterface $att)
|
||||
{
|
||||
$doSplit = intval($request->get('split_journal')) === 1;
|
||||
$journalData = $request->getJournalData();
|
||||
if ($doSplit) {
|
||||
// put all journal data in the session and redirect to split routine.
|
||||
Session::put('temporary_split_data', $journalData);
|
||||
|
||||
return redirect(route('split.journal.from-store'));
|
||||
}
|
||||
|
||||
// if not withdrawal, unset budgetid.
|
||||
if ($journalData['what'] != strtolower(TransactionType::WITHDRAWAL)) {
|
||||
|
||||
@@ -37,11 +37,10 @@ class JournalFormRequest extends Request
|
||||
return [
|
||||
'what' => $this->get('what'),
|
||||
'description' => $this->get('description'),
|
||||
'account_id' => intval($this->get('account_id')),
|
||||
'account_from_id' => intval($this->get('account_from_id')),
|
||||
'account_to_id' => intval($this->get('account_to_id')),
|
||||
'expense_account' => $this->get('expense_account') ?? '',
|
||||
'revenue_account' => $this->get('revenue_account') ?? '',
|
||||
'source_account_id' => intval($this->get('source_account_id')),
|
||||
'source_account_name' => $this->get('source_account_name') ?? '',
|
||||
'account_destination_id' => intval($this->get('account_destination_id')),
|
||||
'destination_account_name' => $this->get('destination_account_name') ?? '',
|
||||
'amount' => round($this->get('amount'), 2),
|
||||
'user' => Auth::user()->id,
|
||||
'amount_currency_id_amount' => intval($this->get('amount_currency_id_amount')),
|
||||
@@ -70,28 +69,27 @@ class JournalFormRequest extends Request
|
||||
'process_date' => 'date',
|
||||
'book_date' => 'date',
|
||||
'interest_date' => 'date',
|
||||
'category' => 'between:1,255',
|
||||
'amount_currency_id_amount' => 'required|exists:transaction_currencies,id',
|
||||
|
||||
];
|
||||
|
||||
switch ($what) {
|
||||
case strtolower(TransactionType::WITHDRAWAL):
|
||||
$rules['account_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
|
||||
$rules['expense_account'] = 'between:1,255';
|
||||
$rules['category'] = 'between:1,255';
|
||||
$rules['source_account_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
|
||||
$rules['destination_account_name'] = 'between:1,255';
|
||||
if (intval(Input::get('budget_id')) != 0) {
|
||||
$rules['budget_id'] = 'exists:budgets,id|belongsToUser:budgets';
|
||||
}
|
||||
break;
|
||||
case strtolower(TransactionType::DEPOSIT):
|
||||
$rules['category'] = 'between:1,255';
|
||||
$rules['account_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
|
||||
$rules['revenue_account'] = 'between:1,255';
|
||||
$rules['source_account_name'] = 'between:1,255';
|
||||
$rules['destination_account_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
|
||||
break;
|
||||
case strtolower(TransactionType::TRANSFER):
|
||||
$rules['account_from_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:account_to_id';
|
||||
$rules['account_to_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:account_from_id';
|
||||
$rules['category'] = 'between:1,255';
|
||||
$rules['source_account_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:destination_account_id';
|
||||
$rules['destination_account_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:source_account_id';
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Cannot handle transaction type of type ' . e($what) . '.');
|
||||
|
||||
@@ -342,6 +342,11 @@ Route::group(
|
||||
*/
|
||||
Route::get('/search', ['uses' => 'SearchController@index', 'as' => 'search']);
|
||||
|
||||
/**
|
||||
* Split controller
|
||||
*/
|
||||
Route::get('/transaction/split', ['uses' => 'Transaction\SplitController@journalFromStore', 'as' => 'split.journal.from-store']);
|
||||
|
||||
/**
|
||||
* Tag Controller
|
||||
*/
|
||||
|
||||
@@ -248,19 +248,19 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
}
|
||||
|
||||
// store accounts (depends on type)
|
||||
list($fromAccount, $toAccount) = $this->storeAccounts($transactionType, $data);
|
||||
list($sourceAccount, $destinationAccount) = $this->storeAccounts($transactionType, $data);
|
||||
|
||||
// store accompanying transactions.
|
||||
Transaction::create( // first transaction.
|
||||
[
|
||||
'account_id' => $fromAccount->id,
|
||||
'account_id' => $sourceAccount->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => $data['amount'] * -1,
|
||||
]
|
||||
);
|
||||
Transaction::create( // second transaction.
|
||||
[
|
||||
'account_id' => $toAccount->id,
|
||||
'account_id' => $destinationAccount->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => $data['amount'],
|
||||
]
|
||||
@@ -391,38 +391,38 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
*/
|
||||
protected function storeAccounts(TransactionType $type, array $data): array
|
||||
{
|
||||
$fromAccount = null;
|
||||
$toAccount = null;
|
||||
$sourceAccount = null;
|
||||
$destinationAccount = null;
|
||||
switch ($type->type) {
|
||||
case TransactionType::WITHDRAWAL:
|
||||
list($fromAccount, $toAccount) = $this->storeWithdrawalAccounts($data);
|
||||
list($sourceAccount, $destinationAccount) = $this->storeWithdrawalAccounts($data);
|
||||
break;
|
||||
|
||||
case TransactionType::DEPOSIT:
|
||||
list($fromAccount, $toAccount) = $this->storeDepositAccounts($data);
|
||||
list($sourceAccount, $destinationAccount) = $this->storeDepositAccounts($data);
|
||||
|
||||
break;
|
||||
case TransactionType::TRANSFER:
|
||||
$fromAccount = Account::find($data['account_from_id']);
|
||||
$toAccount = Account::find($data['account_to_id']);
|
||||
$sourceAccount = Account::find($data['account_from_id']);
|
||||
$destinationAccount = Account::find($data['account_to_id']);
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Did not recognise transaction type.');
|
||||
}
|
||||
|
||||
if (is_null($toAccount)) {
|
||||
if (is_null($destinationAccount)) {
|
||||
Log::error('"to"-account is null, so we cannot continue!', ['data' => $data]);
|
||||
throw new FireflyException('"to"-account is null, so we cannot continue!');
|
||||
}
|
||||
|
||||
if (is_null($fromAccount)) {
|
||||
if (is_null($sourceAccount)) {
|
||||
Log::error('"from"-account is null, so we cannot continue!', ['data' => $data]);
|
||||
throw new FireflyException('"from"-account is null, so we cannot continue!');
|
||||
|
||||
}
|
||||
|
||||
|
||||
return [$fromAccount, $toAccount];
|
||||
return [$sourceAccount, $destinationAccount];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,21 +432,22 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
*/
|
||||
protected function storeDepositAccounts(array $data): array
|
||||
{
|
||||
$toAccount = Account::find($data['account_id']);
|
||||
$destinationAccount = Account::where('user_id', $this->user->id)->where('id', $data['account_destination_id'])->first(['accounts.*']);
|
||||
|
||||
if (strlen($data['revenue_account']) > 0) {
|
||||
if (strlen($data['source_account_name']) > 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]
|
||||
['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => $data['source_account_name'], 'active' => 1]
|
||||
);
|
||||
return [$fromAccount, $destinationAccount];
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$fromType = AccountType::where('type', 'Cash account')->first();
|
||||
$fromAccount = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]
|
||||
['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => 'Cash account', 'active' => 1]
|
||||
);
|
||||
}
|
||||
|
||||
return [$fromAccount, $toAccount];
|
||||
return [$fromAccount, $destinationAccount];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,20 +457,28 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
*/
|
||||
protected function storeWithdrawalAccounts(array $data): array
|
||||
{
|
||||
$fromAccount = Account::find($data['account_id']);
|
||||
$sourceAccount = Account::where('user_id', $this->user->id)->where('id', $data['source_account_id'])->first(['accounts.*']);
|
||||
|
||||
if (strlen($data['expense_account']) > 0) {
|
||||
$toType = AccountType::where('type', 'Expense account')->first();
|
||||
$toAccount = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => $data['expense_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$toAccount = Account::firstOrCreateEncrypted(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]
|
||||
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 [$fromAccount, $toAccount];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Amount as Amt;
|
||||
use Carbon\Carbon;
|
||||
use Eloquent;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
@@ -220,7 +221,7 @@ class ExpandedForm
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $set
|
||||
* @param \Illuminate\Support\Collection $set
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -443,6 +444,9 @@ class ExpandedForm
|
||||
} catch (RuntimeException $e) {
|
||||
// don't care about session errors.
|
||||
}
|
||||
if ($value instanceof Carbon) {
|
||||
$value = $value->format('Y-m-d');
|
||||
}
|
||||
|
||||
|
||||
return $value;
|
||||
|
||||
Reference in New Issue
Block a user