mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
More code for the split journal support.
This commit is contained in:
parent
e113736887
commit
495b80f5ef
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace FireflyIII\Crud\Split;
|
namespace FireflyIII\Crud\Split;
|
||||||
|
|
||||||
|
use FireflyIII\Events\TransactionStored;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\AccountType;
|
use FireflyIII\Models\AccountType;
|
||||||
@ -132,6 +133,13 @@ class Journal implements JournalInterface
|
|||||||
$two->budgets()->save($budget);
|
$two->budgets()->save($budget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($transaction['piggy_bank_id'] > 0) {
|
||||||
|
// add some extra meta information to the transaction data
|
||||||
|
$transaction['transaction_journal_id'] = $journal->id;
|
||||||
|
$transaction['date'] = $journal->date->format('Y-m-d');
|
||||||
|
event(new TransactionStored($transaction));
|
||||||
|
}
|
||||||
|
|
||||||
return new Collection([$one, $two]);
|
return new Collection([$one, $two]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
46
app/Events/TransactionStored.php
Normal file
46
app/Events/TransactionStored.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* TransactionStored.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
/**
|
||||||
|
* TransactionStored.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\Events;
|
||||||
|
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TransactionJournalStored
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Events
|
||||||
|
*/
|
||||||
|
class TransactionStored extends Event
|
||||||
|
{
|
||||||
|
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
public $transaction = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new event instance.
|
||||||
|
*
|
||||||
|
* @param array $transaction
|
||||||
|
*/
|
||||||
|
public function __construct(array $transaction)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
$this->transaction = $transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,6 +11,7 @@ declare(strict_types = 1);
|
|||||||
namespace FireflyIII\Export\Entry;
|
namespace FireflyIII\Export\Entry;
|
||||||
|
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To extend the exported object, in case of new features in Firefly III for example,
|
* To extend the exported object, in case of new features in Firefly III for example,
|
||||||
@ -45,8 +46,21 @@ class Entry
|
|||||||
public $description;
|
public $description;
|
||||||
/** @var EntryAccount */
|
/** @var EntryAccount */
|
||||||
public $destinationAccount;
|
public $destinationAccount;
|
||||||
|
/** @var Collection */
|
||||||
|
public $destinationAccounts;
|
||||||
/** @var EntryAccount */
|
/** @var EntryAccount */
|
||||||
public $sourceAccount;
|
public $sourceAccount;
|
||||||
|
/** @var Collection */
|
||||||
|
public $sourceAccounts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry constructor.
|
||||||
|
*/
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
$this->sourceAccounts = new Collection;
|
||||||
|
$this->destinationAccounts = new Collection;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionJournal $journal
|
* @param TransactionJournal $journal
|
||||||
@ -66,10 +80,18 @@ class Entry
|
|||||||
$entry->bill = new EntryBill($journal->bill);
|
$entry->bill = new EntryBill($journal->bill);
|
||||||
|
|
||||||
$sources = TransactionJournal::sourceAccountList($journal);
|
$sources = TransactionJournal::sourceAccountList($journal);
|
||||||
$entry->sourceAccount = new EntryAccount($sources->first());
|
|
||||||
$destinations = TransactionJournal::destinationAccountList($journal);
|
$destinations = TransactionJournal::destinationAccountList($journal);
|
||||||
|
$entry->sourceAccount = new EntryAccount($sources->first());
|
||||||
$entry->destinationAccount = new EntryAccount($destinations->first());
|
$entry->destinationAccount = new EntryAccount($destinations->first());
|
||||||
|
|
||||||
|
foreach ($sources as $source) {
|
||||||
|
$entry->sourceAccounts->push(new EntryAccount($source));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($destinations as $destination) {
|
||||||
|
$entry->destinationAccounts->push(new EntryAccount($destination));
|
||||||
|
}
|
||||||
|
|
||||||
return $entry;
|
return $entry;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ declare(strict_types = 1);
|
|||||||
namespace FireflyIII\Export\Exporter;
|
namespace FireflyIII\Export\Exporter;
|
||||||
|
|
||||||
use FireflyIII\Export\Entry\Entry;
|
use FireflyIII\Export\Entry\Entry;
|
||||||
|
use FireflyIII\Export\Entry\EntryAccount;
|
||||||
use FireflyIII\Models\ExportJob;
|
use FireflyIII\Models\ExportJob;
|
||||||
use League\Csv\Writer;
|
use League\Csv\Writer;
|
||||||
use SplFileObject;
|
use SplFileObject;
|
||||||
@ -61,19 +62,84 @@ class CsvExporter extends BasicExporter implements ExporterInterface
|
|||||||
// all rows:
|
// all rows:
|
||||||
$rows = [];
|
$rows = [];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count the maximum number of sources and destinations
|
||||||
|
* each entry has. May need to expand the number of export fields:
|
||||||
|
*/
|
||||||
|
$maxSourceAccounts = 1;
|
||||||
|
$maxDestinationAccounts = 1;
|
||||||
|
/** @var Entry $entry */
|
||||||
|
foreach ($this->getEntries() as $entry) {
|
||||||
|
$sources = $entry->sourceAccounts->count();
|
||||||
|
$destinations = $entry->destinationAccounts->count();
|
||||||
|
$maxSourceAccounts = max($maxSourceAccounts, $sources);
|
||||||
|
$maxDestinationAccounts = max($maxDestinationAccounts, $destinations);
|
||||||
|
}
|
||||||
|
|
||||||
// add header:
|
// add header:
|
||||||
$rows[] = array_keys(Entry::getFieldsAndTypes());
|
$rows[] = array_keys($this->getFieldsAndTypes($maxSourceAccounts, $maxDestinationAccounts));
|
||||||
|
|
||||||
// then the rest:
|
// then the rest:
|
||||||
/** @var Entry $entry */
|
/** @var Entry $entry */
|
||||||
foreach ($this->getEntries() as $entry) {
|
foreach ($this->getEntries() as $entry) {
|
||||||
// order is defined in Entry::getFieldsAndTypes.
|
// order is defined in Entry::getFieldsAndTypes.
|
||||||
$rows[] = [
|
$current = [
|
||||||
$entry->description, $entry->amount, $entry->date, $entry->sourceAccount->accountId, $entry->sourceAccount->name, $entry->sourceAccount->iban,
|
$entry->description,
|
||||||
$entry->sourceAccount->type, $entry->sourceAccount->number, $entry->destinationAccount->accountId, $entry->destinationAccount->name,
|
$entry->amount,
|
||||||
$entry->destinationAccount->iban, $entry->destinationAccount->type, $entry->destinationAccount->number, $entry->budget->budgetId,
|
$entry->date];
|
||||||
$entry->budget->name, $entry->category->categoryId, $entry->category->name, $entry->bill->billId, $entry->bill->name,
|
for ($i = 0; $i < $maxSourceAccounts; $i++) {
|
||||||
];
|
/** @var EntryAccount $source */
|
||||||
|
$source = $entry->sourceAccounts->get($i);
|
||||||
|
$currentId = '';
|
||||||
|
$currentName = '';
|
||||||
|
$currentIban = '';
|
||||||
|
$currentType = '';
|
||||||
|
$currentNumber = '';
|
||||||
|
if ($source) {
|
||||||
|
$currentId = $source->accountId;
|
||||||
|
$currentName = $source->name;
|
||||||
|
$currentIban = $source->iban;
|
||||||
|
$currentType = $source->type;
|
||||||
|
$currentNumber = $source->number;
|
||||||
|
}
|
||||||
|
$current[] = $currentId;
|
||||||
|
$current[] = $currentName;
|
||||||
|
$current[] = $currentIban;
|
||||||
|
$current[] = $currentType;
|
||||||
|
$current[] = $currentNumber;
|
||||||
|
}
|
||||||
|
unset($source);
|
||||||
|
for ($i = 0; $i < $maxDestinationAccounts; $i++) {
|
||||||
|
/** @var EntryAccount $destination */
|
||||||
|
$destination = $entry->destinationAccounts->get($i);
|
||||||
|
$currentId = '';
|
||||||
|
$currentName = '';
|
||||||
|
$currentIban = '';
|
||||||
|
$currentType = '';
|
||||||
|
$currentNumber = '';
|
||||||
|
if ($destination) {
|
||||||
|
$currentId = $destination->accountId;
|
||||||
|
$currentName = $destination->name;
|
||||||
|
$currentIban = $destination->iban;
|
||||||
|
$currentType = $destination->type;
|
||||||
|
$currentNumber = $destination->number;
|
||||||
|
}
|
||||||
|
$current[] = $currentId;
|
||||||
|
$current[] = $currentName;
|
||||||
|
$current[] = $currentIban;
|
||||||
|
$current[] = $currentType;
|
||||||
|
$current[] = $currentNumber;
|
||||||
|
}
|
||||||
|
unset($destination);
|
||||||
|
|
||||||
|
|
||||||
|
$current[] = $entry->budget->budgetId;
|
||||||
|
$current[] = $entry->budget->name;
|
||||||
|
$current[] = $entry->category->categoryId;
|
||||||
|
$current[] = $entry->category->name;
|
||||||
|
$current[] = $entry->bill->billId;
|
||||||
|
$current[] = $entry->bill->name;
|
||||||
|
$rows[] = $current;
|
||||||
|
|
||||||
}
|
}
|
||||||
$writer->insertAll($rows);
|
$writer->insertAll($rows);
|
||||||
@ -81,6 +147,43 @@ class CsvExporter extends BasicExporter implements ExporterInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getFieldsAndTypes(int $sources, int $destinations): array
|
||||||
|
{
|
||||||
|
// key = field name (see top of class)
|
||||||
|
// value = field type (see csv.php under 'roles')
|
||||||
|
$array = [
|
||||||
|
'description' => 'description',
|
||||||
|
'amount' => 'amount',
|
||||||
|
'date' => 'date-transaction',
|
||||||
|
];
|
||||||
|
for ($i = 0; $i < $sources; $i++) {
|
||||||
|
$array['source_account_' . $i . '_id'] = 'account-id';
|
||||||
|
$array['source_account_' . $i . '_name'] = 'account-name';
|
||||||
|
$array['source_account_' . $i . '_iban'] = 'account-iban';
|
||||||
|
$array['source_account_' . $i . '_type'] = '_ignore';
|
||||||
|
$array['source_account_' . $i . '_number'] = 'account-number';
|
||||||
|
}
|
||||||
|
for ($i = 0; $i < $destinations; $i++) {
|
||||||
|
$array['destination_account_' . $i . '_id'] = 'account-id';
|
||||||
|
$array['destination_account_' . $i . '_name'] = 'account-name';
|
||||||
|
$array['destination_account_' . $i . '_iban'] = 'account-iban';
|
||||||
|
$array['destination_account_' . $i . '_type'] = '_ignore';
|
||||||
|
$array['destination_account_' . $i . '_number'] = 'account-number';
|
||||||
|
}
|
||||||
|
|
||||||
|
$array['budget_id'] = 'budget-id';
|
||||||
|
$array['budget_name'] = 'budget-name';
|
||||||
|
$array['category_id'] = 'category-id';
|
||||||
|
$array['category_name'] = 'category-name';
|
||||||
|
$array['bill_id'] = 'bill-id';
|
||||||
|
$array['bill_name'] = 'bill-name';
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
private function tempFile()
|
private function tempFile()
|
||||||
{
|
{
|
||||||
$this->fileName = $this->job->key . '-records.csv';
|
$this->fileName = $this->job->key . '-records.csv';
|
||||||
|
68
app/Handlers/Events/ConnectTransactionToPiggyBank.php
Normal file
68
app/Handlers/Events/ConnectTransactionToPiggyBank.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* ConnectTransactionToPiggyBank.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Handlers\Events;
|
||||||
|
|
||||||
|
use FireflyIII\Events\TransactionJournalStored;
|
||||||
|
use FireflyIII\Events\TransactionStored;
|
||||||
|
use FireflyIII\Models\PiggyBankEvent;
|
||||||
|
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ConnectTransactionToPiggyBank
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Handlers\Events
|
||||||
|
*/
|
||||||
|
class ConnectTransactionToPiggyBank
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect a new transaction journal to any related piggy banks.
|
||||||
|
*
|
||||||
|
* @param TransactionStored $event
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function handle(TransactionStored $event): bool
|
||||||
|
{
|
||||||
|
echo '<pre>';
|
||||||
|
/** @var PiggyBankRepositoryInterface $repository */
|
||||||
|
$repository = app(PiggyBankRepositoryInterface::class);
|
||||||
|
$transaction = $event->transaction;
|
||||||
|
$piggyBank = $repository->find($transaction['piggy_bank_id']);
|
||||||
|
|
||||||
|
// valid piggy:
|
||||||
|
if (is_null($piggyBank->id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$amount = strval($transaction['amount']);
|
||||||
|
// piggy bank account something with amount:
|
||||||
|
if ($transaction['source_account_id'] == $piggyBank->account_id) {
|
||||||
|
// if the source of this transaction is the same as the piggy bank,
|
||||||
|
// the money is being removed from the piggy bank. So the
|
||||||
|
// amount must be negative:
|
||||||
|
$amount = bcmul($amount, '-1');
|
||||||
|
}
|
||||||
|
|
||||||
|
$repetition = $piggyBank->currentRelevantRep();
|
||||||
|
// add or remove the money from the piggy bank:
|
||||||
|
$newAmount = bcadd(strval($repetition->currentamount), $amount);
|
||||||
|
$repetition->currentamount = $newAmount;
|
||||||
|
$repetition->save();
|
||||||
|
|
||||||
|
// now generate a piggy bank event:
|
||||||
|
PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'date' => $transaction['date'], 'amount' => $newAmount]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -53,11 +53,13 @@ class SplitController extends Controller
|
|||||||
$accountRepository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
$accountRepository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
||||||
$currencyRepository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
|
$currencyRepository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
|
||||||
$budgetRepository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
|
$budgetRepository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
|
||||||
|
$piggyRepository = app('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface');
|
||||||
$assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccountsByType(['Default account', 'Asset account']));
|
$assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccountsByType(['Default account', 'Asset account']));
|
||||||
$sessionData = session('journal-data', []);
|
$sessionData = session('journal-data', []);
|
||||||
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
|
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
|
||||||
$currencies = ExpandedForm::makeSelectList($currencyRepository->get());
|
$currencies = ExpandedForm::makeSelectList($currencyRepository->get());
|
||||||
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
|
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
|
||||||
|
$piggyBanks = ExpandedForm::makeSelectListWithEmpty($piggyRepository->getPiggyBanksWithAmount());
|
||||||
$subTitle = trans('form.add_new_' . $sessionData['what']);
|
$subTitle = trans('form.add_new_' . $sessionData['what']);
|
||||||
$subTitleIcon = 'fa-plus';
|
$subTitleIcon = 'fa-plus';
|
||||||
$preFilled = [
|
$preFilled = [
|
||||||
@ -74,7 +76,8 @@ class SplitController extends Controller
|
|||||||
];
|
];
|
||||||
|
|
||||||
return view(
|
return view(
|
||||||
'split.journals.create', compact('journal', 'subTitle', 'subTitleIcon', 'preFilled', 'assetAccounts', 'currencies', 'budgets', 'uploadSize')
|
'split.journals.create',
|
||||||
|
compact('journal', 'piggyBanks', 'subTitle', 'subTitleIcon', 'preFilled', 'assetAccounts', 'currencies', 'budgets', 'uploadSize')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +128,6 @@ class SplitController extends Controller
|
|||||||
public function store(JournalInterface $repository, SplitJournalFormRequest $request, TransactionJournal $journal)
|
public function store(JournalInterface $repository, SplitJournalFormRequest $request, TransactionJournal $journal)
|
||||||
{
|
{
|
||||||
$data = $request->getSplitData();
|
$data = $request->getSplitData();
|
||||||
|
|
||||||
foreach ($data['transactions'] as $transaction) {
|
foreach ($data['transactions'] as $transaction) {
|
||||||
$repository->storeTransaction($journal, $transaction);
|
$repository->storeTransaction($journal, $transaction);
|
||||||
}
|
}
|
||||||
@ -245,7 +247,7 @@ class SplitController extends Controller
|
|||||||
$destinationName = $request->old('destination_account_name')[$index] ?? $transaction->account->name;
|
$destinationName = $request->old('destination_account_name')[$index] ?? $transaction->account->name;
|
||||||
|
|
||||||
// any transfer not from the source:
|
// any transfer not from the source:
|
||||||
if (($journal->isWithdrawal() || $journal->isDeposit()) && $transaction->account_id !== $sourceAccounts->first()->id) {
|
if ($transaction->account_id !== $sourceAccounts->first()->id) {
|
||||||
$array['description'][] = $description;
|
$array['description'][] = $description;
|
||||||
$array['destination_account_id'][] = $transaction->account_id;
|
$array['destination_account_id'][] = $transaction->account_id;
|
||||||
$array['destination_account_name'][] = $destinationName;
|
$array['destination_account_name'][] = $destinationName;
|
||||||
|
@ -59,6 +59,9 @@ class SplitJournalFormRequest extends Request
|
|||||||
'category' => $this->get('category')[$index] ?? '',
|
'category' => $this->get('category')[$index] ?? '',
|
||||||
'source_account_id' => intval($this->get('journal_source_account_id')),
|
'source_account_id' => intval($this->get('journal_source_account_id')),
|
||||||
'source_account_name' => $this->get('journal_source_account_name'),
|
'source_account_name' => $this->get('journal_source_account_name'),
|
||||||
|
'piggy_bank_id' => isset($this->get('piggy_bank_id')[$index])
|
||||||
|
? intval($this->get('piggy_bank_id')[$index])
|
||||||
|
: 0,
|
||||||
'destination_account_id' => isset($this->get('destination_account_id')[$index])
|
'destination_account_id' => isset($this->get('destination_account_id')[$index])
|
||||||
? intval($this->get('destination_account_id')[$index])
|
? intval($this->get('destination_account_id')[$index])
|
||||||
: intval($this->get('journal_destination_account_id')),
|
: intval($this->get('journal_destination_account_id')),
|
||||||
|
@ -30,12 +30,16 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
'FireflyIII\Handlers\Events\FireRulesForUpdate',
|
'FireflyIII\Handlers\Events\FireRulesForUpdate',
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
'FireflyIII\Events\BudgetLimitStored' => [
|
'FireflyIII\Events\BudgetLimitStored' => [
|
||||||
'FireflyIII\Handlers\Events\BudgetLimitEventHandler@store',
|
'FireflyIII\Handlers\Events\BudgetLimitEventHandler@store',
|
||||||
],
|
],
|
||||||
'FireflyIII\Events\BudgetLimitUpdated' => [
|
'FireflyIII\Events\BudgetLimitUpdated' => [
|
||||||
'FireflyIII\Handlers\Events\BudgetLimitEventHandler@update',
|
'FireflyIII\Handlers\Events\BudgetLimitEventHandler@update',
|
||||||
],
|
],
|
||||||
|
'FireflyIII\Events\TransactionStored' => [
|
||||||
|
'FireflyIII\Handlers\Events\ConnectTransactionToPiggyBank',
|
||||||
|
],
|
||||||
'FireflyIII\Events\TransactionJournalStored' => [
|
'FireflyIII\Events\TransactionJournalStored' => [
|
||||||
'FireflyIII\Handlers\Events\ScanForBillsAfterStore',
|
'FireflyIII\Handlers\Events\ScanForBillsAfterStore',
|
||||||
'FireflyIII\Handlers\Events\ConnectJournalToPiggyBank',
|
'FireflyIII\Handlers\Events\ConnectJournalToPiggyBank',
|
||||||
|
@ -18,6 +18,7 @@ use FireflyIII\Models\TransactionType;
|
|||||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||||
use FireflyIII\User;
|
use FireflyIII\User;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Query\JoinClause;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Log;
|
use Log;
|
||||||
@ -167,6 +168,18 @@ class JournalRepository implements JournalRepositoryInterface
|
|||||||
|
|
||||||
if ($accounts->count() > 0) {
|
if ($accounts->count() > 0) {
|
||||||
$ids = $accounts->pluck('id')->toArray();
|
$ids = $accounts->pluck('id')->toArray();
|
||||||
|
// join source and destination:
|
||||||
|
$query->leftJoin(
|
||||||
|
'transactions as source', function (JoinClause $join) {
|
||||||
|
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', 0);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$query->leftJoin(
|
||||||
|
'transactions as destination', function (JoinClause $join) {
|
||||||
|
$join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')->where('destination.amount', '>', 0);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$query->where(
|
$query->where(
|
||||||
function (Builder $q) use ($ids) {
|
function (Builder $q) use ($ids) {
|
||||||
$q->whereIn('destination.account_id', $ids);
|
$q->whereIn('destination.account_id', $ids);
|
||||||
|
@ -57,6 +57,21 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $piggyBankid
|
||||||
|
*
|
||||||
|
* @return PiggyBank
|
||||||
|
*/
|
||||||
|
public function find(int $piggyBankid): PiggyBank
|
||||||
|
{
|
||||||
|
$piggyBank = $this->user->piggyBanks()->where('piggy_banks.id', $piggyBankid)->first(['piggy_banks.*']);
|
||||||
|
if (!is_null($piggyBank)) {
|
||||||
|
return $piggyBank;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PiggyBank();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param PiggyBank $piggyBank
|
* @param PiggyBank $piggyBank
|
||||||
*
|
*
|
||||||
|
@ -34,6 +34,13 @@ interface PiggyBankRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function destroy(PiggyBank $piggyBank): bool;
|
public function destroy(PiggyBank $piggyBank): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $piggyBankid
|
||||||
|
*
|
||||||
|
* @return PiggyBank
|
||||||
|
*/
|
||||||
|
public function find(int $piggyBankid): PiggyBank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all events.
|
* Get all events.
|
||||||
*
|
*
|
||||||
|
@ -93,6 +93,9 @@
|
|||||||
<th>{{ trans('list.budget') }}</th>
|
<th>{{ trans('list.budget') }}</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<th>{{ trans('list.category') }}</th>
|
<th>{{ trans('list.category') }}</th>
|
||||||
|
{% if preFilled.what == 'transfer' %}
|
||||||
|
<th>{{ trans('list.piggy_bank') }}</th>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -139,6 +142,12 @@
|
|||||||
<td>
|
<td>
|
||||||
<input type="text" name="category[]" value="{{ preFilled.category[index] }}" class="form-control"/>
|
<input type="text" name="category[]" value="{{ preFilled.category[index] }}" class="form-control"/>
|
||||||
</td>
|
</td>
|
||||||
|
{% if preFilled.what == 'transfer' %}
|
||||||
|
<td>
|
||||||
|
<!-- RELATE THIS TRANSFER TO A PIGGY BANK -->
|
||||||
|
{{ Form.select('piggy_bank_id[]',piggyBanks, preFilled.piggy_bank_id[index], {class: 'form-control'}) }}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
301
storage/database/seed.split.json
Normal file
301
storage/database/seed.split.json
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
{
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"email": "thegrumpydictator@gmail.com",
|
||||||
|
"password": "james"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"role": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"accounts": [
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"account_type_id": 3,
|
||||||
|
"name": "Checking Account",
|
||||||
|
"iban": "NL11XOLA6707795988"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"account_type_id": 3,
|
||||||
|
"name": "Alternate",
|
||||||
|
"iban": "NL40UKBK3619908726"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"account_type_id": 4,
|
||||||
|
"name": "SixtyFive"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"account_type_id": 4,
|
||||||
|
"name": "EightyFour"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"account_type_id": 4,
|
||||||
|
"name": "Fiftyone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"account_type_id": 5,
|
||||||
|
"name": "Work SixtyFive"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"account_type_id": 5,
|
||||||
|
"name": "Work EightyFour"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"account_type_id": 5,
|
||||||
|
"name": "Work Fiftyone"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"account-meta": [
|
||||||
|
{
|
||||||
|
"account_id": 1,
|
||||||
|
"name": "accountRole",
|
||||||
|
"data": "\"defaultAsset\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"account_id": 2,
|
||||||
|
"name": "accountRole",
|
||||||
|
"data": "\"defaultAsset\""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bills": [],
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"name": "Groceries",
|
||||||
|
"user_id": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bills",
|
||||||
|
"user_id": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Car",
|
||||||
|
"user_id": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"budget-limits": [],
|
||||||
|
"monthly-limits": [
|
||||||
|
{
|
||||||
|
"budget_id": 1,
|
||||||
|
"amount_min": 200,
|
||||||
|
"amount_max": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"budget_id": 2,
|
||||||
|
"amount_min": 1000,
|
||||||
|
"amount_max": 1000
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"budget_id": 3,
|
||||||
|
"amount_min": 200,
|
||||||
|
"amount_max": 200
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"name": "Daily groceries",
|
||||||
|
"user_id": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Car",
|
||||||
|
"user_id": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Reimbursements",
|
||||||
|
"user_id": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"piggy-banks": [
|
||||||
|
{
|
||||||
|
"account_id": 2,
|
||||||
|
"name": "New camera",
|
||||||
|
"targetamount": 1000,
|
||||||
|
"startdate": "2015-04-01",
|
||||||
|
"reminder_skip": 0,
|
||||||
|
"remind_me": 0,
|
||||||
|
"order": 1,
|
||||||
|
"currentamount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"account_id": 2,
|
||||||
|
"name": "New phone",
|
||||||
|
"targetamount": 600,
|
||||||
|
"startdate": "2015-04-01",
|
||||||
|
"reminder_skip": 0,
|
||||||
|
"remind_me": 0,
|
||||||
|
"order": 2,
|
||||||
|
"currentamount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"account_id": 2,
|
||||||
|
"name": "New couch",
|
||||||
|
"targetamount": 500,
|
||||||
|
"startdate": "2015-04-01",
|
||||||
|
"reminder_skip": 0,
|
||||||
|
"remind_me": 0,
|
||||||
|
"order": 3,
|
||||||
|
"currentamount": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"piggy-events": [],
|
||||||
|
"rule-groups": [],
|
||||||
|
"rules": [],
|
||||||
|
"rule-triggers": [],
|
||||||
|
"rule-actions": [],
|
||||||
|
"tags": [],
|
||||||
|
"monthly-deposits": [],
|
||||||
|
"monthly-transfers": [],
|
||||||
|
"monthly-withdrawals": [],
|
||||||
|
"attachments": [],
|
||||||
|
"multi-withdrawals": [
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"date": "2016-03-12",
|
||||||
|
"description": "Even multi-withdrawal (50, 50)",
|
||||||
|
"destination_ids": [
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"source_id": 1,
|
||||||
|
"amounts": [
|
||||||
|
50,
|
||||||
|
50
|
||||||
|
],
|
||||||
|
"category_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"budget_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"date": "2016-05-12",
|
||||||
|
"description": "Uneven multi-withdrawal (15,34,51)",
|
||||||
|
"destination_ids": [
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5
|
||||||
|
],
|
||||||
|
"source_id": 1,
|
||||||
|
"amounts": [
|
||||||
|
14,
|
||||||
|
35,
|
||||||
|
51
|
||||||
|
],
|
||||||
|
"category_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"budget_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"multi-deposits": [
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"date": "2016-03-02",
|
||||||
|
"description": "Even multi-deposit (50, 50)",
|
||||||
|
"source_ids": [
|
||||||
|
6,
|
||||||
|
7
|
||||||
|
],
|
||||||
|
"destination_id": 1,
|
||||||
|
"amounts": [
|
||||||
|
50,
|
||||||
|
50
|
||||||
|
],
|
||||||
|
"category_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"date": "2016-05-02",
|
||||||
|
"description": "Uneven multi-deposit (15,34,51)",
|
||||||
|
"source_ids": [
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"destination_id": 1,
|
||||||
|
"amounts": [
|
||||||
|
14,
|
||||||
|
35,
|
||||||
|
51
|
||||||
|
],
|
||||||
|
"category_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"multi-transfers": [
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"date": "2016-01-18",
|
||||||
|
"description": "Even multi-transfer (50, 50)",
|
||||||
|
"source_ids": [
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"destination_ids": [
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"amounts": [
|
||||||
|
50,
|
||||||
|
50
|
||||||
|
],
|
||||||
|
"category_ids": [
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id": 1,
|
||||||
|
"date": "2016-03-28",
|
||||||
|
"description": "Uneven multi-transfer (15,34,51)",
|
||||||
|
"source_ids": [
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"destination_ids": [
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"amounts": [
|
||||||
|
14,
|
||||||
|
35,
|
||||||
|
51
|
||||||
|
],
|
||||||
|
"category_ids": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user