diff --git a/app/Crud/Split/Journal.php b/app/Crud/Split/Journal.php index 9315ba9193..bd0bfeb380 100644 --- a/app/Crud/Split/Journal.php +++ b/app/Crud/Split/Journal.php @@ -53,8 +53,8 @@ class Journal implements JournalInterface [ 'user_id' => $this->user->id, 'transaction_type_id' => $transactionType->id, - 'transaction_currency_id' => $data['currency_id'], - 'description' => $data['description'], + 'transaction_currency_id' => $data['journal_currency_id'], + 'description' => $data['journal_description'], 'completed' => 0, 'date' => $data['date'], 'interest_date' => $data['interest_date'], diff --git a/app/Http/Controllers/Transaction/SplitController.php b/app/Http/Controllers/Transaction/SplitController.php index 913cd6cf97..62870495d3 100644 --- a/app/Http/Controllers/Transaction/SplitController.php +++ b/app/Http/Controllers/Transaction/SplitController.php @@ -19,8 +19,10 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; +use Illuminate\Http\Request; use Log; use Session; +use View; /** * Class SplitController @@ -32,8 +34,31 @@ class SplitController extends Controller /** * */ - public function journalFromStore() + public function __construct() { + parent::__construct(); + View::share('mainTitleIcon', 'fa-share-alt'); + View::share('title', trans('firefly.split-transactions')); + } + + + /** + * @param Request $request + * + * @return mixed + * @throws FireflyException + */ + public function journalFromStore(Request $request) + { + if ($request->old('journal_currency_id')) { + $preFilled = $this->arrayFromOldData($request->old()); + } else { + $preFilled = $this->arrayFromSession(); + } + + Session::flash('preFilled', $preFilled); + View::share('subTitle', trans('firefly.split-new-transaction')); + /** @var CurrencyRepositoryInterface $currencyRepository */ $currencyRepository = app(CurrencyRepositoryInterface::class); /** @var AccountRepositoryInterface $accountRepository */ @@ -45,20 +70,16 @@ class SplitController extends Controller /** @var PiggyBankRepositoryInterface $piggyBankRepository */ $piggyBankRepository = app(PiggyBankRepositoryInterface::class); - // expect data to be in session or in post? - $journalData = session('temporary_split_data'); + $currencies = ExpandedForm::makeSelectList($currencyRepository->get()); $assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccounts(['Default account', 'Asset account'])); $budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets()); $piggyBanks = ExpandedForm::makeSelectListWithEmpty($piggyBankRepository->getPiggyBanks()); - if (!is_array($journalData)) { - throw new FireflyException('Could not find transaction data in your session. Please go back and try again.'); // translate me. - } - Log::debug('Journal data', $journalData); + //Session::flash('warning', 'This feature is very experimental. Beware.'); - return view('split.journals.from-store', compact('currencies', 'piggyBanks', 'assetAccounts', 'budgets'))->with('data', $journalData); + return view('split.journals.from-store', compact('currencies', 'piggyBanks', 'assetAccounts', 'budgets'))->with('data', $preFilled); } @@ -77,6 +98,9 @@ class SplitController extends Controller $journal = $repository->storeJournal($data); // Then, store each transaction individually. + if (is_null($journal->id)) { + throw new FireflyException('Could not store transaction.'); + } foreach ($data['transactions'] as $transaction) { $transactions = $repository->storeTransaction($journal, $transaction); } @@ -92,4 +116,74 @@ class SplitController extends Controller return redirect(session('transactions.create.url')); } + /** + * @param array $old + * + * @return array + */ + private function arrayFromOldData(array $old): array + { + // this array is pretty much equal to what we expect it to be. + Log::debug('Prefilled', $old); + + return $old; + } + + /** + * @return array + * @throws FireflyException + */ + private function arrayFromSession(): array + { + // expect data to be in session or in post? + $data = session('temporary_split_data'); + + if (!is_array($data)) { + Log::error('Could not find transaction data in your session. Please go back and try again.', ['data' => $data]); // translate me. + throw new FireflyException('Could not find transaction data in your session. Please go back and try again.'); // translate me. + } + + Log::debug('Journal data', $data); + + $preFilled = [ + 'what' => $data['what'], + 'journal_description' => $data['description'], + 'journal_source_account_id' => $data['source_account_id'], + 'journal_source_account_name' => $data['source_account_name'], + 'journal_destination_account_id' => $data['destination_account_id'], + 'journal_destination_account_name' => $data['destination_account_name'], + 'journal_amount' => $data['amount'], + 'journal_currency_id' => $data['amount_currency_id_amount'], + 'date' => $data['date'], + 'interest_date' => $data['interest_date'], + 'book_date' => $data['book_date'], + 'process_date' => $data['process_date'], + + 'description' => [], + 'destination_account_id' => [], + 'destination_account_name' => [], + 'amount' => [], + 'budget_id' => [], + 'category' => [], + 'piggy_bank_id' => [], + ]; + + // create the first transaction: + $preFilled['description'][] = $data['description']; + $preFilled['destination_account_id'][] = $data['destination_account_id']; + $preFilled['destination_account_name'][] = $data['destination_account_name']; + $preFilled['amount'][] = $data['amount']; + $preFilled['budget_id'][] = $data['budget_id']; + $preFilled['category'][] = $data['category']; + $preFilled['piggy_bank_id'][] = $data['piggy_bank_id']; + + // echo '
';
+ // var_dump($data);
+ // var_dump($preFilled);
+ // exit;
+ Log::debug('Prefilled', $preFilled);
+
+ return $preFilled;
+ }
+
}
\ No newline at end of file
diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php
index 9aefd01b86..71871aabaa 100644
--- a/app/Http/Controllers/TransactionController.php
+++ b/app/Http/Controllers/TransactionController.php
@@ -30,6 +30,7 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Illuminate\Support\Collection;
use Input;
+use Log;
use Preferences;
use Response;
use Session;
@@ -437,6 +438,7 @@ class TransactionController extends Controller
*/
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository, AttachmentHelperInterface $att)
{
+ Log::debug('Start of store.');
$doSplit = intval($request->get('split_journal')) === 1;
$journalData = $request->getJournalData();
if ($doSplit) {
@@ -445,6 +447,7 @@ class TransactionController extends Controller
return redirect(route('split.journal.from-store'));
}
+ Log::debug('Not in split.');
// if not withdrawal, unset budgetid.
if ($journalData['what'] != strtolower(TransactionType::WITHDRAWAL)) {
@@ -493,6 +496,8 @@ class TransactionController extends Controller
public function update(JournalFormRequest $request, JournalRepositoryInterface $repository, AttachmentHelperInterface $att, TransactionJournal $journal)
{
$journalData = $request->getJournalData();
+ Log::debug('Will update journal ', $journal->toArray());
+ Log::debug('Update related data ', $journalData);
$repository->update($journal, $journalData);
// save attachments:
diff --git a/app/Http/Requests/SplitJournalFormRequest.php b/app/Http/Requests/SplitJournalFormRequest.php
index aad2dd05ba..526fd30c45 100644
--- a/app/Http/Requests/SplitJournalFormRequest.php
+++ b/app/Http/Requests/SplitJournalFormRequest.php
@@ -35,26 +35,29 @@ class SplitJournalFormRequest extends Request
public function getSplitData(): array
{
$data = [
- 'description' => $this->get('journal_description'),
- 'currency_id' => intval($this->get('currency')),
- 'source_account_id' => intval($this->get('source_account_id')),
- 'source_account_name' => $this->get('source_account_name'),
- 'date' => new Carbon($this->get('date')),
- 'what' => $this->get('what'),
- 'interest_date' => $this->get('interest_date') ? new Carbon($this->get('interest_date')) : null,
- 'book_date' => $this->get('book_date') ? new Carbon($this->get('book_date')) : null,
- 'process_date' => $this->get('process_date') ? new Carbon($this->get('process_date')) : null,
- 'transactions' => [],
+ 'journal_description' => $this->get('journal_description'),
+ 'journal_currency_id' => intval($this->get('journal_currency_id')),
+ 'journal_source_account_id' => intval($this->get('journal_source_account_id')),
+ 'journal_source_account_name' => $this->get('journal_source_account_name'),
+ 'journal_destination_account_id' => intval($this->get('journal_source_destination_id')),
+ 'journal_destination_account_name' => $this->get('journal_source_destination_name'),
+ 'date' => new Carbon($this->get('date')),
+ 'what' => $this->get('what'),
+ 'interest_date' => $this->get('interest_date') ? new Carbon($this->get('interest_date')) : null,
+ 'book_date' => $this->get('book_date') ? new Carbon($this->get('book_date')) : null,
+ 'process_date' => $this->get('process_date') ? new Carbon($this->get('process_date')) : null,
+ 'transactions' => [],
];
+
// description is leading because it is one of the mandatory fields.
foreach ($this->get('description') as $index => $description) {
$transaction = [
'description' => $description,
'amount' => round($this->get('amount')[$index], 2),
- 'budget_id' => $this->get('budget')[$index] ? intval($this->get('budget')[$index]) : 0,
+ 'budget_id' => $this->get('budget_id')[$index] ? intval($this->get('budget_id')[$index]) : 0,
'category' => $this->get('category')[$index] ?? '',
- 'source_account_id' => intval($this->get('source_account_id')),
- 'source_account_name' => $this->get('source_account_name'),
+ 'source_account_id' => intval($this->get('journal_source_account_id')),
+ 'source_account_name' => $this->get('journal_source_account_name'),
'destination_account_id' => isset($this->get('destination_account_id')[$index])
? intval($this->get('destination_account_id')[$index])
: intval($this->get('destination_account_id')),
@@ -72,21 +75,23 @@ class SplitJournalFormRequest extends Request
public function rules(): array
{
return [
- 'journal_description' => 'required|between:1,255',
- 'currency' => 'required|exists:transaction_currencies,id',
- 'source_account_id' => 'numeric|belongsToUser:accounts,id',
- 'source_account_name.*' => 'between:1,255',
- 'what' => 'required|in:withdrawal,deposit,transfer',
- 'date' => 'required|date',
- 'interest_date' => 'date',
- 'book_date' => 'date',
- 'process_date' => 'date',
+ 'what' => 'required|in:withdrawal,deposit,transfer',
+ 'journal_description' => 'required|between:1,255',
+ 'journal_source_account_id' => 'numeric|belongsToUser:accounts,id',
+ 'journal_source_account_name.*' => 'between:1,255',
+ 'journal_currency_id' => 'required|exists:transaction_currencies,id',
+ 'date' => 'required|date',
+ 'interest_date' => 'date',
+ 'book_date' => 'date',
+ 'process_date' => 'date',
+
'description.*' => 'required|between:1,255',
'destination_account_id.*' => 'numeric|belongsToUser:accounts,id',
'destination_account_name.*' => 'between:1,255',
'amount.*' => 'required|numeric',
- 'budget.*' => 'belongsToUser:budgets,id',
+ 'budget_id.*' => 'belongsToUser:budgets,id',
'category.*' => 'between:1,255',
+ 'piggy_bank_id.*' => 'between:1,255',
];
}
}
\ No newline at end of file
diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php
index b6ed728650..6a16338f95 100644
--- a/app/Models/TransactionJournal.php
+++ b/app/Models/TransactionJournal.php
@@ -3,7 +3,6 @@
use Auth;
use Carbon\Carbon;
use Crypt;
-use DB;
use FireflyIII\Support\Models\TransactionJournalSupport;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\HasMany;
@@ -325,7 +324,6 @@ class TransactionJournal extends TransactionJournalSupport
*/
public function scopeExpanded(EloquentBuilder $query)
{
- $query->distinct();
// left join transaction type:
if (!self::isJoined($query, 'transaction_types')) {
$query->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
@@ -336,39 +334,12 @@ class TransactionJournal extends TransactionJournalSupport
// left join destination (for amount and account info).
$query->leftJoin(
- 'transactions as destination', function (JoinClause $join) {
- $join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('destination.amount', '>', 0);
+ 'transactions', function (JoinClause $join) {
+ $join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0);
}
);
- // join destination account
- $query->leftJoin('accounts as destination_account', 'destination_account.id', '=', 'destination.account_id');
- // join destination account type
- $query->leftJoin('account_types as destination_acct_type', 'destination_account.account_type_id', '=', 'destination_acct_type.id');
-
- // left join source (for amount and account info).
- $query->leftJoin(
- 'transactions as source', function (JoinClause $join) {
- $join->on('source.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('source.amount', '<', 0);
- }
- );
- // join destination account
- $query->leftJoin('accounts as source_account', 'source_account.id', '=', 'source.account_id');
- // join destination account type
- $query->leftJoin('account_types as source_acct_type', 'source_account.account_type_id', '=', 'source_acct_type.id')
- ->orderBy('transaction_journals.date', 'DESC')->orderBy('transaction_journals.order', 'ASC')->orderBy('transaction_journals.id', 'DESC');
-
- // something else:
- $query->where(DB::raw('`destination`.`amount` * -1'),'=',DB::raw('`source`.`amount`'));
-
- // group:
$query->groupBy('transaction_journals.id');
- $query->groupBy('source.id');
-
- $query->with(['categories', 'budgets', 'attachments', 'bill']);
-
-
+ $query->with(['categories', 'budgets', 'attachments', 'bill','transactions']);
}
/**
diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php
index 44d9bee43f..198c9bd9b6 100644
--- a/app/Repositories/Account/AccountRepository.php
+++ b/app/Repositories/Account/AccountRepository.php
@@ -15,6 +15,7 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasMany;
+use Illuminate\Database\Query\JoinClause;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Log;
@@ -232,23 +233,20 @@ class AccountRepository implements AccountRepositoryInterface
*/
public function getFrontpageTransactions(Account $account, Carbon $start, Carbon $end): Collection
{
- $set = $this->user
+ $query = $this->user
->transactionjournals()
->expanded()
- ->where('source_account.id', $account->id)
- // ->with(['transactions'])
- // ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- // ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')->where('accounts.id', $account->id)
- // ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transaction_journals.transaction_currency_id')
- // ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->before($end)
- ->after($start)
- // ->orderBy('transaction_journals.date', 'DESC')
- // ->orderBy('transaction_journals.order', 'ASC')
- // ->orderBy('transaction_journals.id', 'DESC')
- ->take(10)
- // ->get(['transaction_journals.*', 'transaction_currencies.symbol', 'transaction_types.type']);
- ->get(TransactionJournal::queryFields());
+ ->after($start);
+
+ // expand query:
+ $query->leftJoin(
+ 'transactions as source', function (JoinClause $join) {
+ $join->on('source.transaction_journal_id', '=', 'transaction_journals.id');
+ }
+ )->where('source.account_id', $account->id);
+
+ $set = $query->get(TransactionJournal::queryFields());
return $set;
}
@@ -290,13 +288,15 @@ class AccountRepository implements AccountRepositoryInterface
$offset = ($page - 1) * $pageSize;
$query = $this->user
->transactionJournals()
- ->expanded()
- ->where(
- function (Builder $q) use ($account) {
- $q->where('source_account.id', $account->id);
- $q->orWhere('destination_account.id', $account->id);
- }
- );
+ ->expanded();
+
+ // expand query:
+ $query->leftJoin(
+ 'transactions as source', function (JoinClause $join) {
+ $join->on('source.transaction_journal_id', '=', 'transaction_journals.id');
+ }
+ )->where('source.account_id', $account->id);
+
$count = $query->count();
$set = $query->take($pageSize)->offset($offset)->get(TransactionJournal::queryFields());
diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php
index 1e90caf829..c897a171f2 100644
--- a/app/Repositories/Budget/BudgetRepository.php
+++ b/app/Repositories/Budget/BudgetRepository.php
@@ -568,32 +568,9 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
public function getValidRepetitions(Budget $budget, Carbon $start, Carbon $end, LimitRepetition $ignore) : Collection
{
$query = $budget->limitrepetitions()
- ->where( // valid when either of these are true:
- function ($q) use ($start, $end) {
- $q->where(
- function ($query) use ($start, $end) {
- // starts before start time, and the end also after start time.
- $query->where('limit_repetitions.startdate', '<=', $start->format('Y-m-d 00:00:00'));
- $query->where('limit_repetitions.enddate', '>=', $start->format('Y-m-d 00:00:00'));
- }
- );
- $q->orWhere(
- function ($query) use ($start, $end) {
- // end after end time, and start is before end time
- $query->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00'));
- $query->where('limit_repetitions.enddate', '>=', $end->format('Y-m-d 00:00:00'));
- }
- );
- // start is after start and end is before end
- $q->orWhere(
- function ($query) use ($start, $end) {
- // end after end time, and start is before end time
- $query->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00'));
- $query->where('limit_repetitions.enddate', '<=', $end->format('Y-m-d 00:00:00'));
- }
- );
- }
- );
+ // starts before start time, and the end also after start time.
+ ->where('limit_repetitions.enddate', '>=', $start->format('Y-m-d 00:00:00'))
+ ->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00'));
if (!is_null($ignore->id)) {
$query->where('limit_repetitions.id', '!=', $ignore->id);
}
@@ -683,7 +660,7 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
}
)
->whereIn('transactions.account_id', $ids)
- ->having('transaction_count', '=', 1)
+ //->having('transaction_count', '=', 1) TODO check if this still works
->transactionTypes([TransactionType::WITHDRAWAL])
->first(
[
diff --git a/app/Repositories/Category/SingleCategoryRepository.php b/app/Repositories/Category/SingleCategoryRepository.php
index 3c6ba443ff..7918ceac72 100644
--- a/app/Repositories/Category/SingleCategoryRepository.php
+++ b/app/Repositories/Category/SingleCategoryRepository.php
@@ -10,6 +10,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Shared\ComponentRepository;
use FireflyIII\User;
+use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
/**
@@ -90,9 +91,16 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate
->after($start)
->groupBy('transaction_journals.date');
+ $query->leftJoin(
+ 'transactions as destination', function (JoinClause $join) {
+ $join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')->where('destination.amount', '>', 0);
+ }
+ );
+
+
if ($accounts->count() > 0) {
$ids = $accounts->pluck('id')->toArray();
- $query->whereIn('destination_account.id', $ids);
+ $query->whereIn('destination.account.id', $ids);
}
$result = $query->get(['transaction_journals.date as dateFormatted', DB::raw('SUM(`destination`.`amount`) AS `sum`')]);
@@ -258,13 +266,17 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate
->before($end)
->after($start)
->groupBy('transaction_journals.date');
+ $query->leftJoin(
+ 'transactions as source', function (JoinClause $join) {
+ $join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', 0);
+ }
+ );
if ($accounts->count() > 0) {
$ids = $accounts->pluck('id')->toArray();
- $query->whereIn('source_account.id', $ids);
+ $query->whereIn('source.account_id', $ids);
}
-
$result = $query->get(['transaction_journals.date as dateFormatted', DB::raw('SUM(`source`.`amount`) AS `sum`')]);
$return = [];
diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php
index b90617f5a5..617c87e9f8 100644
--- a/app/Repositories/Journal/JournalRepository.php
+++ b/app/Repositories/Journal/JournalRepository.php
@@ -336,31 +336,36 @@ class JournalRepository implements JournalRepositoryInterface
{
$sourceAccount = null;
$destinationAccount = null;
+ Log::debug('Now in storeAccounts()');
switch ($type->type) {
case TransactionType::WITHDRAWAL:
+ Log::debug('Now in storeAccounts()::withdrawal');
list($sourceAccount, $destinationAccount) = $this->storeWithdrawalAccounts($data);
break;
case TransactionType::DEPOSIT:
+ Log::debug('Now in storeAccounts()::deposit');
list($sourceAccount, $destinationAccount) = $this->storeDepositAccounts($data);
break;
case TransactionType::TRANSFER:
+ Log::debug('Now in storeAccounts()::transfer');
$sourceAccount = Account::where('user_id', $this->user->id)->where('id', $data['source_account_id'])->first();
$destinationAccount = Account::where('user_id', $this->user->id)->where('id', $data['destination_account_id'])->first();
break;
default:
throw new FireflyException('Did not recognise transaction type.');
}
+ Log::debug('Now in storeAccounts(), continued.');
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!');
+ Log::error('"destination"-account is null, so we cannot continue!', ['data' => $data]);
+ throw new FireflyException('"destination"-account is null, so we cannot continue!');
}
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!');
+ Log::error('"source"-account is null, so we cannot continue!', ['data' => $data]);
+ throw new FireflyException('"source"-account is null, so we cannot continue!');
}
@@ -402,8 +407,10 @@ class JournalRepository implements JournalRepositoryInterface
private function storeWithdrawalAccounts(array $data): array
{
$sourceAccount = Account::where('user_id', $this->user->id)->where('id', $data['source_account_id'])->first(['accounts.*']);
+ Log::debug('Now in storeWithdrawalAccounts() with ', ['name' => $data['destination_account_name'], 'len' => strlen($data['destination_account_name'])]);
if (strlen($data['destination_account_name']) > 0) {
+ Log::debug('Now in storeWithdrawalAccounts()');
$destinationType = AccountType::where('type', 'Expense account')->first();
$destinationAccount = Account::firstOrCreateEncrypted(
[
@@ -413,6 +420,7 @@ class JournalRepository implements JournalRepositoryInterface
'active' => 1,
]
);
+ Log::debug('Errors: ', ['err' => $destinationAccount->getErrors()->toArray(), 'id' => $destinationAccount->id]);
return [$sourceAccount, $destinationAccount];
}
diff --git a/app/Support/Migration/TestData.php b/app/Support/Migration/TestData.php
index c383da8e09..9a921e704d 100644
--- a/app/Support/Migration/TestData.php
+++ b/app/Support/Migration/TestData.php
@@ -367,7 +367,7 @@ class TestData
public static function createExpenseAccounts(User $user): bool
{
$expenses = ['Adobe', 'Google', 'Vitens', 'Albert Heijn', 'PLUS', 'Apple', 'Bakker', 'Belastingdienst', 'bol.com', 'Cafe Central', 'conrad.nl',
- 'Coolblue', 'Shell',
+ 'Coolblue', 'Shell', 'SixtyFive', 'EightyFour', 'Fiftyone',
'DUO', 'Etos', 'FEBO', 'Greenchoice', 'Halfords', 'XS4All', 'iCentre', 'Jumper', 'Land lord'];
foreach ($expenses as $name) {
// create account:
diff --git a/app/Support/Models/TransactionJournalSupport.php b/app/Support/Models/TransactionJournalSupport.php
index 71cea6ea8d..37e9a69603 100644
--- a/app/Support/Models/TransactionJournalSupport.php
+++ b/app/Support/Models/TransactionJournalSupport.php
@@ -56,8 +56,21 @@ class TransactionJournalSupport extends Model
return $journal->destination_amount;
}
- $amount = $journal->transactions()->where('amount', '>', 0)->get()->sum('amount');
- if ($journal->isDeposit()) {
+ // saves on queries:
+ $amount = '0';
+ if (count($journal->transactions) === 0) {
+ $amount = '0';
+ foreach ($journal->transactions as $t) {
+ if ($t->amount > 0) {
+ $amount = bcadd($amount, $t->amount);
+ }
+ }
+ }
+ if ($amount === '0') {
+ $amount = $journal->transactions()->where('amount', '>', 0)->get()->sum('amount');
+ }
+
+ if ($journal->isWithdrawal()) {
$amount = $amount * -1;
}
$amount = strval($amount);
@@ -234,19 +247,8 @@ class TransactionJournalSupport extends Model
'transaction_journals.*',
'transaction_types.type AS transaction_type_type', // the other field is called "transaction_type_id" so this is pretty consistent.
'transaction_currencies.code AS transaction_currency_code',
- // all for destination:
- //'destination.amount AS destination_amount', // is always positive
- DB::raw('SUM(`destination`.`amount`) as `destination_amount`'),
- 'destination_account.id AS destination_account_id',
- 'destination_account.name AS destination_account_name',
- 'destination_acct_type.type AS destination_account_type',
- // all for source:
- //'source.amount AS source_amount', // is always negative
- DB::raw('SUM(`source`.`amount`) as `source_amount`'),
- 'source_account.id AS source_account_id',
- 'source_account.name AS source_account_name',
- 'source_acct_type.type AS source_account_type',
- DB::raw('COUNT(`destination`.`id`) + COUNT(`source`.`id`) as `count_transactions`'),
+ DB::raw('SUM(`transactions`.`amount`) as `amount`'),
+ DB::raw('(COUNT(`transactions`.`id`) * 2) as `count_transactions`'),
];
}
diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php
index ba95ca1c4a..b7bb92b1bd 100644
--- a/app/Validation/FireflyValidator.php
+++ b/app/Validation/FireflyValidator.php
@@ -76,7 +76,9 @@ class FireflyValidator extends Validator
{
$field = $parameters[1] ?? 'id';
-
+ if (intval($value) === 0) {
+ return true;
+ }
$count = DB::table($parameters[0])->where('user_id', Auth::user()->id)->where($field, $value)->count();
if ($count === 1) {
return true;
diff --git a/config/app.php b/config/app.php
index 8ba2732c0d..0f9602b381 100644
--- a/config/app.php
+++ b/config/app.php
@@ -154,6 +154,7 @@ return [
/*
* More service providers.
*/
+ FireflyIII\Providers\CrudServiceProvider::class,
FireflyIII\Providers\AccountServiceProvider::class,
FireflyIII\Providers\AttachmentServiceProvider::class,
FireflyIII\Providers\BillServiceProvider::class,
diff --git a/database/seeds/SplitDataSeeder.php b/database/seeds/SplitDataSeeder.php
index 96c350e993..1e4c864b8e 100644
--- a/database/seeds/SplitDataSeeder.php
+++ b/database/seeds/SplitDataSeeder.php
@@ -90,7 +90,7 @@ class SplitDataSeeder extends Seeder
* Create splitted expense of 66,-
*/
$today = new Carbon;
- $today->subDays(6);
+ $today->subDays(2);
if (!$skipWithdrawal) {
$journal = TransactionJournal::create(
@@ -98,7 +98,7 @@ class SplitDataSeeder extends Seeder
'user_id' => $user->id,
'transaction_type_id' => 1, // withdrawal
'transaction_currency_id' => 1,
- 'description' => 'Split Expense (journal)',
+ 'description' => 'Split Even Expense (journal (50/50))',
'completed' => 1,
'date' => $today->format('Y-m-d'),
]
@@ -107,10 +107,11 @@ class SplitDataSeeder extends Seeder
// split in 6 transactions (multiple destinations). 22,- each
// source is TestData Checking Account.
// also attach some budgets and stuff.
- $destinations = ['Albert Heijn', 'PLUS', 'Apple'];
- $budgets = ['Groceries', 'Groceries', 'Car'];
- $categories = ['Bills', 'Bills', 'Car'];
- $source = TestData::findAccount($user, 'Checking Account');
+ $destinations = ['SixtyFive', 'EightyFour'];
+ $budgets = ['Groceries', 'Car'];
+ $categories = ['Bills', 'Bills'];
+ $amounts = [50, 50];
+ $source = TestData::findAccount($user, 'Alternate Checking Account');
foreach ($destinations as $index => $dest) {
$bud = $budgets[$index];
$cat = $categories[$index];
@@ -120,7 +121,7 @@ class SplitDataSeeder extends Seeder
[
'account_id' => $source->id,
'transaction_journal_id' => $journal->id,
- 'amount' => '-22',
+ 'amount' => $amounts[$index] * -1,
]
);
@@ -129,7 +130,7 @@ class SplitDataSeeder extends Seeder
[
'account_id' => $destination->id,
'transaction_journal_id' => $journal->id,
- 'amount' => '22',
+ 'amount' => $amounts[$index],
]
);
@@ -141,6 +142,57 @@ class SplitDataSeeder extends Seeder
$two->categories()->save(TestData::findCategory($user, $cat));
}
}
+ // AND ANOTHER ONE
+ $today->addDay();
+ $journal = TransactionJournal::create(
+ [
+ 'user_id' => $user->id,
+ 'transaction_type_id' => 1, // withdrawal
+ 'transaction_currency_id' => 1,
+ 'description' => 'Split Uneven Expense (journal (15/34/51=100))',
+ 'completed' => 1,
+ 'date' => $today->format('Y-m-d'),
+ ]
+ );
+
+ // split in 6 transactions (multiple destinations). 22,- each
+ // source is TestData Checking Account.
+ // also attach some budgets and stuff.
+ $destinations = ['SixtyFive', 'EightyFour', 'Fiftyone'];
+ $budgets = ['Groceries', 'Groceries', 'Car'];
+ $categories = ['Bills', 'Bills', 'Car'];
+ $amounts = [15, 34, 51];
+ $source = TestData::findAccount($user, 'Checking Account');
+ foreach ($destinations as $index => $dest) {
+ $bud = $budgets[$index];
+ $cat = $categories[$index];
+ $destination = TestData::findAccount($user, $dest);
+
+ $one = Transaction::create(
+ [
+ 'account_id' => $source->id,
+ 'transaction_journal_id' => $journal->id,
+ 'amount' => $amounts[$index] * -1,
+
+ ]
+ );
+
+ $two = Transaction::create(
+ [
+ 'account_id' => $destination->id,
+ 'transaction_journal_id' => $journal->id,
+ 'amount' => $amounts[$index],
+
+ ]
+ );
+
+ $one->budgets()->save(TestData::findBudget($user, $bud));
+ $two->budgets()->save(TestData::findBudget($user, $bud));
+
+ $one->categories()->save(TestData::findCategory($user, $cat));
+ $two->categories()->save(TestData::findCategory($user, $cat));
+ }
+
// create splitted income of 99,-
$today->addDay();
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000000..31ac89bcfe
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,31 @@
+
+
+
+
+ ./tests/
+
+
+
+
+ app/
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/split/journals/from-store.twig b/resources/views/split/journals/from-store.twig
index 6f41cde1be..10e1f88d5c 100644
--- a/resources/views/split/journals/from-store.twig
+++ b/resources/views/split/journals/from-store.twig
@@ -73,18 +73,18 @@
{% if data.what == 'withdrawal' or data.what == 'transfer' %}
- {{ ExpandedForm.staticText('asset_source_account', assetAccounts[data.journal_source_account_id]) }}
-
+ {{ ExpandedForm.staticText('journal_asset_source_account', assetAccounts[data.journal_source_account_id]) }}
+
{% endif %}
{% if data.what == 'deposit' %}
{{ ExpandedForm.staticText('revenue_account', data.journal_source_account_name) }}
-
+
{% endif %}
{% if data.what == 'transfer' %}
{{ ExpandedForm.staticText('asset_destination_account', assetAccounts[data.journal_destination_account_id]) }}
-
+
{% endif %}
diff --git a/tests/acceptance/Controllers/JsonControllerTest.php b/tests/acceptance/Controllers/JsonControllerTest.php
index 140660f5f3..27e86491b0 100644
--- a/tests/acceptance/Controllers/JsonControllerTest.php
+++ b/tests/acceptance/Controllers/JsonControllerTest.php
@@ -155,11 +155,9 @@ class JsonControllerTest extends TestCase
*/
public function testTransactionJournals($range)
{
- $type = factory(FireflyIII\Models\TransactionType::class)->make();
$repository = $this->mock('FireflyIII\Repositories\Journal\JournalRepositoryInterface');
-
- $repository->shouldReceive('getTransactionType')->with('deposit')->once()->andReturn($type);
- $repository->shouldReceive('getJournalsOfType')->with($type)->once()->andReturn(new Collection);
+ $paginator = new \Illuminate\Pagination\LengthAwarePaginator(new Collection, 0, 40);
+ $repository->shouldReceive('getJournals')->withAnyArgs()->once()->andReturn($paginator);
$this->be($this->user());
$this->changeDateRange($this->user(), $range);
diff --git a/tests/acceptance/Controllers/TransactionControllerTest.php b/tests/acceptance/Controllers/TransactionControllerTest.php
index 76223b68a5..a5ce3b5364 100644
--- a/tests/acceptance/Controllers/TransactionControllerTest.php
+++ b/tests/acceptance/Controllers/TransactionControllerTest.php
@@ -68,7 +68,7 @@ class TransactionControllerTest extends TestCase
public function testIndex($range)
{
$journals = $this->mock('FireflyIII\Repositories\Journal\JournalRepositoryInterface');
- $journals->shouldReceive('getJournalsOfTypes')->once()->andReturn(new LengthAwarePaginator([], 0, 50));
+ $journals->shouldReceive('getJournals')->once()->andReturn(new LengthAwarePaginator([], 0, 50));
$this->be($this->user());
$this->changeDateRange($this->user(), $range);
@@ -117,8 +117,8 @@ class TransactionControllerTest extends TestCase
$args = [
'what' => 'withdrawal',
'description' => 'Something',
- 'account_id' => '1',
- 'expense_account' => 'Some expense',
+ 'source_account_id' => '1',
+ 'destination_account_name' => 'Some expense',
'amount' => 100,
'amount_currency_id_amount' => 1,
'date' => '2015-01-01',
@@ -141,10 +141,10 @@ class TransactionControllerTest extends TestCase
$args = [
'what' => 'withdrawal',
- 'id' => 2,
+ 'id' => 4,
'description' => 'Something new',
- 'account_id' => '1',
- 'expense_account' => 'Some expense',
+ 'source_account_id' => '1',
+ 'destination_account_name' => 'Some expense account',
'amount' => 100,
'amount_currency_id_amount' => 1,
'date' => '2015-01-01',