mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2024-12-28 01:41:14 -06:00
Big update to properly support multi currencies.
This commit is contained in:
parent
771ebde295
commit
82e74a2afd
@ -19,6 +19,7 @@ use FireflyIII\Http\Requests\MassDeleteJournalRequest;
|
||||
use FireflyIII\Http\Requests\MassEditJournalRequest;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
@ -126,8 +127,7 @@ class MassController extends Controller
|
||||
$budgetRepository = app(BudgetRepositoryInterface::class);
|
||||
$budgets = $budgetRepository->getBudgets();
|
||||
|
||||
// skip transactions that have multiple destinations
|
||||
// or multiple sources:
|
||||
// skip transactions that have multiple destinations, multiple sources or are an opening balance.
|
||||
$filtered = new Collection;
|
||||
$messages = [];
|
||||
/**
|
||||
@ -146,6 +146,10 @@ class MassController extends Controller
|
||||
$messages[] = trans('firefly.cannot_edit_multiple_dest', ['description' => $journal->description, 'id' => $journal->id]);
|
||||
continue;
|
||||
}
|
||||
if ($journal->transactionType->type === TransactionType::OPENING_BALANCE) {
|
||||
$messages[] = trans('firefly.cannot_edit_opening_balance');
|
||||
continue;
|
||||
}
|
||||
$filtered->push($journal);
|
||||
}
|
||||
|
||||
@ -158,13 +162,21 @@ class MassController extends Controller
|
||||
Session::flash('gaEventCategory', 'transactions');
|
||||
Session::flash('gaEventAction', 'mass-edit');
|
||||
|
||||
// set some values to be used in the edit routine:
|
||||
// collect some useful meta data for the mass edit:
|
||||
$filtered->each(
|
||||
function (TransactionJournal $journal) {
|
||||
$journal->amount = $journal->amountPositive();
|
||||
$sources = $journal->sourceAccountList();
|
||||
$destinations = $journal->destinationAccountList();
|
||||
$journal->transaction_count = $journal->transactions()->count();
|
||||
$transaction = $journal->positiveTransaction();
|
||||
$currency = $transaction->transactionCurrency;
|
||||
$journal->amount = floatval($transaction->amount);
|
||||
$sources = $journal->sourceAccountList();
|
||||
$destinations = $journal->destinationAccountList();
|
||||
$journal->transaction_count = $journal->transactions()->count();
|
||||
$journal->currency_symbol = $currency->symbol;
|
||||
$journal->transaction_type_type = $journal->transactionType->type;
|
||||
|
||||
$journal->foreign_amount = floatval($transaction->foreign_amount);
|
||||
$journal->foreign_currency = $transaction->foreignCurrency;
|
||||
|
||||
if (!is_null($sources->first())) {
|
||||
$journal->source_account_id = $sources->first()->id;
|
||||
$journal->source_account_name = $sources->first()->editname;
|
||||
@ -195,6 +207,7 @@ class MassController extends Controller
|
||||
{
|
||||
$journalIds = $request->get('journals');
|
||||
$count = 0;
|
||||
|
||||
if (is_array($journalIds)) {
|
||||
foreach ($journalIds as $journalId) {
|
||||
$journal = $repository->find(intval($journalId));
|
||||
@ -208,6 +221,10 @@ class MassController extends Controller
|
||||
$budgetId = $request->get('budget_id')[$journal->id] ?? 0;
|
||||
$category = $request->get('category')[$journal->id];
|
||||
$tags = $journal->tags->pluck('tag')->toArray();
|
||||
$amount = round($request->get('amount')[$journal->id], 12);
|
||||
$foreignAmount = isset($request->get('foreign_amount')[$journal->id]) ? round($request->get('foreign_amount')[$journal->id], 12) : null;
|
||||
$foreignCurrencyId = isset($request->get('foreign_currency_id')[$journal->id]) ?
|
||||
intval($request->get('foreign_currency_id')[$journal->id]) : null;
|
||||
|
||||
// build data array
|
||||
$data = [
|
||||
@ -218,16 +235,20 @@ class MassController extends Controller
|
||||
'source_account_name' => $sourceAccountName,
|
||||
'destination_account_id' => intval($destAccountId),
|
||||
'destination_account_name' => $destAccountName,
|
||||
'amount' => round($request->get('amount')[$journal->id], 12),
|
||||
'currency_id' => $journal->transaction_currency_id,
|
||||
'amount' => $foreignAmount,
|
||||
'native_amount' => $amount,
|
||||
'source_amount' => $amount,
|
||||
'date' => new Carbon($request->get('date')[$journal->id]),
|
||||
'interest_date' => $journal->interest_date,
|
||||
'book_date' => $journal->book_date,
|
||||
'process_date' => $journal->process_date,
|
||||
'budget_id' => intval($budgetId),
|
||||
'currency_id' => $foreignCurrencyId,
|
||||
'foreign_amount' => $foreignAmount,
|
||||
'destination_amount' => $foreignAmount,
|
||||
//'foreign_currency_id' => $foreignCurrencyId,
|
||||
'category' => $category,
|
||||
'tags' => $tags,
|
||||
|
||||
];
|
||||
// call repository update function.
|
||||
$repository->update($journal, $data);
|
||||
@ -235,6 +256,7 @@ class MassController extends Controller
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Preferences::mark();
|
||||
Session::flash('success', trans('firefly.mass_edited_transactions_success', ['amount' => $count]));
|
||||
|
@ -238,6 +238,7 @@ class SingleController extends Controller
|
||||
$sourceAccounts = $journal->sourceAccountList();
|
||||
$destinationAccounts = $journal->destinationAccountList();
|
||||
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||
$pTransaction = $journal->positiveTransaction();
|
||||
$preFilled = [
|
||||
'date' => $journal->dateAsString(),
|
||||
'interest_date' => $journal->dateAsString('interest_date'),
|
||||
@ -250,8 +251,6 @@ class SingleController extends Controller
|
||||
'source_account_name' => $sourceAccounts->first()->edit_name,
|
||||
'destination_account_id' => $destinationAccounts->first()->id,
|
||||
'destination_account_name' => $destinationAccounts->first()->edit_name,
|
||||
'amount' => $journal->amountPositive(),
|
||||
'currency' => $journal->transactionCurrency,
|
||||
|
||||
// new custom fields:
|
||||
'due_date' => $journal->dateAsString('due_date'),
|
||||
@ -260,26 +259,36 @@ class SingleController extends Controller
|
||||
'interal_reference' => $journal->getMeta('internal_reference'),
|
||||
'notes' => $journal->getMeta('notes'),
|
||||
|
||||
// exchange rate fields
|
||||
'native_amount' => $journal->amountPositive(),
|
||||
'native_currency' => $journal->transactionCurrency,
|
||||
// amount fields
|
||||
'amount' => $pTransaction->amount,
|
||||
'source_amount' => $pTransaction->amount,
|
||||
'native_amount' => $pTransaction->amount,
|
||||
'destination_amount' => $pTransaction->foreign_amount,
|
||||
'currency' => $pTransaction->transactionCurrency,
|
||||
'source_currency' => $pTransaction->transactionCurrency,
|
||||
'native_currency' => $pTransaction->transactionCurrency,
|
||||
'foreign_currency' => !is_null($pTransaction->foreignCurrency) ? $pTransaction->foreignCurrency : $pTransaction->transactionCurrency,
|
||||
'destination_currency' => !is_null($pTransaction->foreignCurrency) ? $pTransaction->foreignCurrency : $pTransaction->transactionCurrency,
|
||||
];
|
||||
|
||||
// if user has entered a foreign currency, update some fields
|
||||
$foreignCurrencyId = intval($journal->getMeta('foreign_currency_id'));
|
||||
if ($foreignCurrencyId > 0) {
|
||||
// update some fields in pre-filled.
|
||||
// @codeCoverageIgnoreStart
|
||||
$preFilled['amount'] = $journal->getMeta('foreign_amount');
|
||||
$preFilled['currency'] = $this->currency->find(intval($journal->getMeta('foreign_currency_id')));
|
||||
// @codeCoverageIgnoreEnd
|
||||
// amounts for withdrawals and deposits:
|
||||
// (amount, native_amount, source_amount, destination_amount)
|
||||
if (($journal->isWithdrawal() || $journal->isDeposit()) && !is_null($pTransaction->foreign_amount)) {
|
||||
$preFilled['amount'] = $pTransaction->foreign_amount;
|
||||
$preFilled['currency'] = $pTransaction->foreignCurrency;
|
||||
}
|
||||
|
||||
if ($journal->isWithdrawal() && $destinationAccounts->first()->accountType->type == AccountType::CASH) {
|
||||
if ($journal->isTransfer() && !is_null($pTransaction->foreign_amount)) {
|
||||
$preFilled['destination_amount'] = $pTransaction->foreign_amount;
|
||||
$preFilled['destination_currency'] = $pTransaction->foreignCurrency;
|
||||
}
|
||||
|
||||
// fixes for cash accounts:
|
||||
if ($journal->isWithdrawal() && $destinationAccounts->first()->accountType->type === AccountType::CASH) {
|
||||
$preFilled['destination_account_name'] = '';
|
||||
}
|
||||
|
||||
if ($journal->isDeposit() && $sourceAccounts->first()->accountType->type == AccountType::CASH) {
|
||||
if ($journal->isDeposit() && $sourceAccounts->first()->accountType->type === AccountType::CASH) {
|
||||
$preFilled['source_account_name'] = '';
|
||||
}
|
||||
|
||||
@ -319,6 +328,7 @@ class SingleController extends Controller
|
||||
|
||||
return redirect(route('transactions.create', [$request->input('what')]))->withInput();
|
||||
}
|
||||
|
||||
/** @var array $files */
|
||||
$files = $request->hasFile('attachments') ? $request->file('attachments') : null;
|
||||
$this->attachments->saveAttachmentsForModel($journal, $files);
|
||||
|
@ -93,7 +93,7 @@ class SplitController extends Controller
|
||||
}
|
||||
|
||||
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
|
||||
$currencies = ExpandedForm::makeSelectList($this->currencies->get());
|
||||
$currencies = $this->currencies->get();
|
||||
$assetAccounts = ExpandedForm::makeSelectList($this->accounts->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]));
|
||||
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||
$budgets = ExpandedForm::makeSelectListWithEmpty($this->budgets->getActiveBudgets());
|
||||
@ -130,7 +130,6 @@ class SplitController extends Controller
|
||||
*/
|
||||
public function update(Request $request, JournalRepositoryInterface $repository, TransactionJournal $journal)
|
||||
{
|
||||
|
||||
if ($this->isOpeningBalance($journal)) {
|
||||
return $this->redirectToAccount($journal);
|
||||
}
|
||||
@ -179,7 +178,6 @@ class SplitController extends Controller
|
||||
'journal_source_account_id' => $request->get('journal_source_account_id'),
|
||||
'journal_source_account_name' => $request->get('journal_source_account_name'),
|
||||
'journal_destination_account_id' => $request->get('journal_destination_account_id'),
|
||||
'currency_id' => $request->get('currency_id'),
|
||||
'what' => $request->get('what'),
|
||||
'date' => $request->get('date'),
|
||||
// all custom fields:
|
||||
@ -218,7 +216,6 @@ class SplitController extends Controller
|
||||
'journal_source_account_id' => $request->old('journal_source_account_id', $sourceAccounts->first()->id),
|
||||
'journal_source_account_name' => $request->old('journal_source_account_name', $sourceAccounts->first()->name),
|
||||
'journal_destination_account_id' => $request->old('journal_destination_account_id', $destinationAccounts->first()->id),
|
||||
'currency_id' => $request->old('currency_id', $journal->transaction_currency_id),
|
||||
'destinationAccounts' => $destinationAccounts,
|
||||
'what' => strtolower($journal->transactionTypeStr()),
|
||||
'date' => $request->old('date', $journal->date),
|
||||
@ -253,14 +250,22 @@ class SplitController extends Controller
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $index => $transaction) {
|
||||
$set = [
|
||||
'description' => $transaction['description'],
|
||||
'source_account_id' => $transaction['source_account_id'],
|
||||
'source_account_name' => $transaction['source_account_name'],
|
||||
'destination_account_id' => $transaction['destination_account_id'],
|
||||
'destination_account_name' => $transaction['destination_account_name'],
|
||||
'amount' => round($transaction['destination_amount'], 12),
|
||||
'budget_id' => isset($transaction['budget_id']) ? intval($transaction['budget_id']) : 0,
|
||||
'category' => $transaction['category'],
|
||||
'description' => $transaction['description'],
|
||||
'source_account_id' => $transaction['source_account_id'],
|
||||
'source_account_name' => $transaction['source_account_name'],
|
||||
'destination_account_id' => $transaction['destination_account_id'],
|
||||
'destination_account_name' => $transaction['destination_account_name'],
|
||||
'amount' => round($transaction['destination_amount'], 12),
|
||||
'budget_id' => isset($transaction['budget_id']) ? intval($transaction['budget_id']) : 0,
|
||||
'category' => $transaction['category'],
|
||||
'transaction_currency_id' => $transaction['transaction_currency_id'],
|
||||
'transaction_currency_code' => $transaction['transaction_currency_code'],
|
||||
'transaction_currency_symbol' => $transaction['transaction_currency_symbol'],
|
||||
'foreign_amount' => round($transaction['foreign_destination_amount'], 12),
|
||||
'foreign_currency_id' => $transaction['foreign_currency_id'],
|
||||
'foreign_currency_code' => $transaction['foreign_currency_code'],
|
||||
'foreign_currency_symbol' => $transaction['foreign_currency_symbol'],
|
||||
|
||||
];
|
||||
|
||||
// set initial category and/or budget:
|
||||
@ -294,8 +299,12 @@ class SplitController extends Controller
|
||||
'destination_account_id' => $transaction['destination_account_id'] ?? 0,
|
||||
'destination_account_name' => $transaction['destination_account_name'] ?? '',
|
||||
'amount' => round($transaction['amount'] ?? 0, 12),
|
||||
'foreign_amount' => !isset($transaction['foreign_amount']) ? null : round($transaction['foreign_amount'] ?? 0, 12),
|
||||
'budget_id' => isset($transaction['budget_id']) ? intval($transaction['budget_id']) : 0,
|
||||
'category' => $transaction['category'] ?? '',
|
||||
'transaction_currency_id' => intval($transaction['transaction_currency_id']),
|
||||
'foreign_currency_id' => $transaction['foreign_currency_id'] ?? null,
|
||||
|
||||
];
|
||||
}
|
||||
Log::debug(sprintf('Found %d splits in request data.', count($return)));
|
||||
|
@ -183,17 +183,8 @@ class TransactionController extends Controller
|
||||
$transactions = $tasker->getTransactionsOverview($journal);
|
||||
$what = strtolower($journal->transaction_type_type ?? $journal->transactionType->type);
|
||||
$subTitle = trans('firefly.' . $what) . ' "' . e($journal->description) . '"';
|
||||
$foreignCurrency = null;
|
||||
|
||||
if ($journal->hasMeta('foreign_currency_id')) {
|
||||
// @codeCoverageIgnoreStart
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
$foreignCurrency = $repository->find(intval($journal->getMeta('foreign_currency_id')));
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return view('transactions.show', compact('journal', 'events', 'subTitle', 'what', 'transactions', 'foreignCurrency'));
|
||||
return view('transactions.show', compact('journal', 'events', 'subTitle', 'what', 'transactions'));
|
||||
|
||||
|
||||
}
|
||||
|
@ -291,6 +291,7 @@ class ImportStorage
|
||||
'user_id' => $entry->user->id,
|
||||
'transaction_type_id' => $entry->fields['transaction-type']->id,
|
||||
'bill_id' => $billId,
|
||||
// TODO update this transaction currency reference.
|
||||
'transaction_currency_id' => $entry->fields['currency']->id,
|
||||
'description' => $entry->fields['description'],
|
||||
'date' => $entry->fields['date-transaction'],
|
||||
|
@ -74,6 +74,7 @@ class ImportValidator
|
||||
$entry = $this->setOpposingAccount($entry);
|
||||
$entry = $this->cleanDescription($entry);
|
||||
$entry = $this->setTransactionType($entry);
|
||||
// TODO update this transaction currency reference.
|
||||
$entry = $this->setTransactionCurrency($entry);
|
||||
|
||||
$newCollection->put($index, $entry);
|
||||
@ -383,6 +384,7 @@ class ImportValidator
|
||||
*/
|
||||
private function setTransactionCurrency(ImportEntry $entry): ImportEntry
|
||||
{
|
||||
// TODO update this transaction currency reference.
|
||||
if (is_null($entry->fields['currency'])) {
|
||||
/** @var CurrencyRepositoryInterface $repository */
|
||||
$repository = app(CurrencyRepositoryInterface::class);
|
||||
|
@ -26,7 +26,6 @@ use Watson\Validating\ValidatingTrait;
|
||||
*/
|
||||
class Transaction extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* The attributes that should be casted to native types.
|
||||
*
|
||||
@ -42,16 +41,18 @@ class Transaction extends Model
|
||||
'bill_name_encrypted' => 'boolean',
|
||||
];
|
||||
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
|
||||
protected $fillable = ['account_id', 'transaction_journal_id', 'description', 'amount', 'identifier'];
|
||||
protected $fillable = ['account_id', 'transaction_journal_id', 'description', 'amount', 'identifier', 'transaction_currency_id', 'foreign_currency_id','foreign_amount'];
|
||||
protected $hidden = ['encrypted'];
|
||||
protected $rules
|
||||
= [
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'transaction_journal_id' => 'required|exists:transaction_journals,id',
|
||||
'description' => 'between:0,1024',
|
||||
'amount' => 'required|numeric',
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'transaction_journal_id' => 'required|exists:transaction_journals,id',
|
||||
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
//'foreign_currency_id' => 'exists:transaction_currencies,id',
|
||||
'description' => 'between:0,1024',
|
||||
'amount' => 'required|numeric',
|
||||
//'foreign_amount' => 'numeric',
|
||||
];
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
|
||||
/**
|
||||
* @param Builder $query
|
||||
@ -74,6 +75,8 @@ class Transaction extends Model
|
||||
return false;
|
||||
}
|
||||
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
@ -160,6 +163,22 @@ class Transaction extends Model
|
||||
$this->attributes['amount'] = strval(round($value, 12));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function transactionCurrency()
|
||||
{
|
||||
return $this->belongsTo('FireflyIII\Models\TransactionCurrency');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function foreignCurrency()
|
||||
{
|
||||
return $this->belongsTo('FireflyIII\Models\TransactionCurrency','foreign_currency_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
|
@ -68,7 +68,6 @@ class TransactionJournal extends Model
|
||||
= [
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'transaction_type_id' => 'required|exists:transaction_types,id',
|
||||
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'description' => 'required|between:1,1024',
|
||||
'completed' => 'required|boolean',
|
||||
'date' => 'required|date',
|
||||
@ -299,46 +298,6 @@ class TransactionJournal extends Model
|
||||
return $query->where('transaction_journals.date', '<=', $date->format('Y-m-d 00:00:00'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
*/
|
||||
public function scopeExpanded(EloquentBuilder $query)
|
||||
{
|
||||
// left join transaction type:
|
||||
if (!self::isJoined($query, 'transaction_types')) {
|
||||
$query->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||
}
|
||||
|
||||
// left join transaction currency:
|
||||
$query->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transaction_journals.transaction_currency_id');
|
||||
|
||||
// extend group by:
|
||||
$query->groupBy(
|
||||
[
|
||||
'transaction_journals.id',
|
||||
'transaction_journals.created_at',
|
||||
'transaction_journals.updated_at',
|
||||
'transaction_journals.deleted_at',
|
||||
'transaction_journals.user_id',
|
||||
'transaction_journals.transaction_type_id',
|
||||
'transaction_journals.bill_id',
|
||||
'transaction_journals.transaction_currency_id',
|
||||
'transaction_journals.description',
|
||||
'transaction_journals.date',
|
||||
'transaction_journals.interest_date',
|
||||
'transaction_journals.book_date',
|
||||
'transaction_journals.process_date',
|
||||
'transaction_journals.order',
|
||||
'transaction_journals.tag_count',
|
||||
'transaction_journals.encrypted',
|
||||
'transaction_journals.completed',
|
||||
'transaction_types.type',
|
||||
'transaction_currencies.code',
|
||||
]
|
||||
);
|
||||
$query->with(['categories', 'budgets', 'attachments', 'bill', 'transactions']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
*/
|
||||
|
@ -44,6 +44,7 @@ use FireflyIII\Support\Navigation;
|
||||
use FireflyIII\Support\Preferences;
|
||||
use FireflyIII\Support\Steam;
|
||||
use FireflyIII\Support\Twig\Account;
|
||||
use FireflyIII\Support\Twig\AmountFormat;
|
||||
use FireflyIII\Support\Twig\General;
|
||||
use FireflyIII\Support\Twig\Journal;
|
||||
use FireflyIII\Support\Twig\PiggyBank;
|
||||
@ -79,7 +80,7 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
Twig::addExtension(new Translation);
|
||||
Twig::addExtension(new Transaction);
|
||||
Twig::addExtension(new Rule);
|
||||
Twig::addExtension(new Account);
|
||||
Twig::addExtension(new AmountFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -481,6 +481,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'transaction_type_id' => $transactionType->id,
|
||||
// TODO update this transaction currency reference.
|
||||
'transaction_currency_id' => $currencyId,
|
||||
'description' => 'Initial balance for "' . $account->name . '"',
|
||||
'completed' => true,
|
||||
@ -622,6 +623,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
// update date:
|
||||
$journal->date = $date;
|
||||
// TODO update this transaction currency reference.
|
||||
$journal->transaction_currency_id = $currencyId;
|
||||
$journal->save();
|
||||
// update transactions:
|
||||
|
@ -39,7 +39,6 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
{
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/** @var array */
|
||||
private $validMetaFields
|
||||
= ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date', 'internal_reference', 'notes', 'foreign_amount',
|
||||
@ -182,13 +181,12 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
$transactionType = TransactionType::where('type', ucfirst($data['what']))->first();
|
||||
$accounts = $this->storeAccounts($transactionType, $data);
|
||||
$data = $this->verifyNativeAmount($data, $accounts);
|
||||
$currencyId = $data['currency_id'];
|
||||
$amount = strval($data['amount']);
|
||||
$journal = new TransactionJournal(
|
||||
[
|
||||
'user_id' => $this->user->id,
|
||||
'transaction_type_id' => $transactionType->id,
|
||||
'transaction_currency_id' => $currencyId,
|
||||
'transaction_currency_id' => $data['currency_id'], // no longer used.
|
||||
'description' => $data['description'],
|
||||
'completed' => 0,
|
||||
'date' => $data['date'],
|
||||
@ -200,27 +198,32 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
$this->storeCategoryWithJournal($journal, $data['category']);
|
||||
$this->storeBudgetWithJournal($journal, $data['budget_id']);
|
||||
|
||||
|
||||
// store two transactions:
|
||||
$one = [
|
||||
'journal' => $journal,
|
||||
'account' => $accounts['source'],
|
||||
'amount' => bcmul($amount, '-1'),
|
||||
'description' => null,
|
||||
'category' => null,
|
||||
'budget' => null,
|
||||
'identifier' => 0,
|
||||
'journal' => $journal,
|
||||
'account' => $accounts['source'],
|
||||
'amount' => bcmul($amount, '-1'),
|
||||
'transaction_currency_id' => $data['currency_id'],
|
||||
'foreign_amount' => is_null($data['foreign_amount']) ? null : bcmul(strval($data['foreign_amount']), '-1'),
|
||||
'foreign_currency_id' => $data['foreign_currency_id'],
|
||||
'description' => null,
|
||||
'category' => null,
|
||||
'budget' => null,
|
||||
'identifier' => 0,
|
||||
];
|
||||
$this->storeTransaction($one);
|
||||
|
||||
$two = [
|
||||
'journal' => $journal,
|
||||
'account' => $accounts['destination'],
|
||||
'amount' => $amount,
|
||||
'description' => null,
|
||||
'category' => null,
|
||||
'budget' => null,
|
||||
'identifier' => 0,
|
||||
'journal' => $journal,
|
||||
'account' => $accounts['destination'],
|
||||
'amount' => $amount,
|
||||
'transaction_currency_id' => $data['currency_id'],
|
||||
'foreign_amount' => $data['foreign_amount'],
|
||||
'foreign_currency_id' => $data['foreign_currency_id'],
|
||||
'description' => null,
|
||||
'category' => null,
|
||||
'budget' => null,
|
||||
'identifier' => 0,
|
||||
];
|
||||
|
||||
$this->storeTransaction($two);
|
||||
@ -256,11 +259,14 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
{
|
||||
|
||||
// update actual journal:
|
||||
$journal->description = $data['description'];
|
||||
$journal->date = $data['date'];
|
||||
$accounts = $this->storeAccounts($journal->transactionType, $data);
|
||||
$data = $this->verifyNativeAmount($data, $accounts);
|
||||
$amount = strval($data['amount']);
|
||||
$journal->description = $data['description'];
|
||||
$journal->date = $data['date'];
|
||||
$accounts = $this->storeAccounts($journal->transactionType, $data);
|
||||
$data = $this->verifyNativeAmount($data, $accounts);
|
||||
$data['amount'] = strval($data['amount']);
|
||||
$data['foreign_amount'] = is_null($data['foreign_amount']) ? null : strval($data['foreign_amount']);
|
||||
|
||||
var_dump($data);
|
||||
|
||||
// unlink all categories, recreate them:
|
||||
$journal->categories()->detach();
|
||||
@ -269,9 +275,11 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
$this->storeCategoryWithJournal($journal, $data['category']);
|
||||
$this->storeBudgetWithJournal($journal, $data['budget_id']);
|
||||
|
||||
// negative because source loses money.
|
||||
$this->updateSourceTransaction($journal, $accounts['source'], $data);
|
||||
|
||||
$this->updateSourceTransaction($journal, $accounts['source'], bcmul($amount, '-1')); // negative because source loses money.
|
||||
$this->updateDestinationTransaction($journal, $accounts['destination'], $amount); // positive because destination gets money.
|
||||
// positive because destination gets money.
|
||||
$this->updateDestinationTransaction($journal, $accounts['destination'], $data);
|
||||
|
||||
$journal->save();
|
||||
|
||||
@ -308,9 +316,8 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
public function updateSplitJournal(TransactionJournal $journal, array $data): TransactionJournal
|
||||
{
|
||||
// update actual journal:
|
||||
$journal->transaction_currency_id = $data['currency_id'];
|
||||
$journal->description = $data['journal_description'];
|
||||
$journal->date = $data['date'];
|
||||
$journal->description = $data['journal_description'];
|
||||
$journal->date = $data['date'];
|
||||
$journal->save();
|
||||
Log::debug(sprintf('Updated split journal #%d', $journal->id));
|
||||
|
||||
@ -342,6 +349,7 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
// store each transaction.
|
||||
$identifier = 0;
|
||||
Log::debug(sprintf('Count %d transactions in updateSplitJournal()', count($data['transactions'])));
|
||||
|
||||
foreach ($data['transactions'] as $transaction) {
|
||||
Log::debug(sprintf('Split journal update split transaction %d', $identifier));
|
||||
$transaction = $this->appendTransactionData($transaction, $data);
|
||||
@ -564,30 +572,40 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
$accounts = $this->storeAccounts($journal->transactionType, $transaction);
|
||||
|
||||
// store transaction one way:
|
||||
$one = $this->storeTransaction(
|
||||
$amount = bcmul(strval($transaction['amount']), '-1');
|
||||
$foreignAmount = is_null($transaction['foreign_amount']) ? null : bcmul(strval($transaction['foreign_amount']), '-1');
|
||||
$one = $this->storeTransaction(
|
||||
[
|
||||
'journal' => $journal,
|
||||
'account' => $accounts['source'],
|
||||
'amount' => bcmul(strval($transaction['amount']), '-1'),
|
||||
'description' => $transaction['description'],
|
||||
'category' => null,
|
||||
'budget' => null,
|
||||
'identifier' => $identifier,
|
||||
'journal' => $journal,
|
||||
'account' => $accounts['source'],
|
||||
'amount' => $amount,
|
||||
'transaction_currency_id' => $transaction['transaction_currency_id'],
|
||||
'foreign_amount' => $foreignAmount,
|
||||
'foreign_currency_id' => $transaction['foreign_currency_id'],
|
||||
'description' => $transaction['description'],
|
||||
'category' => null,
|
||||
'budget' => null,
|
||||
'identifier' => $identifier,
|
||||
]
|
||||
);
|
||||
$this->storeCategoryWithTransaction($one, $transaction['category']);
|
||||
$this->storeBudgetWithTransaction($one, $transaction['budget_id']);
|
||||
|
||||
// and the other way:
|
||||
$two = $this->storeTransaction(
|
||||
$amount = strval($transaction['amount']);
|
||||
$foreignAmount = is_null($transaction['foreign_amount']) ? null : strval($transaction['foreign_amount']);
|
||||
$two = $this->storeTransaction(
|
||||
[
|
||||
'journal' => $journal,
|
||||
'account' => $accounts['destination'],
|
||||
'amount' => strval($transaction['amount']),
|
||||
'description' => $transaction['description'],
|
||||
'category' => null,
|
||||
'budget' => null,
|
||||
'identifier' => $identifier,
|
||||
'journal' => $journal,
|
||||
'account' => $accounts['destination'],
|
||||
'amount' => $amount,
|
||||
'transaction_currency_id' => $transaction['transaction_currency_id'],
|
||||
'foreign_amount' => $foreignAmount,
|
||||
'foreign_currency_id' => $transaction['foreign_currency_id'],
|
||||
'description' => $transaction['description'],
|
||||
'category' => null,
|
||||
'budget' => null,
|
||||
'identifier' => $identifier,
|
||||
]
|
||||
);
|
||||
$this->storeCategoryWithTransaction($two, $transaction['category']);
|
||||
@ -603,16 +621,27 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
*/
|
||||
private function storeTransaction(array $data): Transaction
|
||||
{
|
||||
$fields = [
|
||||
'transaction_journal_id' => $data['journal']->id,
|
||||
'account_id' => $data['account']->id,
|
||||
'amount' => $data['amount'],
|
||||
'foreign_amount' => $data['foreign_amount'],
|
||||
'transaction_currency_id' => $data['transaction_currency_id'],
|
||||
'foreign_currency_id' => $data['foreign_currency_id'],
|
||||
'description' => $data['description'],
|
||||
'identifier' => $data['identifier'],
|
||||
];
|
||||
|
||||
|
||||
if (is_null($data['foreign_currency_id'])) {
|
||||
unset($fields['foreign_currency_id']);
|
||||
}
|
||||
if (is_null($data['foreign_amount'])) {
|
||||
unset($fields['foreign_amount']);
|
||||
}
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = Transaction::create(
|
||||
[
|
||||
'transaction_journal_id' => $data['journal']->id,
|
||||
'account_id' => $data['account']->id,
|
||||
'amount' => $data['amount'],
|
||||
'description' => $data['description'],
|
||||
'identifier' => $data['identifier'],
|
||||
]
|
||||
);
|
||||
$transaction = Transaction::create($fields);
|
||||
|
||||
Log::debug(sprintf('Transaction stored with ID: %s', $transaction->id));
|
||||
|
||||
@ -675,22 +704,23 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param Account $account
|
||||
* @param string $amount
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function updateDestinationTransaction(TransactionJournal $journal, Account $account, string $amount)
|
||||
private function updateDestinationTransaction(TransactionJournal $journal, Account $account, array $data)
|
||||
{
|
||||
// should be one:
|
||||
$set = $journal->transactions()->where('amount', '>', 0)->get();
|
||||
if ($set->count() != 1) {
|
||||
throw new FireflyException(
|
||||
sprintf('Journal #%d has an unexpected (%d) amount of transactions with an amount more than zero.', $journal->id, $set->count())
|
||||
);
|
||||
throw new FireflyException(sprintf('Journal #%d has %d transactions with an amount more than zero.', $journal->id, $set->count()));
|
||||
}
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $set->first();
|
||||
$transaction->amount = $amount;
|
||||
$transaction = $set->first();
|
||||
$transaction->amount = app('steam')->positive($data['amount']);
|
||||
$transaction->transaction_currency_id = $data['currency_id'];
|
||||
$transaction->foreign_amount = is_null($data['foreign_amount']) ? null : app('steam')->positive($data['foreign_amount']);
|
||||
$transaction->foreign_currency_id = $data['foreign_currency_id'];
|
||||
|
||||
$transaction->account_id = $account->id;
|
||||
$transaction->save();
|
||||
|
||||
@ -699,26 +729,24 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param Account $account
|
||||
* @param string $amount
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function updateSourceTransaction(TransactionJournal $journal, Account $account, string $amount)
|
||||
private function updateSourceTransaction(TransactionJournal $journal, Account $account, array $data)
|
||||
{
|
||||
// should be one:
|
||||
$set = $journal->transactions()->where('amount', '<', 0)->get();
|
||||
if ($set->count() != 1) {
|
||||
throw new FireflyException(
|
||||
sprintf('Journal #%d has an unexpected (%d) amount of transactions with an amount less than zero.', $journal->id, $set->count())
|
||||
);
|
||||
throw new FireflyException(sprintf('Journal #%d has %d transactions with an amount more than zero.', $journal->id, $set->count()));
|
||||
}
|
||||
/** @var Transaction $transaction */
|
||||
$transaction = $set->first();
|
||||
$transaction->amount = $amount;
|
||||
$transaction->account_id = $account->id;
|
||||
$transaction = $set->first();
|
||||
$transaction->amount = bcmul(app('steam')->positive($data['amount']), '-1');
|
||||
$transaction->transaction_currency_id = $data['currency_id'];
|
||||
$transaction->foreign_amount = is_null($data['foreign_amount']) ? null : bcmul(app('steam')->positive($data['foreign_amount']), '-1');
|
||||
$transaction->foreign_currency_id = $data['foreign_currency_id'];
|
||||
$transaction->save();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -777,8 +805,10 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
private function verifyNativeAmount(array $data, array $accounts): array
|
||||
{
|
||||
/** @var TransactionType $transactionType */
|
||||
$transactionType = TransactionType::where('type', ucfirst($data['what']))->first();
|
||||
$submittedCurrencyId = $data['currency_id'];
|
||||
$transactionType = TransactionType::where('type', ucfirst($data['what']))->first();
|
||||
$submittedCurrencyId = $data['currency_id'];
|
||||
$data['foreign_amount'] = null;
|
||||
$data['foreign_currency_id'] = null;
|
||||
|
||||
// which account to check for what the native currency is?
|
||||
$check = 'source';
|
||||
@ -803,11 +833,17 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
}
|
||||
break;
|
||||
case TransactionType::TRANSFER:
|
||||
// source gets the original amount.
|
||||
$data['amount'] = strval($data['source_amount']);
|
||||
$data['currency_id'] = intval($accounts['source']->getMeta('currency_id'));
|
||||
$data['foreign_amount'] = strval($data['destination_amount']);
|
||||
$data['foreign_currency_id'] = intval($accounts['destination']->getMeta('currency_id'));
|
||||
$sourceCurrencyId = intval($accounts['source']->getMeta('currency_id'));
|
||||
$destinationCurrencyId = intval($accounts['destination']->getMeta('currency_id'));
|
||||
$data['amount'] = strval($data['source_amount']);
|
||||
$data['currency_id'] = intval($accounts['source']->getMeta('currency_id'));
|
||||
|
||||
if ($sourceCurrencyId !== $destinationCurrencyId) {
|
||||
// accounts have different id's, save this info:
|
||||
$data['foreign_amount'] = strval($data['destination_amount']);
|
||||
$data['foreign_currency_id'] = $destinationCurrencyId;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot handle %s in verifyNativeAmount()', $transactionType->type));
|
||||
|
@ -81,6 +81,8 @@ class JournalTasker implements JournalTaskerInterface
|
||||
->leftJoin('account_types as source_account_types', 'source_accounts.account_type_id', '=', 'source_account_types.id')
|
||||
->leftJoin('accounts as destination_accounts', 'destination.account_id', '=', 'destination_accounts.id')
|
||||
->leftJoin('account_types as destination_account_types', 'destination_accounts.account_type_id', '=', 'destination_account_types.id')
|
||||
->leftJoin('transaction_currencies as native_currencies', 'transactions.transaction_currency_id', '=', 'native_currencies.id')
|
||||
->leftJoin('transaction_currencies as foreign_currencies', 'transactions.foreign_currency_id', '=', 'foreign_currencies.id')
|
||||
->where('transactions.amount', '<', 0)
|
||||
->whereNull('transactions.deleted_at')
|
||||
->get(
|
||||
@ -91,12 +93,21 @@ class JournalTasker implements JournalTaskerInterface
|
||||
'source_accounts.encrypted as account_encrypted',
|
||||
'source_account_types.type as account_type',
|
||||
'transactions.amount',
|
||||
'transactions.foreign_amount',
|
||||
'transactions.description',
|
||||
'destination.id as destination_id',
|
||||
'destination.account_id as destination_account_id',
|
||||
'destination_accounts.name as destination_account_name',
|
||||
'destination_accounts.encrypted as destination_account_encrypted',
|
||||
'destination_account_types.type as destination_account_type',
|
||||
'native_currencies.id as transaction_currency_id',
|
||||
'native_currencies.code as transaction_currency_code',
|
||||
'native_currencies.symbol as transaction_currency_symbol',
|
||||
|
||||
'foreign_currencies.id as foreign_currency_id',
|
||||
'foreign_currencies.code as foreign_currency_code',
|
||||
'foreign_currencies.symbol as foreign_currency_symbol',
|
||||
|
||||
]
|
||||
);
|
||||
|
||||
@ -109,23 +120,31 @@ class JournalTasker implements JournalTaskerInterface
|
||||
$budget = $entry->budgets->first();
|
||||
$category = $entry->categories->first();
|
||||
$transaction = [
|
||||
'source_id' => $entry->id,
|
||||
'source_amount' => $entry->amount,
|
||||
'description' => $entry->description,
|
||||
'source_account_id' => $entry->account_id,
|
||||
'source_account_name' => Steam::decrypt(intval($entry->account_encrypted), $entry->account_name),
|
||||
'source_account_type' => $entry->account_type,
|
||||
'source_account_before' => $sourceBalance,
|
||||
'source_account_after' => bcadd($sourceBalance, $entry->amount),
|
||||
'destination_id' => $entry->destination_id,
|
||||
'destination_amount' => bcmul($entry->amount, '-1'),
|
||||
'destination_account_id' => $entry->destination_account_id,
|
||||
'destination_account_type' => $entry->destination_account_type,
|
||||
'destination_account_name' => Steam::decrypt(intval($entry->destination_account_encrypted), $entry->destination_account_name),
|
||||
'destination_account_before' => $destinationBalance,
|
||||
'destination_account_after' => bcadd($destinationBalance, bcmul($entry->amount, '-1')),
|
||||
'budget_id' => is_null($budget) ? 0 : $budget->id,
|
||||
'category' => is_null($category) ? '' : $category->name,
|
||||
'source_id' => $entry->id,
|
||||
'source_amount' => $entry->amount,
|
||||
'foreign_source_amount' => $entry->foreign_amount,
|
||||
'description' => $entry->description,
|
||||
'source_account_id' => $entry->account_id,
|
||||
'source_account_name' => Steam::decrypt(intval($entry->account_encrypted), $entry->account_name),
|
||||
'source_account_type' => $entry->account_type,
|
||||
'source_account_before' => $sourceBalance,
|
||||
'source_account_after' => bcadd($sourceBalance, $entry->amount),
|
||||
'destination_id' => $entry->destination_id,
|
||||
'destination_amount' => bcmul($entry->amount, '-1'),
|
||||
'foreign_destination_amount' => is_null($entry->foreign_amount) ? null : bcmul($entry->foreign_amount, '-1'),
|
||||
'destination_account_id' => $entry->destination_account_id,
|
||||
'destination_account_type' => $entry->destination_account_type,
|
||||
'destination_account_name' => Steam::decrypt(intval($entry->destination_account_encrypted), $entry->destination_account_name),
|
||||
'destination_account_before' => $destinationBalance,
|
||||
'destination_account_after' => bcadd($destinationBalance, bcmul($entry->amount, '-1')),
|
||||
'budget_id' => is_null($budget) ? 0 : $budget->id,
|
||||
'category' => is_null($category) ? '' : $category->name,
|
||||
'transaction_currency_id' => $entry->transaction_currency_id,
|
||||
'transaction_currency_code' => $entry->transaction_currency_code,
|
||||
'transaction_currency_symbol' => $entry->transaction_currency_symbol,
|
||||
'foreign_currency_id' => $entry->foreign_currency_id,
|
||||
'foreign_currency_code' => $entry->foreign_currency_code,
|
||||
'foreign_currency_symbol' => $entry->foreign_currency_symbol,
|
||||
];
|
||||
if ($entry->destination_account_type === AccountType::CASH) {
|
||||
$transaction['destination_account_name'] = '';
|
||||
|
@ -17,6 +17,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences as Prefs;
|
||||
|
||||
@ -101,17 +102,6 @@ class Amount
|
||||
return $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $amount
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format(string $amount, bool $coloured = true): string
|
||||
{
|
||||
return $this->formatAnything($this->getDefaultCurrency(), $amount, $coloured);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will properly format the given number, in color or "black and white",
|
||||
* as a currency, given two things: the currency required and the current locale.
|
||||
@ -159,49 +149,6 @@ class Amount
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in many places (unfortunately).
|
||||
*
|
||||
* @param string $currencyCode
|
||||
* @param string $amount
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatByCode(string $currencyCode, string $amount, bool $coloured = true): string
|
||||
{
|
||||
$currency = TransactionCurrency::where('code', $currencyCode)->first();
|
||||
|
||||
return $this->formatAnything($currency, $amount, $coloured);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \FireflyIII\Models\TransactionJournal $journal
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatJournal(TransactionJournal $journal, bool $coloured = true): string
|
||||
{
|
||||
$currency = $journal->transactionCurrency;
|
||||
|
||||
return $this->formatAnything($currency, $journal->amount(), $coloured);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Transaction $transaction
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatTransaction(Transaction $transaction, bool $coloured = true)
|
||||
{
|
||||
$currency = $transaction->transactionJournal->transactionCurrency;
|
||||
|
||||
return $this->formatAnything($currency, strval($transaction->amount), $coloured);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
|
@ -37,15 +37,8 @@ class JournalList implements BinderInterface
|
||||
$ids = explode(',', $value);
|
||||
/** @var \Illuminate\Support\Collection $object */
|
||||
$object = TransactionJournal::whereIn('transaction_journals.id', $ids)
|
||||
->expanded()
|
||||
->where('transaction_journals.user_id', auth()->user()->id)
|
||||
->get(
|
||||
[
|
||||
'transaction_journals.*',
|
||||
'transaction_types.type AS transaction_type_type',
|
||||
'transaction_currencies.code AS transaction_currency_code',
|
||||
]
|
||||
);
|
||||
->get(['transaction_journals.*',]);
|
||||
|
||||
if ($object->count() > 0) {
|
||||
return $object;
|
||||
|
@ -213,6 +213,14 @@ trait TransactionJournalTrait
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Transaction
|
||||
*/
|
||||
public function positiveTransaction(): Transaction
|
||||
{
|
||||
return $this->transactions()->where('amount', '>', 0)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
|
@ -1,63 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Account.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Twig;
|
||||
|
||||
|
||||
use FireflyIII\Models\Account as AccountModel;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Support\Facades\Amount as AmountFacade;
|
||||
use Twig_Extension;
|
||||
use Twig_SimpleFunction;
|
||||
|
||||
/**
|
||||
* Class Account
|
||||
*
|
||||
* @package FireflyIII\Support\Twig
|
||||
*/
|
||||
class Account extends Twig_Extension
|
||||
{
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
$this->formatAmountByAccount(),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return "active" when a part of the route matches the argument.
|
||||
* ie. "accounts" will match "accounts.index".
|
||||
*
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
protected function formatAmountByAccount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'formatAmountByAccount', function (AccountModel $account, string $amount, bool $coloured = true): string {
|
||||
$currencyId = intval($account->getMeta('currency_id'));
|
||||
if ($currencyId === 0) {
|
||||
// Format using default currency:
|
||||
return AmountFacade::format($amount, $coloured);
|
||||
}
|
||||
$currency = TransactionCurrency::find($currencyId);
|
||||
|
||||
return AmountFacade::formatAnything($currency, $amount, $coloured);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
109
app/Support/Twig/AmountFormat.php
Normal file
109
app/Support/Twig/AmountFormat.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* AmountFormat.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Twig;
|
||||
|
||||
|
||||
use FireflyIII\Models\Account as AccountModel;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Twig_Extension;
|
||||
use Twig_SimpleFilter;
|
||||
use Twig_SimpleFunction;
|
||||
|
||||
/**
|
||||
* Contains all amount formatting routines.
|
||||
*
|
||||
* @package FireflyIII\Support\Twig
|
||||
*/
|
||||
class AmountFormat extends Twig_Extension
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFilters(): array
|
||||
{
|
||||
return [
|
||||
$this->formatAmount(),
|
||||
$this->formatAmountPlain(),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
$this->formatAmountByAccount(),
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'FireflyIII\Support\Twig\AmountFormat';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Twig_SimpleFilter
|
||||
*/
|
||||
protected function formatAmount(): Twig_SimpleFilter
|
||||
{
|
||||
return new Twig_SimpleFilter(
|
||||
'formatAmount', function (string $string): string {
|
||||
|
||||
return app('amount')->format($string);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will format the amount by the currency related to the given account.
|
||||
*
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
protected function formatAmountByAccount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'formatAmountByAccount', function (AccountModel $account, string $amount, bool $coloured = true): string {
|
||||
$currencyId = intval($account->getMeta('currency_id'));
|
||||
if ($currencyId === 0) {
|
||||
// Format using default currency:
|
||||
return app('amount')->format($amount, $coloured);
|
||||
}
|
||||
$currency = TransactionCurrency::find($currencyId);
|
||||
|
||||
return app('amount')->formatAnything($currency, $amount, $coloured);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFilter
|
||||
*/
|
||||
protected function formatAmountPlain(): Twig_SimpleFilter
|
||||
{
|
||||
return new Twig_SimpleFilter(
|
||||
'formatAmountPlain', function (string $string): string {
|
||||
|
||||
return app('amount')->format($string, false);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
}
|
@ -38,9 +38,6 @@ class General extends Twig_Extension
|
||||
public function getFilters(): array
|
||||
{
|
||||
return [
|
||||
$this->formatAmount(),
|
||||
$this->formatAmountPlain(),
|
||||
$this->formatJournal(),
|
||||
$this->balance(),
|
||||
$this->formatFilesize(),
|
||||
$this->mimeIcon(),
|
||||
@ -173,33 +170,6 @@ class General extends Twig_Extension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Twig_SimpleFilter
|
||||
*/
|
||||
protected function formatAmount(): Twig_SimpleFilter
|
||||
{
|
||||
return new Twig_SimpleFilter(
|
||||
'formatAmount', function (string $string): string {
|
||||
|
||||
return app('amount')->format($string);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFilter
|
||||
*/
|
||||
protected function formatAmountPlain(): Twig_SimpleFilter
|
||||
{
|
||||
return new Twig_SimpleFilter(
|
||||
'formatAmountPlain', function (string $string): string {
|
||||
|
||||
return app('amount')->format($string, false);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFilter
|
||||
*/
|
||||
@ -223,17 +193,6 @@ class General extends Twig_Extension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFilter
|
||||
*/
|
||||
protected function formatJournal(): Twig_SimpleFilter
|
||||
{
|
||||
return new Twig_SimpleFilter(
|
||||
'formatJournal', function (TransactionJournal $journal): string {
|
||||
return app('amount')->formatJournal($journal);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
|
@ -16,7 +16,6 @@ namespace FireflyIII\Support\Twig;
|
||||
use Amount;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction as TransactionModel;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Steam;
|
||||
use Twig_Extension;
|
||||
@ -30,49 +29,6 @@ use Twig_SimpleFunction;
|
||||
*/
|
||||
class Transaction extends Twig_Extension
|
||||
{
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function formatAnything(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'formatAnything', function (TransactionCurrency $currency, string $amount): string {
|
||||
|
||||
return Amount::formatAnything($currency, $amount, true);
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function formatAnythingPlain(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'formatAnythingPlain', function (TransactionCurrency $currency, string $amount): string {
|
||||
|
||||
return Amount::formatAnything($currency, $amount, false);
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function formatByCode(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'formatByCode', function (string $currencyCode, string $amount): string {
|
||||
|
||||
return Amount::formatByCode($currencyCode, $amount, true);
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@ -91,17 +47,13 @@ class Transaction extends Twig_Extension
|
||||
public function getFunctions(): array
|
||||
{
|
||||
$functions = [
|
||||
$this->formatAnything(),
|
||||
$this->formatAnythingPlain(),
|
||||
$this->transactionSourceAccount(),
|
||||
$this->transactionDestinationAccount(),
|
||||
$this->optionalJournalAmount(),
|
||||
$this->transactionBudgets(),
|
||||
$this->transactionIdBudgets(),
|
||||
$this->transactionCategories(),
|
||||
$this->transactionIdCategories(),
|
||||
$this->splitJournalIndicator(),
|
||||
$this->formatByCode(),
|
||||
];
|
||||
|
||||
return $functions;
|
||||
@ -117,33 +69,6 @@ class Transaction extends Twig_Extension
|
||||
return 'transaction';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function optionalJournalAmount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'optionalJournalAmount', function (int $journalId, string $transactionAmount, string $code, string $type): string {
|
||||
// get amount of journal:
|
||||
$amount = strval(TransactionModel::where('transaction_journal_id', $journalId)->whereNull('deleted_at')->where('amount', '<', 0)->sum('amount'));
|
||||
// display deposit and transfer positive
|
||||
if ($type === TransactionType::DEPOSIT || $type === TransactionType::TRANSFER) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
// not equal to transaction amount?
|
||||
if (bccomp($amount, $transactionAmount) !== 0 && bccomp($amount, bcmul($transactionAmount, '-1')) !== 0) {
|
||||
//$currency =
|
||||
return sprintf(' (%s)', Amount::formatByCode($code, $amount, true));
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
|
@ -89,6 +89,7 @@ $factory->define(
|
||||
'user_id' => 1,
|
||||
'transaction_type_id' => 1,
|
||||
'bill_id' => null,
|
||||
// TODO update this transaction currency reference.
|
||||
'transaction_currency_id' => 1,
|
||||
'description' => $faker->words(3, true),
|
||||
'date' => '2017-01-01',
|
||||
|
@ -38,11 +38,12 @@ function updateInitialPage() {
|
||||
$('#native_amount_holder').hide();
|
||||
$('#amount_holder').hide();
|
||||
|
||||
if (journalData.native_currency.id === journalData.currency.id) {
|
||||
|
||||
if (journalData.native_currency.id === journalData.destination_currency.id) {
|
||||
$('#exchange_rate_instruction_holder').hide();
|
||||
$('#destination_amount_holder').hide();
|
||||
}
|
||||
if (journalData.native_currency.id !== journalData.currency.id) {
|
||||
if (journalData.native_currency.id !== journalData.destination_currency.id) {
|
||||
$('#exchange_rate_instruction_holder').show().find('p').text(getTransferExchangeInstructions());
|
||||
|
||||
}
|
||||
|
@ -166,11 +166,31 @@ function resetSplits() {
|
||||
var input = $(v);
|
||||
input.attr('name', 'transactions[' + i + '][amount]');
|
||||
});
|
||||
|
||||
// ends with ][foreign_amount]
|
||||
$.each($('input[name$="][foreign_amount]"]'), function (i, v) {
|
||||
var input = $(v);
|
||||
input.attr('name', 'transactions[' + i + '][foreign_amount]');
|
||||
});
|
||||
|
||||
// ends with ][transaction_currency_id]
|
||||
$.each($('input[name$="][transaction_currency_id]"]'), function (i, v) {
|
||||
var input = $(v);
|
||||
input.attr('name', 'transactions[' + i + '][transaction_currency_id]');
|
||||
});
|
||||
|
||||
// ends with ][foreign_currency_id]
|
||||
$.each($('input[name$="][foreign_currency_id]"]'), function (i, v) {
|
||||
var input = $(v);
|
||||
input.attr('name', 'transactions[' + i + '][foreign_currency_id]');
|
||||
});
|
||||
|
||||
// ends with ][budget_id]
|
||||
$.each($('select[name$="][budget_id]"]'), function (i, v) {
|
||||
var input = $(v);
|
||||
input.attr('name', 'transactions[' + i + '][budget_id]');
|
||||
});
|
||||
|
||||
// ends with ][category]
|
||||
$.each($('input[name$="][category]"]'), function (i, v) {
|
||||
var input = $(v);
|
||||
|
@ -962,6 +962,7 @@ return [
|
||||
'split_this_transfer' => 'Split this transfer',
|
||||
'cannot_edit_multiple_source' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple source accounts.',
|
||||
'cannot_edit_multiple_dest' => 'You cannot edit splitted transaction #:id with description ":description" because it contains multiple destination accounts.',
|
||||
'cannot_edit_opening_balance' => 'You cannot edit the opening balance of an account.',
|
||||
'no_edit_multiple_left' => 'You have selected no valid transactions to edit.',
|
||||
|
||||
// import
|
||||
|
@ -14,10 +14,8 @@
|
||||
{{ transaction.description }}
|
||||
{% endif %}
|
||||
<span class="pull-right small">
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
|
@ -64,14 +64,11 @@
|
||||
<span style="margin-right:5px;">
|
||||
{% if transaction.transaction_type_type == 'Transfer' %}
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatByCode(transaction.transaction_currency_code, steam_positive(transaction.transaction_amount)) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
{# TODO format amount of transaction. #}
|
||||
{# TODO format: Amount of transaction (amount in foreign) / total (total foreign) #}
|
||||
XX.XX
|
||||
{% else %}
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
XX.XX
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
|
@ -45,10 +45,8 @@
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
</td>
|
||||
<td class="hidden-sm hidden-xs">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
|
@ -59,10 +59,8 @@
|
||||
</td>
|
||||
<td class="hide-balance_before" style="text-align: right;">{{ transaction.before|formatAmount }}</td>
|
||||
<td class="hide-amount" style="text-align: right;">
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
</td>
|
||||
<td class="hide-balance_after" style="text-align: right;">{{ transaction.after|formatAmount }}</td>
|
||||
|
||||
|
@ -62,17 +62,8 @@
|
||||
</td>
|
||||
<td style="text-align: right;">
|
||||
<span style="margin-right:5px;">
|
||||
{% if transaction.transaction_type_type == 'Transfer' %}
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatByCode(transaction.transaction_currency_code, steam_positive(transaction.transaction_amount)) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
{% else %}
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
{% endif %}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
</span>
|
||||
|
||||
</td>
|
||||
|
@ -39,10 +39,8 @@
|
||||
|
||||
</td>
|
||||
<td data-value="{{ transaction.transaction_amount }}">
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
|
||||
|
||||
</td>
|
||||
|
@ -43,7 +43,8 @@
|
||||
<a href="{{ route('transactions.show',journal.id) }}" title="{{ journal.description }}">{{ journal.description }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ journal|formatJournal }}
|
||||
{# TODO fix amount display #}
|
||||
XX.XX
|
||||
</td>
|
||||
<td>
|
||||
{{ journal.date.formatLocalized(monthAndDayFormat) }}
|
||||
|
@ -47,11 +47,20 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">{{ journal.transactionCurrency.symbol }}</span>
|
||||
<span class="input-group-addon">{{ journal.currency_symbol }}</span>
|
||||
<input name="amount[{{ journal.id }}]" class="form-control" autocomplete="off"
|
||||
step="any" type="number" value="{{ journal.amount }}">
|
||||
<input type="hidden" name="transaction_currency_id[{{ journal.id }}]" value="{{ journal.transaction_currency_id }}">
|
||||
</div>
|
||||
|
||||
{% if journal.foreign_amount %}
|
||||
{# insert foreign data #}
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">{{ journal.foreign_currency.symbol }}</span>
|
||||
<input name="foreign_amount[{{ journal.id }}]" class="form-control" autocomplete="off"
|
||||
step="any" type="number" value="{{ journal.foreign_amount }}">
|
||||
<input type="hidden" name="foreign_currency_id[{{ journal.id }}]" value="{{ journal.foreign_currency.id }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{# DATE #}
|
||||
|
@ -36,14 +36,9 @@
|
||||
<!-- total amount -->
|
||||
<tr>
|
||||
<td>{{ 'total_amount'|_ }}</td>
|
||||
<td>{{ journal|formatJournal }}
|
||||
{% if journal.hasMeta('foreign_amount') %}
|
||||
{% if journal.transactiontype.type == 'Withdrawal' %}
|
||||
({{ formatAnything(foreignCurrency, journal.getMeta('foreign_amount')*-1) }})
|
||||
{% else %}
|
||||
({{ formatAnything(foreignCurrency, journal.getMeta('foreign_amount')) }})
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<td>
|
||||
{# TODO fix amount display #}
|
||||
XX.XX
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -304,9 +299,8 @@
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
{{ formatAnything(journal.transactionCurrency, transaction.source_account_before) }}
|
||||
⟶ {{ formatAnything(journal.transactionCurrency, transaction.source_account_after) }}
|
||||
{# TODO replace with new display: #}
|
||||
XX.XX
|
||||
</td>
|
||||
<td>
|
||||
{% if transaction.destination_account_type == 'Cash account' %}
|
||||
@ -317,25 +311,27 @@
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
{{ formatAnything(journal.transactionCurrency, transaction.destination_account_before) }}
|
||||
⟶ {{ formatAnything(journal.transactionCurrency, transaction.destination_account_after) }}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
</td>
|
||||
<td>
|
||||
{% if journal.transactiontype.type == 'Deposit' %}
|
||||
<!-- deposit, positive amount with correct currency -->
|
||||
{{ formatAnything(journal.transactionCurrency, transaction.destination_amount) }}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
|
||||
{% endif %}
|
||||
{% if journal.transactiontype.type == 'Withdrawal' %}
|
||||
<!-- withdrawal, negative amount with correct currency -->
|
||||
{{ formatAnything(journal.transactionCurrency, transaction.source_amount) }}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
|
||||
{% endif %}
|
||||
{% if journal.transactiontype.type == 'Transfer' %}
|
||||
<!-- transfer, positive amount in blue -->
|
||||
<span class="text-info">
|
||||
{{ formatAnythingPlain(journal.transactionCurrency, transaction.destination_amount) }}
|
||||
{# TODO replace with new format code #}
|
||||
XX.XX
|
||||
</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
@ -64,9 +64,9 @@
|
||||
|
||||
{{ ExpandedForm.nonSelectableAmount('native_amount', data.native_amount, {currency: data.native_currency}) }}
|
||||
|
||||
{{ ExpandedForm.nonSelectableAmount('source_amount', data.native_amount, {currency: data.native_currency }) }}
|
||||
{{ ExpandedForm.nonSelectableAmount('source_amount', data.source_amount, {currency: data.source_currency }) }}
|
||||
|
||||
{{ ExpandedForm.nonSelectableAmount('destination_amount', data.amount, {currency: data.currency }) }}
|
||||
{{ ExpandedForm.nonSelectableAmount('destination_amount', data.destination_amount, {currency: data.destination_currency }) }}
|
||||
|
||||
{# ALWAYS SHOW DATE #}
|
||||
{{ ExpandedForm.date('date',data['date']) }}
|
||||
|
@ -40,9 +40,6 @@
|
||||
{# DESCRIPTION IS ALWAYS AVAILABLE #}
|
||||
{{ ExpandedForm.text('journal_description', journal.description) }}
|
||||
|
||||
{# CURRENCY IS NEW FOR SPLIT JOURNALS #}
|
||||
{{ ExpandedForm.select('currency_id', currencies, preFilled.currency_id) }}
|
||||
|
||||
{# show source if withdrawal or transfer #}
|
||||
{% if preFilled.what == 'withdrawal' or preFilled.what == 'transfer' %}
|
||||
{{ ExpandedForm.select('journal_source_account_id', assetAccounts, preFilled.journal_source_account_id) }}
|
||||
@ -59,6 +56,7 @@
|
||||
{% endif %}
|
||||
|
||||
{# TOTAL AMOUNT IS STATIC TEXT #}
|
||||
{# TODO this does not reflect the actual currency (currencies) #}
|
||||
{{ ExpandedForm.staticText('journal_amount', preFilled.journal_amount|formatAmount ) }}
|
||||
<input type="hidden" name="journal_amount" value="{{ preFilled.journal_amount }}"/>
|
||||
|
||||
@ -204,7 +202,7 @@
|
||||
<th>{{ trans('list.source') }}</th>
|
||||
{% endif %}
|
||||
|
||||
<th>{{ trans('list.amount') }}</th>
|
||||
<th colspan="2">{{ trans('list.amount') }}</th>
|
||||
|
||||
{# only withdrawal has budget #}
|
||||
{% if preFilled.what == 'withdrawal' %}
|
||||
@ -234,7 +232,7 @@
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<!-- deposit has several source names -->
|
||||
{# deposit has several source names #}
|
||||
{% if preFilled.what == 'deposit' %}
|
||||
<td>
|
||||
<input type="text" name="transactions[{{ loop.index0 }}][source_account_name]"
|
||||
@ -243,10 +241,26 @@
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{# two fields for amount #}
|
||||
<td style="width:10%;">
|
||||
<input type="number" name="transactions[{{ loop.index0 }}][amount]" value="{{ transaction.amount }}"
|
||||
class="form-control" autocomplete="off" step="any" min="0.01">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">{{ transaction.transaction_currency_symbol }}</div>
|
||||
<input type="number" name="transactions[{{ loop.index0 }}][amount]" value="{{ transaction.amount }}"
|
||||
class="form-control" autocomplete="off" step="any" min="0.01">
|
||||
</div>
|
||||
<input type="hidden" name="transactions[{{ loop.index0 }}][transaction_currency_id]" value="{{ transaction.transaction_currency_id }}">
|
||||
</td>
|
||||
{# foreign amount #}
|
||||
<td style="width:10%;">
|
||||
{% if transaction.foreign_amount != null %}
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon">{{ transaction.foreign_currency_symbol }}</div>
|
||||
<input type="number" name="transactions[{{ loop.index0 }}][foreign_amount]"
|
||||
value="{{ transaction.foreign_amount }}"
|
||||
class="form-control" autocomplete="off" step="any" min="0.01">
|
||||
</div>
|
||||
<input type="hidden" name="transactions[{{ loop.index0 }}][foreign_currency_id]" value="{{ transaction.foreign_currency_id }}">
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
{% if preFilled.what == 'withdrawal' %}
|
||||
|
Loading…
Reference in New Issue
Block a user