mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Code for 4.1.6
This commit is contained in:
parent
124ecb1372
commit
69422cc796
14
CHANGELOG.md
14
CHANGELOG.md
@ -2,6 +2,20 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [4.1.6] - 2016-11-06
|
||||
### Added
|
||||
- New budget table for multi year report.
|
||||
|
||||
### Changed
|
||||
- Greatly expanded help pages and their function.
|
||||
- Built a new transaction collector, which I think was the idea of @roberthorlings originally.
|
||||
- Rebuilt seach engine.
|
||||
|
||||
### Fixed
|
||||
- #375, thanks to @schoentoon which made it impossible to resurrect currencies.
|
||||
- #370 thanks to @ksmolder
|
||||
- #378, thanks to @HomelessAvatar
|
||||
|
||||
## [4.1.5] - 2016-11-01
|
||||
### Changed
|
||||
- Report parts are loaded using AJAX, making a lot of code more simple.
|
||||
|
@ -66,7 +66,7 @@ class Import extends Command
|
||||
return;
|
||||
}
|
||||
|
||||
$this->line('Going to import job with key "' . $job->key . '" of type ' . $job->file_type);
|
||||
$this->line(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type));
|
||||
|
||||
$monolog = Log::getMonolog();
|
||||
$handler = new CommandHandler($this);
|
||||
|
86
app/Console/Commands/MoveRepository.php
Normal file
86
app/Console/Commands/MoveRepository.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
* MoveRepository.php
|
||||
* Copyright (C) 2016 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\Console\Commands;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class MoveRepository
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class MoveRepository extends Command
|
||||
{
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Alerts the user that the Github repository will move, if they are interested to know this.';
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly:github-move';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$moveDate = new Carbon('2017-01-01');
|
||||
$final = new Carbon('2017-03-01');
|
||||
$now = new Carbon;
|
||||
|
||||
// display message before 2017-01-01
|
||||
if ($moveDate > $now) {
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
$this->line('');
|
||||
$this->line('The Github repository for Firefly III will MOVE');
|
||||
$this->line('This move will be on January 1st 2017');
|
||||
$this->line('');
|
||||
$this->error('READ THIS WIKI PAGE FOR MORE INFORMATION');
|
||||
$this->line('');
|
||||
$this->info('https://github.com/firefly-iii/help/wiki/New-Github-repository');
|
||||
$this->line('');
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
}
|
||||
|
||||
// display message after 2017-01-01 but before 2017-03-01
|
||||
if ($moveDate <= $now && $now <= $final) {
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
$this->line('');
|
||||
$this->line('The Github repository for Firefly III has MOVED');
|
||||
$this->line('This move was on January 1st 2017!');
|
||||
$this->line('');
|
||||
$this->error('READ THIS WIKI PAGE FOR MORE INFORMATION');
|
||||
$this->line('');
|
||||
$this->info('https://github.com/firefly-iii/help/wiki/New-Github-repository');
|
||||
$this->line('');
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -99,7 +99,7 @@ class UpgradeDatabase extends Command
|
||||
} catch (QueryException $e) {
|
||||
Log::error($e->getMessage());
|
||||
$this->error('Firefly III could not find the "identifier" field in the "transactions" table.');
|
||||
$this->error('This field is required for Firefly III version ' . config('firefly.version') . ' to run.');
|
||||
$this->error(sprintf('This field is required for Firefly III version %s to run.', config('firefly.version')));
|
||||
$this->error('Please run "php artisan migrate" to add this field to the table.');
|
||||
$this->info('Then, run "php artisan firefly:upgrade-database" to try again.');
|
||||
break 2;
|
||||
|
@ -63,21 +63,20 @@ class UpgradeFireflyInstructions extends Command
|
||||
|
||||
}
|
||||
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
$this->line('');
|
||||
|
||||
if (is_null($text)) {
|
||||
$this->line('Thank you for installing Firefly III, v' . $version);
|
||||
$this->line(sprintf('Thank you for installing Firefly III, v%s', $version));
|
||||
$this->info('There are no extra upgrade instructions.');
|
||||
$this->line('Firefly III should be ready for use.');
|
||||
} else {
|
||||
$this->line('Thank you for installing Firefly III, v' . $version);
|
||||
$this->line('If you are upgrading from a previous version,');
|
||||
$this->line('please follow these upgrade instructions carefully:');
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
$this->line('');
|
||||
$this->line(sprintf('Thank you for installing Firefly III, v%s', $version));
|
||||
$this->info(wordwrap($text));
|
||||
$this->line('');
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
}
|
||||
|
||||
$this->line('');
|
||||
$this->line('+------------------------------------------------------------------------------+');
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -127,8 +127,11 @@ class VerifyDatabase extends Command
|
||||
|
||||
/** @var stdClass $entry */
|
||||
foreach ($set as $entry) {
|
||||
$line = 'Notice: User #' . $entry->user_id . ' (' . $entry->email . ') has budget #' . $entry->id . ' ("' . Crypt::decrypt($entry->name)
|
||||
. '") which has no budget limits.';
|
||||
|
||||
$line = sprintf(
|
||||
'Notice: User #%d (%s) has budget #%d ("%s") which has no budget limits.',
|
||||
$entry->user_id, $entry->email, $entry->id, Crypt::decrypt($entry->name)
|
||||
);
|
||||
$this->line($line);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ namespace FireflyIII\Console;
|
||||
use FireflyIII\Console\Commands\CreateImport;
|
||||
use FireflyIII\Console\Commands\EncryptFile;
|
||||
use FireflyIII\Console\Commands\Import;
|
||||
use FireflyIII\Console\Commands\MoveRepository;
|
||||
use FireflyIII\Console\Commands\ScanAttachments;
|
||||
use FireflyIII\Console\Commands\UpgradeDatabase;
|
||||
use FireflyIII\Console\Commands\UpgradeFireflyInstructions;
|
||||
@ -63,7 +64,7 @@ class Kernel extends ConsoleKernel
|
||||
EncryptFile::class,
|
||||
ScanAttachments::class,
|
||||
UpgradeDatabase::class,
|
||||
|
||||
MoveRepository::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* JournalCollector.php
|
||||
* JournalExportCollector.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
@ -21,11 +21,11 @@ use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class JournalCollector
|
||||
* Class JournalExportCollector
|
||||
*
|
||||
* @package FireflyIII\Export\Collector
|
||||
*/
|
||||
class JournalCollector extends BasicCollector implements CollectorInterface
|
||||
class JournalExportCollector extends BasicCollector implements CollectorInterface
|
||||
{
|
||||
/** @var Collection */
|
||||
private $accounts;
|
@ -14,7 +14,6 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Export\Exporter;
|
||||
|
||||
use FireflyIII\Export\Entry\Entry;
|
||||
use FireflyIII\Export\Entry\EntryAccount;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
use League\Csv\Writer;
|
||||
use SplFileObject;
|
||||
|
@ -15,7 +15,7 @@ namespace FireflyIII\Export;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Export\Collector\AttachmentCollector;
|
||||
use FireflyIII\Export\Collector\JournalCollector;
|
||||
use FireflyIII\Export\Collector\JournalExportCollector;
|
||||
use FireflyIII\Export\Collector\UploadCollector;
|
||||
use FireflyIII\Export\Entry\Entry;
|
||||
use FireflyIII\Models\ExportJob;
|
||||
@ -45,8 +45,6 @@ class Processor
|
||||
public $job;
|
||||
/** @var array */
|
||||
public $settings;
|
||||
/** @var \FireflyIII\Export\ConfigurationFile */
|
||||
private $configurationMaker;
|
||||
/** @var Collection */
|
||||
private $exportEntries;
|
||||
/** @var Collection */
|
||||
@ -93,8 +91,8 @@ class Processor
|
||||
*/
|
||||
public function collectJournals(): bool
|
||||
{
|
||||
/** @var JournalCollector $collector */
|
||||
$collector = app(JournalCollector::class, [$this->job]);
|
||||
/** @var JournalExportCollector $collector */
|
||||
$collector = app(JournalExportCollector::class, [$this->job]);
|
||||
$collector->setDates($this->settings['startDate'], $this->settings['endDate']);
|
||||
$collector->setAccounts($this->settings['accounts']);
|
||||
$collector->run();
|
||||
|
@ -14,7 +14,7 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Generator\Chart\Bill;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@ -61,13 +61,13 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
|
||||
$minAmount = [];
|
||||
$maxAmount = [];
|
||||
$actualAmount = [];
|
||||
/** @var TransactionJournal $entry */
|
||||
/** @var Transaction $entry */
|
||||
foreach ($entries as $entry) {
|
||||
$data['labels'][] = $entry->date->formatLocalized($format);
|
||||
$minAmount[] = round($bill->amount_min, 2);
|
||||
$maxAmount[] = round($bill->amount_max, 2);
|
||||
// journalAmount has been collected in BillRepository::getJournals
|
||||
$actualAmount[] = round(TransactionJournal::amountPositive($entry), 2);
|
||||
$actualAmount[] = bcmul($entry->transaction_amount, '-1');
|
||||
}
|
||||
|
||||
$data['datasets'][] = [
|
||||
|
@ -21,6 +21,7 @@ use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\Support\Events\BillScanner;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class StoredJournalEventHandler
|
||||
@ -42,30 +43,69 @@ class StoredJournalEventHandler
|
||||
$journal = $event->journal;
|
||||
$piggyBankId = $event->piggyBankId;
|
||||
|
||||
Log::debug(sprintf('Trying to connect journal %d to piggy bank %d.', $journal->id, $piggyBankId));
|
||||
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = $journal->user->piggyBanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
|
||||
|
||||
if (is_null($piggyBank)) {
|
||||
Log::error('No such piggy bank!');
|
||||
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('Found piggy bank #%d: "%s"', $piggyBank->id, $piggyBank->name));
|
||||
// update piggy bank rep for date of transaction journal.
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
if (is_null($repetition)) {
|
||||
Log::error(sprintf('No piggy bank repetition on %s!', $journal->date->format('Y-m-d')));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$amount = TransactionJournal::amountPositive($journal);
|
||||
Log::debug(sprintf('Will add/remove %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
|
||||
// if piggy account matches source account, the amount is positive
|
||||
$sources = TransactionJournal::sourceAccountList($journal)->pluck('id')->toArray();
|
||||
if (in_array($piggyBank->account_id, $sources)) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
Log::debug(sprintf('Account #%d is the source, so will remove amount from piggy bank.', $piggyBank->account_id));
|
||||
}
|
||||
|
||||
// if the amount is positive:
|
||||
// make sure it fits in piggy bank:
|
||||
if (bccomp($amount, '0') === 1) {
|
||||
// amount is positive
|
||||
$room = bcsub(strval($piggyBank->targetamount), strval($repetition->currentamount));
|
||||
Log::debug(sprintf('Room in piggy bank for extra money is %f', $room));
|
||||
if (bccomp($room, $amount) === -1) {
|
||||
// $room is smaller than $amount
|
||||
Log::debug(sprintf('There is NO room to add %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
|
||||
Log::debug(sprintf('New amount is %f', $room));
|
||||
$amount = $room;
|
||||
}
|
||||
}
|
||||
|
||||
if (bccomp($amount, '0') === -1) {
|
||||
// amount is negative
|
||||
Log::debug(sprintf('Max amount to remove is %f', $repetition->currentamount));
|
||||
$compare = bcmul($repetition->currentamount, '-1');
|
||||
if (bccomp($compare, $amount) === 1) {
|
||||
// $currentamount is smaller than $amount
|
||||
Log::debug(sprintf('Cannot remove %f from piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
|
||||
Log::debug(sprintf('New amount is %f', $compare));
|
||||
$amount = $compare;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $amount);
|
||||
$repetition->save();
|
||||
|
||||
PiggyBankEvent::create(['piggy_bank_id' => $piggyBank->id, 'transaction_journal_id' => $journal->id, 'date' => $journal->date, 'amount' => $amount]);
|
||||
/** @var PiggyBankEvent $event */
|
||||
$event = PiggyBankEvent::create(
|
||||
['piggy_bank_id' => $piggyBank->id, 'transaction_journal_id' => $journal->id, 'date' => $journal->date, 'amount' => $amount]
|
||||
);
|
||||
Log::debug(sprintf('Created piggy bank event #%d', $event->id));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -15,11 +15,8 @@ namespace FireflyIII\Handlers\Events;
|
||||
|
||||
|
||||
use FireflyIII\Events\UpdatedTransactionJournal;
|
||||
use FireflyIII\Models\PiggyBankEvent;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\Support\Events\BillScanner;
|
||||
|
||||
@ -30,50 +27,6 @@ use FireflyIII\Support\Events\BillScanner;
|
||||
*/
|
||||
class UpdatedJournalEventHandler
|
||||
{
|
||||
/**
|
||||
* This method will try to reconnect a journal to a piggy bank, updating the piggy bank repetition.
|
||||
*
|
||||
* @param UpdatedTransactionJournal $event
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function connectToPiggyBank(UpdatedTransactionJournal $event): bool
|
||||
{
|
||||
$journal = $event->journal;
|
||||
|
||||
if (!$journal->isTransfer()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// get the event connected to this journal:
|
||||
/** @var PiggyBankEvent $event */
|
||||
$event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first();
|
||||
if (is_null($event)) {
|
||||
return false;
|
||||
}
|
||||
$piggyBank = $event->piggyBank()->first();
|
||||
$repetition = null;
|
||||
if (!is_null($piggyBank)) {
|
||||
/** @var PiggyBankRepetition $repetition */
|
||||
$repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first();
|
||||
}
|
||||
|
||||
if (is_null($repetition)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$amount = TransactionJournal::amount($journal);
|
||||
$diff = bcsub($amount, $event->amount); // update current repetition
|
||||
|
||||
$repetition->currentamount = bcadd($repetition->currentamount, $diff);
|
||||
$repetition->save();
|
||||
|
||||
|
||||
$event->amount = $amount;
|
||||
$event->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will check all the rules when a journal is updated.
|
||||
|
@ -17,10 +17,8 @@ use FireflyIII\Models\Attachment;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Input;
|
||||
use Log;
|
||||
use Storage;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Class AttachmentHelper
|
||||
@ -236,13 +234,8 @@ class AttachmentHelper implements AttachmentHelperInterface
|
||||
private function getFiles()
|
||||
{
|
||||
$files = null;
|
||||
try {
|
||||
if (Input::hasFile('attachments')) {
|
||||
$files = Input::file('attachments');
|
||||
}
|
||||
} catch (TypeError $e) {
|
||||
// Log it, do nothing else.
|
||||
Log::error($e->getMessage());
|
||||
if (Input::hasFile('attachments')) {
|
||||
$files = Input::file('attachments');
|
||||
}
|
||||
|
||||
return $files;
|
||||
|
485
app/Helpers/Collector/JournalCollector.php
Normal file
485
app/Helpers/Collector/JournalCollector.php
Normal file
@ -0,0 +1,485 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Helpers\Collector;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Maybe this is a good idea after all...
|
||||
*
|
||||
* Class JournalCollector
|
||||
*
|
||||
* @package FireflyIII\Helpers\Collector
|
||||
*/
|
||||
class JournalCollector
|
||||
{
|
||||
|
||||
/** @var int */
|
||||
private $count = 0;
|
||||
|
||||
/** @var array */
|
||||
private $fields
|
||||
= [
|
||||
'transaction_journals.id as journal_id',
|
||||
'transaction_journals.description',
|
||||
'transaction_journals.date',
|
||||
'transaction_journals.encrypted',
|
||||
//'transaction_journals.transaction_currency_id',
|
||||
'transaction_currencies.code as transaction_currency_code',
|
||||
//'transaction_currencies.symbol as transaction_currency_symbol',
|
||||
'transaction_types.type as transaction_type_type',
|
||||
'transaction_journals.bill_id',
|
||||
'bills.name as bill_name',
|
||||
'transactions.id as id',
|
||||
'transactions.amount as transaction_amount',
|
||||
'transactions.description as transaction_description',
|
||||
'transactions.account_id',
|
||||
'transactions.identifier',
|
||||
'transactions.transaction_journal_id',
|
||||
'accounts.name as account_name',
|
||||
'accounts.encrypted as account_encrypted',
|
||||
'account_types.type as account_type',
|
||||
];
|
||||
/** @var bool */
|
||||
private $filterTransfers = false;
|
||||
/** @var bool */
|
||||
private $joinedBudget = false;
|
||||
/** @var bool */
|
||||
private $joinedCategory = false;
|
||||
/** @var bool */
|
||||
private $joinedTag = false;
|
||||
/** @var int */
|
||||
private $limit;
|
||||
/** @var int */
|
||||
private $offset;
|
||||
/** @var int */
|
||||
private $page = 1;
|
||||
/** @var EloquentBuilder */
|
||||
private $query;
|
||||
/** @var bool */
|
||||
private $run = false;
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* JournalCollector constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->query = $this->startQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
if ($this->run === true) {
|
||||
throw new FireflyException('Cannot count after run in JournalCollector.');
|
||||
}
|
||||
|
||||
$countQuery = clone $this->query;
|
||||
|
||||
// dont need some fields:
|
||||
$countQuery->getQuery()->limit = null;
|
||||
$countQuery->getQuery()->offset = null;
|
||||
$countQuery->getQuery()->unionLimit = null;
|
||||
$countQuery->getQuery()->groups = null;
|
||||
$countQuery->getQuery()->orders = null;
|
||||
$countQuery->groupBy('accounts.user_id');
|
||||
$this->count = $countQuery->count();
|
||||
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournals(): Collection
|
||||
{
|
||||
$this->run = true;
|
||||
$set = $this->query->get(array_values($this->fields));
|
||||
$set = $this->filterTransfers($set);
|
||||
|
||||
// loop for decryption.
|
||||
$set->each(
|
||||
function (Transaction $transaction) {
|
||||
$transaction->date = new Carbon($transaction->date);
|
||||
$transaction->description = intval($transaction->encrypted) === 1 ? Crypt::decrypt($transaction->description) : $transaction->description;
|
||||
$transaction->bill_name = !is_null($transaction->bill_name) ? Crypt::decrypt($transaction->bill_name) : '';
|
||||
}
|
||||
);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LengthAwarePaginator
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function getPaginatedJournals():LengthAwarePaginator
|
||||
{
|
||||
if ($this->run === true) {
|
||||
throw new FireflyException('Cannot getPaginatedJournals after run in JournalCollector.');
|
||||
}
|
||||
$this->count();
|
||||
$set = $this->getJournals();
|
||||
$journals = new LengthAwarePaginator($set, $this->count, $this->limit, $this->page);
|
||||
|
||||
return $journals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setAccounts(Collection $accounts): JournalCollector
|
||||
{
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$this->query->whereIn('transactions.account_id', $accountIds);
|
||||
}
|
||||
|
||||
if ($accounts->count() > 1) {
|
||||
$this->filterTransfers = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setAllAssetAccounts(): JournalCollector
|
||||
{
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class, [$this->user]);
|
||||
$accounts = $repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]);
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$this->query->whereIn('transactions.account_id', $accountIds);
|
||||
}
|
||||
|
||||
if ($accounts->count() > 1) {
|
||||
$this->filterTransfers = true;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $bills
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setBills(Collection $bills): JournalCollector
|
||||
{
|
||||
if ($bills->count() > 0) {
|
||||
$billIds = $bills->pluck('id')->toArray();
|
||||
$this->query->whereIn('transaction_journals.bill_id', $billIds);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setBudget(Budget $budget): JournalCollector
|
||||
{
|
||||
$this->joinBudgetTables();
|
||||
|
||||
$this->query->where(
|
||||
function (EloquentBuilder $q) use ($budget) {
|
||||
$q->where('budget_transaction.budget_id', $budget->id);
|
||||
$q->orWhere('budget_transaction_journal.budget_id', $budget->id);
|
||||
}
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setCategory(Category $category): JournalCollector
|
||||
{
|
||||
$this->joinCategoryTables();
|
||||
|
||||
$this->query->where(
|
||||
function (EloquentBuilder $q) use ($category) {
|
||||
$q->where('category_transaction.category_id', $category->id);
|
||||
$q->orWhere('category_transaction_journal.category_id', $category->id);
|
||||
}
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setLimit(int $limit): JournalCollector
|
||||
{
|
||||
$this->limit = $limit;
|
||||
$this->query->limit($limit);
|
||||
Log::debug(sprintf('Set limit to %d', $limit));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setOffset(int $offset): JournalCollector
|
||||
{
|
||||
$this->offset = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setPage(int $page): JournalCollector
|
||||
{
|
||||
$this->page = $page;
|
||||
|
||||
if ($page > 0) {
|
||||
$page--;
|
||||
}
|
||||
Log::debug(sprintf('Page is %d', $page));
|
||||
|
||||
if (!is_null($this->limit)) {
|
||||
$offset = ($this->limit * $page);
|
||||
$this->offset = $offset;
|
||||
$this->query->skip($offset);
|
||||
Log::debug(sprintf('Changed offset to %d', $offset));
|
||||
}
|
||||
if (is_null($this->limit)) {
|
||||
Log::debug('The limit is zero, cannot set the page.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setRange(Carbon $start, Carbon $end): JournalCollector
|
||||
{
|
||||
if ($start <= $end) {
|
||||
$this->query->where('transaction_journals.date', '>=', $start->format('Y-m-d'));
|
||||
$this->query->where('transaction_journals.date', '<=', $end->format('Y-m-d'));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Tag $tag
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setTag(Tag $tag): JournalCollector
|
||||
{
|
||||
$this->joinTagTables();
|
||||
$this->query->where('tag_transaction_journal.tag_id', $tag->id);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function setTypes(array $types): JournalCollector
|
||||
{
|
||||
if (count($types) > 0) {
|
||||
$this->query->whereIn('transaction_types.type', $types);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function withoutBudget(): JournalCollector
|
||||
{
|
||||
$this->joinBudgetTables();
|
||||
|
||||
$this->query->where(
|
||||
function (EloquentBuilder $q) {
|
||||
$q->whereNull('budget_transaction.budget_id');
|
||||
$q->whereNull('budget_transaction_journal.budget_id');
|
||||
}
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JournalCollector
|
||||
*/
|
||||
public function withoutCategory(): JournalCollector
|
||||
{
|
||||
$this->joinCategoryTables();
|
||||
|
||||
$this->query->where(
|
||||
function (EloquentBuilder $q) {
|
||||
$q->whereNull('category_transaction.category_id');
|
||||
$q->whereNull('category_transaction_journal.category_id');
|
||||
}
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the set of accounts used by the collector includes more than one asset
|
||||
* account, chances are the set include double entries: transfers get selected
|
||||
* on both the source, and then again on the destination account.
|
||||
*
|
||||
* This method filters them out.
|
||||
*
|
||||
* @param Collection $set
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
private function filterTransfers(Collection $set): Collection
|
||||
{
|
||||
if ($this->filterTransfers) {
|
||||
$set = $set->filter(
|
||||
function (Transaction $transaction) {
|
||||
if (!($transaction->transaction_type_type === TransactionType::TRANSFER && bccomp($transaction->transaction_amount, '0') === -1)) {
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Included journal #%d (transaction #%d) because its a %s with amount %f',
|
||||
$transaction->transaction_journal_id,
|
||||
$transaction->id,
|
||||
$transaction->transaction_type_type,
|
||||
$transaction->transaction_amount
|
||||
)
|
||||
);
|
||||
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
Log::debug(
|
||||
sprintf(
|
||||
'Removed journal #%d (transaction #%d) because its a %s with amount %f',
|
||||
$transaction->transaction_journal_id,
|
||||
$transaction->id,
|
||||
$transaction->transaction_type_type,
|
||||
$transaction->transaction_amount
|
||||
)
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function joinBudgetTables()
|
||||
{
|
||||
if (!$this->joinedBudget) {
|
||||
// join some extra tables:
|
||||
$this->joinedBudget = true;
|
||||
$this->query->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
$this->query->leftJoin('budget_transaction', 'budget_transaction.transaction_id', '=', 'transactions.id');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function joinCategoryTables()
|
||||
{
|
||||
if (!$this->joinedCategory) {
|
||||
// join some extra tables:
|
||||
$this->joinedCategory = true;
|
||||
$this->query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
$this->query->leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function joinTagTables()
|
||||
{
|
||||
if (!$this->joinedTag) {
|
||||
// join some extra tables:
|
||||
$this->joinedTag = true;
|
||||
$this->query->leftJoin('tag_transaction_journal', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EloquentBuilder
|
||||
*/
|
||||
private function startQuery(): EloquentBuilder
|
||||
{
|
||||
|
||||
$query = Transaction
|
||||
::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->leftJoin('transaction_currencies', 'transaction_currencies.id', 'transaction_journals.transaction_currency_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin('bills', 'bills.id', 'transaction_journals.bill_id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin('account_types', 'accounts.account_type_id', 'account_types.id')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->where('transaction_journals.user_id', $this->user->id)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC');
|
||||
|
||||
return $query;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,8 @@ use Route;
|
||||
*/
|
||||
class Help implements HelpInterface
|
||||
{
|
||||
/** @var string */
|
||||
protected $userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36';
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
@ -35,7 +37,9 @@ class Help implements HelpInterface
|
||||
*/
|
||||
public function getFromCache(string $route, string $language): string
|
||||
{
|
||||
return Cache::get('help.' . $route . '.' . $language);
|
||||
$line = sprintf('help.%s.%s', $route, $language);
|
||||
|
||||
return Cache::get($line);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,9 +53,10 @@ class Help implements HelpInterface
|
||||
|
||||
$uri = sprintf('https://raw.githubusercontent.com/firefly-iii/help/master/%s/%s.md', $language, $route);
|
||||
Log::debug(sprintf('Trying to get %s...', $uri));
|
||||
$opt = ['useragent' => $this->userAgent];
|
||||
$content = '';
|
||||
try {
|
||||
$result = Requests::get($uri);
|
||||
$result = Requests::get($uri, [], $opt);
|
||||
} catch (Requests_Exception $e) {
|
||||
Log::error($e);
|
||||
|
||||
@ -69,6 +74,9 @@ class Help implements HelpInterface
|
||||
$converter = new CommonMarkConverter();
|
||||
$content = $converter->convertToHtml($content);
|
||||
}
|
||||
if (strlen($content) === 0) {
|
||||
Log::warning('Raw content length is zero.');
|
||||
}
|
||||
|
||||
return $content;
|
||||
|
||||
@ -93,7 +101,8 @@ class Help implements HelpInterface
|
||||
*/
|
||||
public function inCache(string $route, string $language):bool
|
||||
{
|
||||
$result = Cache::has('help.' . $route . '.' . $language);
|
||||
$line = sprintf('help.%s.%s', $route, $language);
|
||||
$result = Cache::has($line);
|
||||
if ($result) {
|
||||
Log::debug(sprintf('Cache has this entry: %s', 'help.' . $route . '.' . $language));
|
||||
}
|
||||
@ -115,8 +124,12 @@ class Help implements HelpInterface
|
||||
*/
|
||||
public function putInCache(string $route, string $language, string $content)
|
||||
{
|
||||
$key = 'help.' . $route . '.' . $language;
|
||||
Log::debug(sprintf('Will store entry in cache: %s', $key));
|
||||
Cache::put($key, $content, 10080); // a week.
|
||||
$key = sprintf('help.%s.%s', $route, $language);
|
||||
if (strlen($content) > 0) {
|
||||
Log::debug(sprintf('Will store entry in cache: %s', $key));
|
||||
Cache::put($key, $content, 10080); // a week.
|
||||
return;
|
||||
}
|
||||
Log::info(sprintf('Will not cache %s because content is empty.', $key));
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ interface HelpInterface
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function inCache(string $route, string $language ): bool;
|
||||
public function inCache(string $route, string $language): bool;
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
|
@ -15,13 +15,17 @@ namespace FireflyIII\Helpers\Report;
|
||||
|
||||
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use FireflyIII\Helpers\Collection\Budget as BudgetCollection;
|
||||
use FireflyIII\Helpers\Collection\BudgetLine;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class BudgetReportHelper
|
||||
@ -97,6 +101,66 @@ class BudgetReportHelper implements BudgetReportHelperInterface
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBudgetMultiYear(Carbon $start, Carbon $end, Collection $accounts): array
|
||||
{
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$query = TransactionJournal
|
||||
::leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->where('transaction_journals.user_id', auth()->user()->id);
|
||||
|
||||
if (count($accountIds) > 0) {
|
||||
$query->whereIn('transactions.account_id', $accountIds);
|
||||
}
|
||||
$query->groupBy(['budget_transaction_journal.budget_id', 'the_year']);
|
||||
$queryResult = $query->get(
|
||||
[
|
||||
'budget_transaction_journal.budget_id',
|
||||
DB::raw('DATE_FORMAT(transaction_journals.date,"%Y") AS the_year'),
|
||||
DB::raw('SUM(transactions.amount) as sum_of_period'),
|
||||
]
|
||||
);
|
||||
|
||||
$data = [];
|
||||
$budgets = $this->repository->getBudgets();
|
||||
$years = $this->listOfYears($start, $end);
|
||||
|
||||
// do budget "zero"
|
||||
$emptyBudget = new Budget;
|
||||
$emptyBudget->id = 0;
|
||||
$emptyBudget->name = strval(trans('firefly.no_budget'));
|
||||
$budgets->push($emptyBudget);
|
||||
|
||||
|
||||
// get all budgets and years.
|
||||
foreach ($budgets as $budget) {
|
||||
$data[$budget->id] = [
|
||||
'name' => $budget->name,
|
||||
'entries' => $this->filterAmounts($queryResult, $budget->id, $years),
|
||||
'sum' => '0',
|
||||
];
|
||||
}
|
||||
// filter out empty ones and fill sum:
|
||||
$data = $this->getBudgetMultiYearMeta($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
@ -183,30 +247,21 @@ class BudgetReportHelper implements BudgetReportHelperInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the array as returned by CategoryRepositoryInterface::spentPerDay and CategoryRepositoryInterface::earnedByDay
|
||||
* and sum up everything in the array in the given range.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
protected function getSumOfRange(Carbon $start, Carbon $end, array $array)
|
||||
public function listOfYears(Carbon $start, Carbon $end): array
|
||||
{
|
||||
$sum = '0';
|
||||
$currentStart = clone $start; // to not mess with the original one
|
||||
$currentEnd = clone $end; // to not mess with the original one
|
||||
|
||||
while ($currentStart <= $currentEnd) {
|
||||
$date = $currentStart->format('Y-m-d');
|
||||
if (isset($array[$date])) {
|
||||
$sum = bcadd($sum, $array[$date]);
|
||||
}
|
||||
$currentStart->addDay();
|
||||
$begin = clone $start;
|
||||
$years = [];
|
||||
while ($begin < $end) {
|
||||
$years[] = $begin->year;
|
||||
$begin->addYear();
|
||||
}
|
||||
|
||||
return $sum;
|
||||
return $years;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,6 +302,59 @@ class BudgetReportHelper implements BudgetReportHelperInterface
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $set
|
||||
* @param int $budgetId
|
||||
* @param array $years
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filterAmounts(Collection $set, int $budgetId, array $years):array
|
||||
{
|
||||
$arr = [];
|
||||
foreach ($years as $year) {
|
||||
/** @var stdClass $object */
|
||||
$result = $set->filter(
|
||||
function (TransactionJournal $object) use ($budgetId, $year) {
|
||||
return intval($object->the_year) === $year && $budgetId === intval($object->budget_id);
|
||||
}
|
||||
);
|
||||
$amount = '0';
|
||||
if (!is_null($result->first())) {
|
||||
$amount = $result->first()->sum_of_period;
|
||||
}
|
||||
|
||||
$arr[$year] = $amount;
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getBudgetMultiYearMeta(array $data): array
|
||||
{
|
||||
/**
|
||||
* @var int $budgetId
|
||||
* @var array $set
|
||||
*/
|
||||
foreach ($data as $budgetId => $set) {
|
||||
$sum = '0';
|
||||
foreach ($set['entries'] as $amount) {
|
||||
$sum = bcadd($amount, $sum);
|
||||
}
|
||||
$data[$budgetId]['sum'] = $sum;
|
||||
if (bccomp('0', $sum) === 0) {
|
||||
unset($data[$budgetId]);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $current
|
||||
* @param Carbon $end
|
||||
|
@ -34,6 +34,15 @@ interface BudgetReportHelperInterface
|
||||
*/
|
||||
public function budgetYearOverview(Carbon $start, Carbon $end, Collection $accounts): Collection;
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBudgetMultiYear(Carbon $start, Carbon $end, Collection $accounts): array;
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
@ -52,4 +61,12 @@ interface BudgetReportHelperInterface
|
||||
*/
|
||||
public function getBudgetsWithExpenses(Carbon $start, Carbon $end, Collection $accounts): Collection;
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfYears(Carbon $start, Carbon $end): array;
|
||||
|
||||
}
|
||||
|
@ -14,18 +14,17 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use FireflyIII\Helpers\Collection\Bill as BillCollection;
|
||||
use FireflyIII\Helpers\Collection\BillLine;
|
||||
use FireflyIII\Helpers\Collection\Category as CategoryCollection;
|
||||
use FireflyIII\Helpers\Collection\Expense;
|
||||
use FireflyIII\Helpers\Collection\Income;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Helpers\FiscalHelperInterface;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
@ -79,7 +78,9 @@ class ReportHelper implements ReportHelperInterface
|
||||
/** @var BillRepositoryInterface $repository */
|
||||
$repository = app(BillRepositoryInterface::class);
|
||||
$bills = $repository->getBillsForAccounts($accounts);
|
||||
$journals = $repository->getAllJournalsInRange($bills, $start, $end);
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts($accounts)->setRange($start, $end)->setBills($bills);
|
||||
$journals = $collector->getJournals();
|
||||
$collection = new BillCollection;
|
||||
|
||||
/** @var Bill $bill */
|
||||
@ -93,14 +94,14 @@ class ReportHelper implements ReportHelperInterface
|
||||
// is hit in period?
|
||||
|
||||
$entry = $journals->filter(
|
||||
function (TransactionJournal $journal) use ($bill) {
|
||||
return $journal->bill_id === $bill->id;
|
||||
function (Transaction $transaction) use ($bill) {
|
||||
return $transaction->bill_id === $bill->id;
|
||||
}
|
||||
);
|
||||
$first = $entry->first();
|
||||
if (!is_null($first)) {
|
||||
$billLine->setTransactionJournalId($first->id);
|
||||
$billLine->setAmount($first->journalAmount);
|
||||
$billLine->setAmount($first->transaction_amount);
|
||||
$billLine->setHit(true);
|
||||
}
|
||||
|
||||
@ -113,67 +114,6 @@ class ReportHelper implements ReportHelperInterface
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBudgetMultiYear(Carbon $start, Carbon $end, Collection $accounts): array
|
||||
{
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$query = TransactionJournal
|
||||
::leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('transactions.deleted_at')
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->where('transaction_journals.user_id', auth()->user()->id);
|
||||
|
||||
if (count($accountIds) > 0) {
|
||||
$query->whereIn('transactions.account_id', $accountIds);
|
||||
}
|
||||
$query->groupBy(['budget_transaction_journal.budget_id', 'the_year']);
|
||||
$queryResult = $query->get(
|
||||
[
|
||||
'budget_transaction_journal.budget_id',
|
||||
DB::raw('DATE_FORMAT(transaction_journals.date,"%Y") AS the_year'),
|
||||
DB::raw('SUM(transactions.amount) as sum_of_period'),
|
||||
]
|
||||
);
|
||||
|
||||
$data = [];
|
||||
$budgets = $this->budgetRepository->getBudgets();
|
||||
$years = $this->listOfYears($start, $end);
|
||||
|
||||
// do budget "zero"
|
||||
$emptyBudget = new Budget;
|
||||
$emptyBudget->id = 0;
|
||||
$emptyBudget->name = strval(trans('firefly.no_budget'));
|
||||
$budgets->push($emptyBudget);
|
||||
|
||||
|
||||
// get all budgets and years.
|
||||
foreach ($budgets as $budget) {
|
||||
$data[$budget->id] = [
|
||||
'name' => $budget->name,
|
||||
'entries' => [],
|
||||
];
|
||||
foreach ($years as $year) {
|
||||
// filter query result here!
|
||||
$data[$budget->id]['entries'][$year] = $this->filterAmount($queryResult, $budget->id, $year);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
@ -294,24 +234,6 @@ class ReportHelper implements ReportHelperInterface
|
||||
return $months;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfYears(Carbon $start, Carbon $end): array
|
||||
{
|
||||
$begin = clone $start;
|
||||
$years = [];
|
||||
while ($begin < $end) {
|
||||
$years[] = $begin->year;
|
||||
$begin->addYear();
|
||||
}
|
||||
|
||||
return $years;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of tags and their comparitive size with amounts bla bla.
|
||||
*
|
||||
@ -386,56 +308,4 @@ class ReportHelper implements ReportHelperInterface
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $set
|
||||
* @param int $budgetId
|
||||
* @param int $year
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function filterAmount(Collection $set, int $budgetId, int $year): string
|
||||
{
|
||||
/** @var stdClass $object */
|
||||
$result = $set->filter(
|
||||
function (TransactionJournal $object) use ($budgetId, $year) {
|
||||
return intval($object->the_year) === $year && $budgetId === intval($object->budget_id);
|
||||
}
|
||||
);
|
||||
$amount = '0';
|
||||
if (!is_null($result->first())) {
|
||||
$amount = $result->first()->sum_of_period;
|
||||
}
|
||||
|
||||
return $amount;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the array as returned by CategoryRepositoryInterface::spentPerDay and CategoryRepositoryInterface::earnedByDay
|
||||
* and sum up everything in the array in the given range.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getSumOfRange(Carbon $start, Carbon $end, array $array)
|
||||
{
|
||||
$sum = '0';
|
||||
$currentStart = clone $start; // to not mess with the original one
|
||||
$currentEnd = clone $end; // to not mess with the original one
|
||||
|
||||
while ($currentStart <= $currentEnd) {
|
||||
$date = $currentStart->format('Y-m-d');
|
||||
if (isset($array[$date])) {
|
||||
$sum = bcadd($sum, $array[$date]);
|
||||
}
|
||||
$currentStart->addDay();
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -28,16 +28,6 @@ use Illuminate\Support\Collection;
|
||||
interface ReportHelperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBudgetMultiYear(Carbon $start, Carbon $end, Collection $accounts): array;
|
||||
|
||||
|
||||
/**
|
||||
* This method generates a full report for the given period on all
|
||||
* the users bills and their payments.
|
||||
@ -90,14 +80,6 @@ interface ReportHelperInterface
|
||||
*/
|
||||
public function listOfMonths(Carbon $date): array;
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfYears(Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* Returns an array of tags and their comparitive size with amounts bla bla.
|
||||
*
|
||||
|
@ -16,6 +16,7 @@ namespace FireflyIII\Http\Controllers;
|
||||
use Carbon\Carbon;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Http\Requests\AccountFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
@ -23,7 +24,6 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Navigation;
|
||||
@ -221,13 +221,13 @@ class AccountController extends Controller
|
||||
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
|
||||
$page = intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $tasker->getJournalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$count = $set->count();
|
||||
$subSet = $set->splice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
|
||||
$page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
|
||||
// replace with journal collector:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts(new Collection([$account]))->setRange($start, $end)->setLimit($pageSize)->setPage($page);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('accounts/show/' . $account->id);
|
||||
|
||||
// grouped other months thing:
|
||||
@ -275,27 +275,25 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountTaskerInterface $tasker
|
||||
* @param Account $account
|
||||
* @param string $date
|
||||
* @param Account $account
|
||||
* @param string $date
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function showWithDate(AccountTaskerInterface $tasker, Account $account, string $date)
|
||||
public function showWithDate(Account $account, string $date)
|
||||
{
|
||||
$carbon = new Carbon($date);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($carbon, $range);
|
||||
$end = Navigation::endOfPeriod($carbon, $range);
|
||||
$subTitle = $account->name . ' (' . Navigation::periodShow($start, $range) . ')';
|
||||
$page = intval(Input::get('page'));
|
||||
$page = $page === 0 ? 1 : $page;
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $tasker->getJournalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$count = $set->count();
|
||||
$subSet = $set->splice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
|
||||
$page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
|
||||
// replace with journal collector:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts(new Collection([$account]))->setRange($start, $end)->setLimit($pageSize)->setPage($page);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('accounts/show/' . $account->id . '/' . $date);
|
||||
|
||||
return view('accounts.show_with_date', compact('category', 'date', 'account', 'journals', 'subTitle', 'carbon'));
|
||||
|
@ -14,10 +14,12 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Http\Requests\BillFormRequest;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Session;
|
||||
@ -200,10 +202,15 @@ class BillController extends Controller
|
||||
$year = $date->year;
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
$journals = $repository->getJournals($bill, $page, $pageSize);
|
||||
$yearAverage = $repository->getYearAverage($bill, $date);
|
||||
$overallAverage = $repository->getOverallAverage($bill);
|
||||
|
||||
// use collector:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAllAssetAccounts()->setBills(new Collection([$bill]))->setPage($page)->setLimit($pageSize);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('/bills/show/' . $bill->id);
|
||||
|
||||
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill, new Carbon);
|
||||
$hideBill = true;
|
||||
$subTitle = e($bill->name);
|
||||
|
@ -17,13 +17,13 @@ use Amount;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Http\Requests\BudgetFormRequest;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Log;
|
||||
@ -247,31 +247,28 @@ class BudgetController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function noBudget(BudgetRepositoryInterface $repository)
|
||||
public function noBudget()
|
||||
{
|
||||
/** @var Carbon $start */
|
||||
$start = session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$journals = $repository->journalsInPeriodWithoutBudget(new Collection, $start, $end); // budget
|
||||
$count = $journals->count();
|
||||
$journals = $journals->slice($offset, $pageSize);
|
||||
$list = new LengthAwarePaginator($journals, $count, $pageSize);
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
$subTitle = trans(
|
||||
'firefly.without_budget_between',
|
||||
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
|
||||
);
|
||||
$list->setPath('/budgets/list/noBudget');
|
||||
|
||||
return view('budgets.noBudget', compact('list', 'subTitle'));
|
||||
// collector
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAllAssetAccounts()->setRange($start, $end)->setLimit($pageSize)->setPage($page)->withoutBudget();
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('/budgets/list/noBudget');
|
||||
|
||||
return view('budgets.no-budget', compact('journals', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -305,14 +302,13 @@ class BudgetController extends Controller
|
||||
$start = session('first', Carbon::create()->startOfYear());
|
||||
$end = new Carbon;
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$journals = $repository->journalsInPeriod(new Collection([$budget]), new Collection, $start, $end); // budget
|
||||
$count = $journals->count();
|
||||
$journals = $journals->slice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($journals, $count, $pageSize);
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]);
|
||||
|
||||
// collector:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAllAssetAccounts()->setRange($start, $end)->setBudget($budget)->setLimit($pageSize)->setPage($page);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('/budgets/show/' . $budget->id);
|
||||
|
||||
|
||||
@ -347,16 +343,15 @@ class BudgetController extends Controller
|
||||
$start = $repetition->startdate;
|
||||
$end = $repetition->enddate;
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$journals = $repository->journalsInPeriod(new Collection([$budget]), new Collection, $start, $end); // budget
|
||||
$count = $journals->count();
|
||||
$journals = $journals->slice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($journals, $count, $pageSize);
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
$subTitle = trans('firefly.budget_in_month', ['name' => $budget->name, 'month' => $repetition->startdate->formatLocalized($this->monthFormat)]);
|
||||
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::CASH]);
|
||||
|
||||
|
||||
// collector:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAllAssetAccounts()->setRange($start, $end)->setBudget($budget)->setLimit($pageSize)->setPage($page);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('/budgets/show/' . $budget->id . '/' . $repetition->id);
|
||||
|
||||
|
||||
|
@ -14,13 +14,13 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Http\Requests\CategoryFormRequest;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Navigation;
|
||||
@ -147,23 +147,25 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRI $repository
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function noCategory(CRI $repository)
|
||||
public function noCategory()
|
||||
{
|
||||
/** @var Carbon $start */
|
||||
$start = session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->startOfMonth());
|
||||
$list = $repository->journalsInPeriodWithoutCategory(new Collection(), [], $start, $end); // category
|
||||
$end = session('end', Carbon::now()->startOfMonth());
|
||||
|
||||
// new collector:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAllAssetAccounts()->setRange($start, $end)->withoutCategory();//->groupJournals();
|
||||
$journals = $collector->getJournals();
|
||||
$subTitle = trans(
|
||||
'firefly.without_category_between',
|
||||
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
|
||||
);
|
||||
|
||||
return view('categories.noCategory', compact('list', 'subTitle'));
|
||||
return view('categories.no-category', compact('journals', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,16 +182,17 @@ class CategoryController extends Controller
|
||||
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
|
||||
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end); // category
|
||||
$count = $set->count();
|
||||
$subSet = $set->splice($offset, $pageSize);
|
||||
$page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
$subTitle = $category->name;
|
||||
$subTitleIcon = 'fa-bar-chart';
|
||||
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
|
||||
|
||||
// use journal collector
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setPage($page)->setLimit($pageSize)->setAllAssetAccounts()->setRange($start, $end)->setCategory($category);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('categories/show/' . $category->id);
|
||||
|
||||
// oldest transaction in category:
|
||||
@ -218,7 +221,7 @@ class CategoryController extends Controller
|
||||
|
||||
|
||||
$categoryCollection = new Collection([$category]);
|
||||
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
|
||||
while ($end >= $start) {
|
||||
$end = Navigation::startOfPeriod($end, $range);
|
||||
$currentEnd = Navigation::endOfPeriod($end, $range);
|
||||
@ -233,18 +236,16 @@ class CategoryController extends Controller
|
||||
}
|
||||
$cache->store($entries);
|
||||
|
||||
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle'));
|
||||
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRI $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @param $date
|
||||
* @param Category $category
|
||||
* @param $date
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function showWithDate(CRI $repository, Category $category, string $date)
|
||||
public function showWithDate(Category $category, string $date)
|
||||
{
|
||||
$carbon = new Carbon($date);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
@ -252,15 +253,16 @@ class CategoryController extends Controller
|
||||
$end = Navigation::endOfPeriod($carbon, $range);
|
||||
$subTitle = $category->name;
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end); // category
|
||||
$count = $set->count();
|
||||
$subSet = $set->splice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
|
||||
$page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
|
||||
// new collector:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setPage($page)->setLimit($pageSize)->setAllAssetAccounts()->setRange($start, $end)->setCategory($category);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('categories/show/' . $category->id . '/' . $date);
|
||||
|
||||
|
||||
return view('categories.show_with_date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon'));
|
||||
}
|
||||
|
||||
|
@ -15,11 +15,13 @@ namespace FireflyIII\Http\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Generator\Chart\Bill\BillChartGeneratorInterface;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
use Response;
|
||||
|
||||
/**
|
||||
@ -64,12 +66,11 @@ class BillController extends Controller
|
||||
/**
|
||||
* Shows the overview for a bill. The min/max amount and matched journals.
|
||||
*
|
||||
* @param BillRepositoryInterface $repository
|
||||
* @param Bill $bill
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function single(BillRepositoryInterface $repository, Bill $bill)
|
||||
public function single(Bill $bill)
|
||||
{
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('single');
|
||||
@ -80,12 +81,14 @@ class BillController extends Controller
|
||||
}
|
||||
|
||||
// get first transaction or today for start:
|
||||
$results = $repository->getJournals($bill, 1, 200);
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAllAssetAccounts()->setBills(new Collection([$bill]));
|
||||
$results = $collector->getJournals();
|
||||
|
||||
// resort:
|
||||
$results = $results->sortBy(
|
||||
function (TransactionJournal $journal) {
|
||||
return $journal->date->format('U');
|
||||
function (Transaction $transaction) {
|
||||
return $transaction->date->format('U');
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -15,10 +15,12 @@ namespace FireflyIII\Http\Controllers\Chart;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Generator\Chart\Budget\BudgetChartGeneratorInterface;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -175,7 +177,7 @@ class BudgetController extends Controller
|
||||
$allEntries = $allEntries->merge($collection);
|
||||
|
||||
}
|
||||
$entry = $this->spentInPeriodWithout($repository, $start, $end);
|
||||
$entry = $this->spentInPeriodWithout($start, $end);
|
||||
$allEntries->push($entry);
|
||||
$data = $this->generator->frontpage($allEntries);
|
||||
$cache->store($data);
|
||||
@ -319,19 +321,22 @@ class BudgetController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function spentInPeriodWithout(BudgetRepositoryInterface $repository, Carbon $start, Carbon $end):array
|
||||
private function spentInPeriodWithout(Carbon $start, Carbon $end):array
|
||||
{
|
||||
$list = $repository->journalsInPeriodWithoutBudget(new Collection, $start, $end); // budget
|
||||
$sum = '0';
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($list as $entry) {
|
||||
$sum = bcadd(TransactionJournal::amount($entry), $sum);
|
||||
// collector
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$types = [TransactionType::WITHDRAWAL];
|
||||
$collector->setAllAssetAccounts()->setTypes($types)->setRange($start, $end)->withoutBudget();
|
||||
$journals = $collector->getJournals();
|
||||
$sum = '0';
|
||||
/** @var Transaction $entry */
|
||||
foreach ($journals as $entry) {
|
||||
$sum = bcadd($entry->transaction_amount, $sum);
|
||||
}
|
||||
|
||||
return [trans('firefly.no_budget'), '0', '0', $sum, '0', '0'];
|
||||
|
@ -13,7 +13,6 @@ declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
@ -61,31 +60,4 @@ class Controller extends BaseController
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the array as returned by CategoryRepositoryInterface::spentPerDay and CategoryRepositoryInterface::earnedByDay
|
||||
* and sum up everything in the array in the given range.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param array $array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getSumOfRange(Carbon $start, Carbon $end, array $array)
|
||||
{
|
||||
$sum = '0';
|
||||
$currentStart = clone $start; // to not mess with the original one
|
||||
$currentEnd = clone $end; // to not mess with the original one
|
||||
|
||||
while ($currentStart <= $currentEnd) {
|
||||
$date = $currentStart->format('Y-m-d');
|
||||
if (isset($array[$date])) {
|
||||
$sum = bcadd($sum, $array[$date]);
|
||||
}
|
||||
$currentStart->addDay();
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ class CurrencyController extends Controller
|
||||
|
||||
Session::flash('success', trans('firefly.deleted_currency', ['name' => $currency->name]));
|
||||
if (auth()->user()->hasRole('owner')) {
|
||||
$currency->delete();
|
||||
$currency->forceDelete();
|
||||
}
|
||||
|
||||
return redirect(session('currency.delete.url'));
|
||||
|
@ -42,9 +42,8 @@ class HelpController extends Controller
|
||||
public function show(HelpInterface $help, string $route)
|
||||
{
|
||||
|
||||
$language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data;
|
||||
$content = '<p>' . strval(trans('firefly.route_has_no_help')) . '</p>';
|
||||
$alternative = false;
|
||||
$language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data;
|
||||
$content = '<p>' . strval(trans('firefly.route_has_no_help')) . '</p>';
|
||||
|
||||
if (!$help->hasRoute($route)) {
|
||||
Log::error('No such route: ' . $route);
|
||||
@ -54,7 +53,7 @@ class HelpController extends Controller
|
||||
|
||||
if ($help->inCache($route, $language)) {
|
||||
$content = $help->getFromCache($route, $language);
|
||||
Log::debug('Help text was in cache.');
|
||||
Log::debug(sprintf('Help text %s was in cache.', $language));
|
||||
|
||||
return Response::json($content);
|
||||
}
|
||||
@ -63,19 +62,21 @@ class HelpController extends Controller
|
||||
|
||||
// get backup language content (try English):
|
||||
if (strlen($content) === 0) {
|
||||
$language = 'en_US';
|
||||
$content = $help->getFromGithub($language, $route);
|
||||
$alternative = true;
|
||||
}
|
||||
|
||||
if ($alternative && strlen($content) > 0) {
|
||||
$content = '<p><em>' . strval(trans('firefly.help_may_not_be_your_language')) . '</em></p>' . $content;
|
||||
$language = 'en_US';
|
||||
if ($help->inCache($route, $language)) {
|
||||
Log::debug(sprintf('Help text %s was in cache.', $language));
|
||||
$content = $help->getFromCache($route, $language);
|
||||
}
|
||||
if (!$help->inCache($route, $language)) {
|
||||
$content = $help->getFromGithub($language, $route);
|
||||
$content = '<p><em>' . strval(trans('firefly.help_may_not_be_your_language')) . '</em></p>' . $content;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($content) === 0) {
|
||||
$content = '<p>' . strval(trans('firefly.route_has_no_help')) . '</p>';
|
||||
}
|
||||
|
||||
|
||||
$help->putInCache($route, $language, $content);
|
||||
|
||||
return Response::json($content);
|
||||
|
@ -15,10 +15,10 @@ namespace FireflyIII\Http\Controllers;
|
||||
use Artisan;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -115,12 +115,11 @@ class HomeController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ARI $repository
|
||||
* @param AccountTaskerInterface $tasker
|
||||
* @param ARI $repository
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
|
||||
*/
|
||||
public function index(ARI $repository, AccountTaskerInterface $tasker)
|
||||
public function index(ARI $repository)
|
||||
{
|
||||
|
||||
$types = config('firefly.accountTypesByIdentifier.asset');
|
||||
@ -144,8 +143,9 @@ class HomeController extends Controller
|
||||
$showDepositsFrontpage = Preferences::get('showDepositsFrontpage', false)->data;
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = $tasker->getJournalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$set = $set->splice(0, 10);
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts(new Collection([$account]))->setRange($start, $end)->setLimit(10)->setPage(1);
|
||||
$set = $collector->getJournals();
|
||||
|
||||
if (count($set) > 0) {
|
||||
$transactions[] = [$set, $account];
|
||||
|
@ -15,12 +15,12 @@ namespace FireflyIII\Http\Controllers;
|
||||
use Amount;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
|
||||
use FireflyIII\Repositories\Journal\JournalTaskerInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Input;
|
||||
@ -270,17 +270,20 @@ class JsonController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param JournalTaskerInterface $tasker
|
||||
* @param $what
|
||||
* @param $what
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function transactionJournals(JournalTaskerInterface $tasker, $what)
|
||||
public function transactionJournals($what)
|
||||
{
|
||||
$descriptions = [];
|
||||
$type = config('firefly.transactionTypesByWhat.' . $what);
|
||||
$types = [$type];
|
||||
$journals = $tasker->getJournals($types, 1, 50);
|
||||
|
||||
// use journal collector instead:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setTypes($types)->setLimit(100)->setPage(1);
|
||||
$journals = $collector->getJournals();
|
||||
foreach ($journals as $j) {
|
||||
$descriptions[] = $j->description;
|
||||
}
|
||||
|
@ -107,6 +107,12 @@ class PiggyBankController extends Controller
|
||||
$subTitle = trans('firefly.new_piggy_bank');
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
if (count($accounts) === 0) {
|
||||
Session::flash('error', strval(trans('firefly.need_at_least_one_account')));
|
||||
|
||||
return redirect(route('new-user.index'));
|
||||
}
|
||||
|
||||
// put previous url in session if not redirect from store (not "create another").
|
||||
if (session('piggy-banks.create.fromStore') !== true) {
|
||||
Session::put('piggy-banks.create.url', URL::previous());
|
||||
|
@ -17,12 +17,12 @@ namespace FireflyIII\Http\Controllers\Popup;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collection\BalanceLine;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Support\Binder\AccountList;
|
||||
@ -98,20 +98,39 @@ class ReportController extends Controller
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
|
||||
$account = $repository->find(intval($attributes['accountId']));
|
||||
$types = [TransactionType::WITHDRAWAL];
|
||||
|
||||
switch (true) {
|
||||
case ($role === BalanceLine::ROLE_DEFAULTROLE && !is_null($budget->id)):
|
||||
$journals = $budgetRepository->journalsInPeriod(
|
||||
new Collection([$budget]), new Collection([$account]), $attributes['startDate'], $attributes['endDate']
|
||||
);
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector
|
||||
->setAccounts(new Collection([$account]))
|
||||
->setRange($attributes['startDate'], $attributes['endDate'])
|
||||
->setBudget($budget);
|
||||
$journals = $collector->getJournals();
|
||||
|
||||
break;
|
||||
case ($role === BalanceLine::ROLE_DEFAULTROLE && is_null($budget->id)):
|
||||
$budget->name = strval(trans('firefly.no_budget'));
|
||||
$journals = $budgetRepository->journalsInPeriodWithoutBudget($attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
|
||||
// collector
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector
|
||||
->setAccounts(new Collection([$account]))
|
||||
->setTypes($types)
|
||||
->setRange($attributes['startDate'], $attributes['endDate'])
|
||||
->withoutBudget();
|
||||
$journals = $collector->getJournals();
|
||||
break;
|
||||
case ($role === BalanceLine::ROLE_DIFFROLE):
|
||||
// journals no budget, not corrected by a tag.
|
||||
$journals = $budgetRepository->journalsInPeriodWithoutBudget($attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector
|
||||
->setAccounts(new Collection([$account]))
|
||||
->setTypes($types)
|
||||
->setRange($attributes['startDate'], $attributes['endDate'])
|
||||
->withoutBudget();
|
||||
$journals = $collector->getJournals();
|
||||
|
||||
$budget->name = strval(trans('firefly.leftUnbalanced'));
|
||||
$journals = $journals->filter(
|
||||
function (TransactionJournal $journal) {
|
||||
@ -148,14 +167,21 @@ class ReportController extends Controller
|
||||
/** @var BudgetRepositoryInterface $repository */
|
||||
$repository = app(BudgetRepositoryInterface::class);
|
||||
$budget = $repository->find(intval($attributes['budgetId']));
|
||||
if (is_null($budget->id)) {
|
||||
$journals = $repository->journalsInPeriodWithoutBudget($attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
|
||||
} else {
|
||||
// get all expenses in budget in period:
|
||||
$journals = $repository->journalsInPeriod(new Collection([$budget]), $attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
|
||||
}
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
|
||||
$view = view('popup.report.budget-spent-amount', compact('journals', 'budget'))->render();
|
||||
$collector
|
||||
->setAccounts($attributes['accounts'])
|
||||
->setRange($attributes['startDate'], $attributes['endDate']);
|
||||
|
||||
if (is_null($budget->id)) {
|
||||
$collector->setTypes([TransactionType::WITHDRAWAL])->withoutBudget();
|
||||
}
|
||||
if (!is_null($budget->id)) {
|
||||
// get all expenses in budget in period:
|
||||
$collector->setBudget($budget);
|
||||
}
|
||||
$journals = $collector->getJournals();
|
||||
$view = view('popup.report.budget-spent-amount', compact('journals', 'budget'))->render();
|
||||
|
||||
return $view;
|
||||
}
|
||||
@ -174,10 +200,14 @@ class ReportController extends Controller
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$category = $repository->find(intval($attributes['categoryId']));
|
||||
$types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
|
||||
$journals = $repository->journalsInPeriod(
|
||||
new Collection([$category]), $attributes['accounts'], $types, $attributes['startDate'], $attributes['endDate']
|
||||
);
|
||||
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
|
||||
// get journal collector instead:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts($attributes['accounts'])->setTypes($types)
|
||||
->setRange($attributes['startDate'], $attributes['endDate'])
|
||||
->setCategory($category);
|
||||
$journals = $collector->getJournals(); // 7193
|
||||
|
||||
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
|
||||
|
||||
return $view;
|
||||
}
|
||||
@ -192,14 +222,14 @@ class ReportController extends Controller
|
||||
*/
|
||||
private function expenseEntry(array $attributes): string
|
||||
{
|
||||
/** @var AccountTaskerInterface $tasker */
|
||||
$tasker = app(AccountTaskerInterface::class);
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
|
||||
$account = $repository->find(intval($attributes['accountId']));
|
||||
$types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
|
||||
$journals = $tasker->getJournalsInPeriod(new Collection([$account]), $types, $attributes['startDate'], $attributes['endDate']);
|
||||
$account = $repository->find(intval($attributes['accountId']));
|
||||
$types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts(new Collection([$account]))->setRange($attributes['startDate'], $attributes['endDate'])->setTypes($types);
|
||||
$journals = $collector->getJournals();
|
||||
$report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report
|
||||
|
||||
// filter for transfers and withdrawals TO the given $account
|
||||
@ -228,14 +258,14 @@ class ReportController extends Controller
|
||||
*/
|
||||
private function incomeEntry(array $attributes): string
|
||||
{
|
||||
/** @var AccountTaskerInterface $tasker */
|
||||
$tasker = app(AccountTaskerInterface::class);
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$account = $repository->find(intval($attributes['accountId']));
|
||||
$types = [TransactionType::DEPOSIT, TransactionType::TRANSFER];
|
||||
$journals = $tasker->getJournalsInPeriod(new Collection([$account]), $types, $attributes['startDate'], $attributes['endDate']);
|
||||
$report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts(new Collection([$account]))->setRange($attributes['startDate'], $attributes['endDate'])->setTypes($types);
|
||||
$journals = $collector->getJournals();
|
||||
$report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report
|
||||
|
||||
// filter the set so the destinations outside of $attributes['accounts'] are not included.
|
||||
$journals = $journals->filter(
|
||||
|
@ -13,7 +13,6 @@ declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Events\DeletedUser;
|
||||
use FireflyIII\Http\Requests\DeleteAccountFormRequest;
|
||||
use FireflyIII\Http\Requests\ProfileFormRequest;
|
||||
use FireflyIII\User;
|
||||
|
@ -28,6 +28,35 @@ use Illuminate\Support\Collection;
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @param BudgetReportHelperInterface $helper
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function budgetMultiYear(BudgetReportHelperInterface $helper, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('budget-mult-year-report');
|
||||
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
|
||||
$years = $helper->listOfYears($start, $end);
|
||||
$budgetMultiYear = $helper->getBudgetMultiYear($start, $end, $accounts);
|
||||
|
||||
$result = view('reports.partials.budget-multi-year', compact('budgetMultiYear', 'years'))->render();
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BudgetReportHelperInterface $helper
|
||||
* @param Carbon $start
|
||||
|
@ -19,7 +19,6 @@ use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
use Response;
|
||||
|
||||
/**
|
||||
* Class InOutController
|
||||
@ -37,29 +36,83 @@ class InOutController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function inOutReport(ReportHelperInterface $helper, Carbon $start, Carbon $end, Collection $accounts)
|
||||
public function expenseReport(ReportHelperInterface $helper, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('in-out-report');
|
||||
$cache->addProperty('expense-report');
|
||||
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||
if ($cache->has()) {
|
||||
return Response::json($cache->get());
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
$expenses = $helper->getExpenseReport($start, $end, $accounts);
|
||||
|
||||
$result = view('reports.partials.expenses', compact('expenses'))->render();
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReportHelperInterface $helper
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function incExpReport(ReportHelperInterface $helper, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('inc-exp-report');
|
||||
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
$incomes = $helper->getIncomeReport($start, $end, $accounts);
|
||||
$expenses = $helper->getExpenseReport($start, $end, $accounts);
|
||||
|
||||
$result = [
|
||||
'income' => view('reports.partials.income', compact('incomes'))->render(),
|
||||
'expenses' => view('reports.partials.expenses', compact('expenses'))->render(),
|
||||
'incomes_expenses' => view('reports.partials.income-vs-expenses', compact('expenses', 'incomes'))->render(),
|
||||
];
|
||||
$result = view('reports.partials.income-vs-expenses', compact('expenses', 'incomes'))->render();
|
||||
$cache->store($result);
|
||||
|
||||
return Response::json($result);
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReportHelperInterface $helper
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function incomeReport(ReportHelperInterface $helper, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('income-report');
|
||||
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
$incomes = $helper->getIncomeReport($start, $end, $accounts);
|
||||
|
||||
$result = view('reports.partials.income', compact('incomes'))->render();
|
||||
$cache->store($result);
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,12 +15,12 @@ namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
use Session;
|
||||
@ -150,8 +150,6 @@ class ReportController extends Controller
|
||||
*/
|
||||
private function auditReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
/** @var AccountTaskerInterface $tasker */
|
||||
$tasker = app(AccountTaskerInterface::class);
|
||||
$auditData = [];
|
||||
$dayBefore = clone $start;
|
||||
$dayBefore->subDay();
|
||||
@ -160,9 +158,11 @@ class ReportController extends Controller
|
||||
// balance the day before:
|
||||
$id = $account->id;
|
||||
$dayBeforeBalance = Steam::balance($account, $dayBefore);
|
||||
$journals = $tasker->getJournalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$journals = $journals->reverse();
|
||||
$startBalance = $dayBeforeBalance;
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts(new Collection([$account]))->setRange($start, $end);
|
||||
$journals = $collector->getJournals();
|
||||
$journals = $journals->reverse();
|
||||
$startBalance = $dayBeforeBalance;
|
||||
|
||||
|
||||
/** @var Transaction $journal */
|
||||
@ -244,8 +244,6 @@ class ReportController extends Controller
|
||||
{
|
||||
// need all budgets
|
||||
// need all years.
|
||||
$years = $this->helper->listOfYears($start, $end);
|
||||
$budgetMultiYear = $this->helper->getBudgetMultiYear($start, $end, $accounts);
|
||||
|
||||
|
||||
// and some id's, joined:
|
||||
@ -259,8 +257,7 @@ class ReportController extends Controller
|
||||
return view(
|
||||
'reports.default.multi-year',
|
||||
compact(
|
||||
'accounts', 'start', 'end', 'accountIds', 'reportType',
|
||||
'years', 'budgetMultiYear'
|
||||
'accounts', 'start', 'end', 'accountIds', 'reportType'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ class RuleController extends Controller
|
||||
}
|
||||
|
||||
// Return json response
|
||||
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
|
||||
$view = view('list.journals-tiny-tasker', ['transactions' => $matchingTransactions])->render();
|
||||
|
||||
return Response::json(['html' => $view, 'warning' => $warning]);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Support\Search\SearchInterface;
|
||||
use Input;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class SearchController
|
||||
@ -30,12 +30,6 @@ class SearchController extends Controller
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware(
|
||||
function ($request, $next) {
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,16 +39,21 @@ class SearchController extends Controller
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function index(SearchInterface $searcher)
|
||||
public function index(Request $request, SearchInterface $searcher)
|
||||
{
|
||||
|
||||
$minSearchLen = 1;
|
||||
$subTitle = null;
|
||||
$query = null;
|
||||
$result = [];
|
||||
$title = trans('firefly.search');
|
||||
$limit = 20;
|
||||
$mainTitleIcon = 'fa-search';
|
||||
if (!is_null(Input::get('q')) && strlen(Input::get('q')) > 0) {
|
||||
$query = trim(Input::get('q'));
|
||||
|
||||
// set limit for search:
|
||||
$searcher->setLimit($limit);
|
||||
|
||||
if (!is_null($request->get('q')) && strlen($request->get('q')) >= $minSearchLen) {
|
||||
$query = trim(strtolower($request->get('q')));
|
||||
$words = explode(' ', $query);
|
||||
$subTitle = trans('firefly.search_results_for', ['query' => $query]);
|
||||
|
||||
@ -67,7 +66,7 @@ class SearchController extends Controller
|
||||
|
||||
}
|
||||
|
||||
return view('search.index', compact('title', 'subTitle', 'mainTitleIcon', 'query', 'result'));
|
||||
return view('search.index', compact('title', 'subTitle', 'limit', 'mainTitleIcon', 'query', 'result'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,10 +13,11 @@ declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Http\Requests\TagFormRequest;
|
||||
use FireflyIII\Models\Preference;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
@ -226,19 +227,27 @@ class TagController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Tag $tag
|
||||
* @param TagRepositoryInterface $repository
|
||||
* @param Tag $tag
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function show(Tag $tag, TagRepositoryInterface $repository)
|
||||
public function show(Tag $tag)
|
||||
{
|
||||
$subTitle = $tag->tag;
|
||||
$subTitleIcon = 'fa-tag';
|
||||
$journals = $repository->getJournals($tag);
|
||||
$sum = $journals->sum(
|
||||
function (TransactionJournal $journal) {
|
||||
return TransactionJournal::amount($journal);
|
||||
$page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
|
||||
// use collector:
|
||||
// replace with journal collector:
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAllAssetAccounts()->setLimit($pageSize)->setPage($page)->setTag($tag);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('tags/show/' . $tag->id);
|
||||
|
||||
$sum = $journals->sum(
|
||||
function (Transaction $transaction) {
|
||||
return $transaction->transaction_amount;
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -206,7 +206,6 @@ class ConvertController extends Controller
|
||||
$sourceAccount = TransactionJournal::sourceAccountList($journal)->first();
|
||||
$destinationAccount = TransactionJournal::destinationAccountList($journal)->first();
|
||||
$sourceType = $journal->transactionType;
|
||||
$source = new Account;
|
||||
$joined = $sourceType->type . '-' . $destinationType->type;
|
||||
switch ($joined) {
|
||||
default:
|
||||
|
@ -171,7 +171,6 @@ class SingleController extends Controller
|
||||
|
||||
$assetAccounts = ExpandedForm::makeSelectList($this->accounts->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]));
|
||||
$budgetList = ExpandedForm::makeSelectListWithEmpty($this->budgets->getActiveBudgets());
|
||||
$piggyBankList = ExpandedForm::makeSelectListWithEmpty($this->piggyBanks->getPiggyBanks());
|
||||
|
||||
// view related code
|
||||
$subTitle = trans('breadcrumbs.edit_journal', ['description' => $journal->description]);
|
||||
@ -188,7 +187,6 @@ class SingleController extends Controller
|
||||
'process_date' => TransactionJournal::dateAsString($journal, 'process_date'),
|
||||
'category' => TransactionJournal::categoryAsString($journal),
|
||||
'budget_id' => TransactionJournal::budgetId($journal),
|
||||
'piggy_bank_id' => TransactionJournal::piggyBankId($journal),
|
||||
'tags' => join(',', $journal->tags->pluck('tag')->toArray()),
|
||||
'source_account_id' => $sourceAccounts->first()->id,
|
||||
'source_account_name' => $sourceAccounts->first()->name,
|
||||
@ -225,7 +223,7 @@ class SingleController extends Controller
|
||||
|
||||
return view(
|
||||
'transactions.edit',
|
||||
compact('journal', 'optionalFields', 'assetAccounts', 'what', 'budgetList', 'piggyBankList', 'subTitle')
|
||||
compact('journal', 'optionalFields', 'assetAccounts', 'what', 'budgetList', 'subTitle')
|
||||
)->with('data', $preFilled);
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalTaskerInterface;
|
||||
@ -49,21 +50,22 @@ class TransactionController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param JournalTaskerInterface $tasker
|
||||
* @param string $what
|
||||
* @param Request $request
|
||||
* @param string $what
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index(Request $request, JournalTaskerInterface $tasker, string $what)
|
||||
public function index(Request $request, string $what)
|
||||
{
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
$subTitleIcon = config('firefly.transactionIconsByWhat.' . $what);
|
||||
$types = config('firefly.transactionTypesByWhat.' . $what);
|
||||
$subTitle = trans('firefly.title_' . $what);
|
||||
$page = intval($request->get('page'));
|
||||
$journals = $tasker->getJournals($types, $page, $pageSize);
|
||||
$page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page'));
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts();
|
||||
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('transactions/' . $what);
|
||||
|
||||
return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals'));
|
||||
|
@ -14,8 +14,8 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Jobs;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
use FireflyIII\Repositories\Journal\JournalTaskerInterface;
|
||||
use FireflyIII\Rules\Processor;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@ -129,16 +129,16 @@ class ExecuteRuleGroupOnExistingTransactions extends Job implements ShouldQueue
|
||||
public function handle()
|
||||
{
|
||||
// Lookup all journals that match the parameters specified
|
||||
$journals = $this->collectJournals();
|
||||
$transactions = $this->collectJournals();
|
||||
|
||||
// Find processors for each rule within the current rule group
|
||||
$processors = $this->collectProcessors();
|
||||
|
||||
// Execute the rules for each transaction
|
||||
foreach ($journals as $journal) {
|
||||
foreach ($transactions as $transaction) {
|
||||
/** @var Processor $processor */
|
||||
foreach ($processors as $processor) {
|
||||
$processor->handleTransactionJournal($journal);
|
||||
$processor->handleTransaction($transaction);
|
||||
|
||||
// Stop processing this group if the rule specifies 'stop_processing'
|
||||
if ($processor->getRule()->stop_processing) {
|
||||
@ -155,10 +155,10 @@ class ExecuteRuleGroupOnExistingTransactions extends Job implements ShouldQueue
|
||||
*/
|
||||
protected function collectJournals()
|
||||
{
|
||||
/** @var JournalTaskerInterface $tasker */
|
||||
$tasker = app(JournalTaskerInterface::class);
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts($this->accounts)->setRange($this->startDate, $this->endDate);
|
||||
|
||||
return $tasker->getJournalsInRange($this->accounts, $this->startDate, $this->endDate);
|
||||
return $collector->getJournals();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,13 +46,12 @@ class Note extends Model
|
||||
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMarkdownAttribute(): string
|
||||
{
|
||||
$converter = new CommonMarkConverter;
|
||||
$converter = new CommonMarkConverter;
|
||||
|
||||
return $converter->convertToHtml($this->text);
|
||||
}
|
||||
|
||||
|
@ -23,22 +23,22 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
/**
|
||||
* FireflyIII\Models\PiggyBank
|
||||
*
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property integer $account_id
|
||||
* @property string $name
|
||||
* @property float $targetamount
|
||||
* @property \Carbon\Carbon $startdate
|
||||
* @property \Carbon\Carbon $targetdate
|
||||
* @property integer $order
|
||||
* @property boolean $encrypted
|
||||
* @property-read Account $account
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|PiggyBankRepetition[] $piggyBankRepetitions
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|PiggyBankEvent[] $piggyBankEvents
|
||||
* @property string $reminder
|
||||
* @property PiggyBankRepetition $currentRep
|
||||
* @property integer $id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property integer $account_id
|
||||
* @property string $name
|
||||
* @property float $targetamount
|
||||
* @property \Carbon\Carbon $startdate
|
||||
* @property \Carbon\Carbon $targetdate
|
||||
* @property integer $order
|
||||
* @property boolean $encrypted
|
||||
* @property-read Account $account
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|PiggyBankRepetition[] $piggyBankRepetitions
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|PiggyBankEvent[] $piggyBankEvents
|
||||
* @property string $reminder
|
||||
* @property PiggyBankRepetition $currentRep
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereUpdatedAt($value)
|
||||
@ -54,7 +54,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereEncrypted($value)
|
||||
* @mixin \Eloquent
|
||||
* @property boolean $active
|
||||
* @property boolean $active
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\PiggyBank whereActive($value)
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Note[] $notes
|
||||
*/
|
||||
|
@ -70,7 +70,6 @@ class EventServiceProvider extends ServiceProvider
|
||||
'FireflyIII\Events\UpdatedTransactionJournal' => // is a Transaction Journal related event.
|
||||
[
|
||||
'FireflyIII\Handlers\Events\UpdatedJournalEventHandler@scanBills',
|
||||
'FireflyIII\Handlers\Events\UpdatedJournalEventHandler@connectToPiggyBank',
|
||||
'FireflyIII\Handlers\Events\UpdatedJournalEventHandler@processRules',
|
||||
],
|
||||
|
||||
|
@ -94,7 +94,6 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
);
|
||||
|
||||
$this->app->bind('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', 'FireflyIII\Repositories\Currency\CurrencyRepository');
|
||||
$this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
|
||||
$this->app->bind('FireflyIII\Repositories\User\UserRepositoryInterface', 'FireflyIII\Repositories\User\UserRepository');
|
||||
$this->app->bind('FireflyIII\Helpers\Attachments\AttachmentHelperInterface', 'FireflyIII\Helpers\Attachments\AttachmentHelper');
|
||||
$this->app->bind(
|
||||
|
59
app/Providers/SearchServiceProvider.php
Normal file
59
app/Providers/SearchServiceProvider.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* AccountServiceProvider.php
|
||||
* Copyright (C) 2016 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\Providers;
|
||||
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
/**
|
||||
* Class SearchServiceProvider
|
||||
*
|
||||
* @package FireflyIII\Providers
|
||||
*/
|
||||
class SearchServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->bind(
|
||||
'FireflyIII\Support\Search\SearchInterface',
|
||||
function (Application $app, array $arguments) {
|
||||
if (!isset($arguments[0]) && $app->auth->check()) {
|
||||
return app('FireflyIII\Support\Search\Search', [auth()->user()]);
|
||||
}
|
||||
if (!isset($arguments[0]) && !$app->auth->check()) {
|
||||
throw new FireflyException('There is no user present.');
|
||||
}
|
||||
|
||||
return app('FireflyIII\Support\Search\Search', $arguments);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -190,77 +190,6 @@ class AccountTasker implements AccountTaskerInterface
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* It might be worth it to expand this query to include all account information required.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournalsInPeriod(Collection $accounts, array $types, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$query = Transaction
|
||||
::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->leftJoin('transaction_currencies', 'transaction_currencies.id', 'transaction_journals.transaction_currency_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin('bills', 'bills.id', 'transaction_journals.bill_id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin('account_types', 'accounts.account_type_id', 'account_types.id')
|
||||
->whereIn('transactions.account_id', $accountIds)
|
||||
->whereNull('transactions.deleted_at')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
|
||||
->where('transaction_journals.user_id', $this->user->id)
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.order', 'ASC')
|
||||
->orderBy('transaction_journals.id', 'DESC');
|
||||
|
||||
if (count($types) > 0) {
|
||||
$query->whereIn('transaction_types.type', $types);
|
||||
}
|
||||
|
||||
$set = $query->get(
|
||||
[
|
||||
'transaction_journals.id as journal_id',
|
||||
'transaction_journals.description',
|
||||
'transaction_journals.date',
|
||||
'transaction_journals.encrypted',
|
||||
//'transaction_journals.transaction_currency_id',
|
||||
'transaction_currencies.code as transaction_currency_code',
|
||||
//'transaction_currencies.symbol as transaction_currency_symbol',
|
||||
'transaction_types.type as transaction_type_type',
|
||||
'transaction_journals.bill_id',
|
||||
'bills.name as bill_name',
|
||||
'transactions.id as id',
|
||||
'transactions.amount as transaction_amount',
|
||||
'transactions.description as transaction_description',
|
||||
'transactions.account_id',
|
||||
'transactions.identifier',
|
||||
'transactions.transaction_journal_id',
|
||||
'accounts.name as account_name',
|
||||
'accounts.encrypted as account_encrypted',
|
||||
'account_types.type as account_type',
|
||||
|
||||
]
|
||||
);
|
||||
|
||||
// loop for decryption.
|
||||
$set->each(
|
||||
function (Transaction $transaction) {
|
||||
$transaction->date = new Carbon($transaction->date);
|
||||
$transaction->description = intval($transaction->encrypted) === 1 ? Crypt::decrypt($transaction->description) : $transaction->description;
|
||||
$transaction->bill_name = !is_null($transaction->bill_name) ? Crypt::decrypt($transaction->bill_name) : '';
|
||||
}
|
||||
);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $excluded
|
||||
@ -328,7 +257,6 @@ class AccountTasker implements AccountTaskerInterface
|
||||
$join->on('transaction_journals.id', '=', 'other_side.transaction_journal_id')->where('other_side.amount', $joinModifier, 0);
|
||||
}
|
||||
)
|
||||
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
|
||||
->where('transaction_journals.user_id', $this->user->id)
|
||||
@ -384,7 +312,7 @@ class AccountTasker implements AccountTaskerInterface
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as other_account', 'other_account.id', '=', 'other_side.account_id')
|
||||
->where('transaction_types.type','!=', TransactionType::OPENING_BALANCE)
|
||||
->where('transaction_types.type', '!=', TransactionType::OPENING_BALANCE)
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
|
||||
->where('transaction_journals.user_id', $this->user->id)
|
||||
|
@ -71,18 +71,6 @@ interface AccountTaskerInterface
|
||||
*/
|
||||
public function getAccountReport(Carbon $start, Carbon $end, Collection $accounts): AccountCollection;
|
||||
|
||||
/**
|
||||
* Experimental getJournals method.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournalsInPeriod(Collection $accounts, array $types, Carbon $start, Carbon $end): Collection;
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Collection $excluded
|
||||
|
@ -22,7 +22,6 @@ use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Navigation;
|
||||
@ -116,41 +115,6 @@ class BillRepository implements BillRepositoryInterface
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all journals connected to these bills in the given range. Amount paid
|
||||
* is stored in "journalAmount" as a negative number.
|
||||
*
|
||||
* @param Collection $bills
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAllJournalsInRange(Collection $bills, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
$ids = $bills->pluck('id')->toArray();
|
||||
|
||||
$set = $this->user->transactionJournals()
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->whereIn('bill_id', $ids)
|
||||
->before($end)
|
||||
->after($start)
|
||||
->groupBy(['transaction_journals.bill_id', 'transaction_journals.id'])
|
||||
->get(
|
||||
[
|
||||
'transaction_journals.bill_id',
|
||||
'transaction_journals.id',
|
||||
DB::raw('SUM(transactions.amount) AS journalAmount'),
|
||||
]
|
||||
);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
@ -287,30 +251,6 @@ class BillRepository implements BillRepositoryInterface
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method also returns the amount of the journal in "journalAmount"
|
||||
* for easy access.
|
||||
*
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @param int $page
|
||||
* @param int $pageSize
|
||||
*
|
||||
* @return LengthAwarePaginator|Collection
|
||||
*/
|
||||
public function getJournals(Bill $bill, int $page, int $pageSize = 50): LengthAwarePaginator
|
||||
{
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$query = $bill->transactionJournals()
|
||||
->expanded()
|
||||
->sortCorrectly();
|
||||
$count = $query->count();
|
||||
$set = $query->take($pageSize)->offset($offset)->get(TransactionJournal::queryFields());
|
||||
$paginator = new LengthAwarePaginator($set, $count, $pageSize, $page);
|
||||
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
|
@ -16,7 +16,6 @@ namespace FireflyIII\Repositories\Bill;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@ -57,18 +56,6 @@ interface BillRepositoryInterface
|
||||
*/
|
||||
public function getActiveBills(): Collection;
|
||||
|
||||
/**
|
||||
* Returns all journals connected to these bills in the given range. Amount paid
|
||||
* is stored in "journalAmount" as a negative number.
|
||||
*
|
||||
* @param Collection $bills
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAllJournalsInRange(Collection $bills, Carbon $start, Carbon $end): Collection;
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
@ -103,16 +90,6 @@ interface BillRepositoryInterface
|
||||
*/
|
||||
public function getBillsUnpaidInRange(Carbon $start, Carbon $end): string;
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @param int $page
|
||||
* @param int $pageSize
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public function getJournals(Bill $bill, int $page, int $pageSize = 50): LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
|
@ -24,7 +24,6 @@ use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
@ -210,135 +209,6 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
$return = new Collection;
|
||||
$accountIds = [];
|
||||
// expand the number of grabbed fields:
|
||||
$fields = TransactionJournal::queryFields();
|
||||
$fields[] = 'source.account_id';
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
}
|
||||
|
||||
// first get all journals for all budget(s):
|
||||
$journalQuery = $this->user->transactionJournals()
|
||||
->expanded()
|
||||
->sortCorrectly()
|
||||
->before($end)
|
||||
->after($start)
|
||||
->leftJoin(
|
||||
'transactions as source',
|
||||
function (JoinClause $join) {
|
||||
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', '0');
|
||||
}
|
||||
)
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereIn('budget_transaction_journal.budget_id', $budgets->pluck('id')->toArray());
|
||||
// add account id's, if relevant:
|
||||
if (count($accountIds) > 0) {
|
||||
$journalQuery->whereIn('source.account_id', $accountIds);
|
||||
}
|
||||
// get them:
|
||||
$journals = $journalQuery->get(TransactionJournal::queryFields());
|
||||
|
||||
// then get transactions themselves.
|
||||
$transactionQuery = $this->user->transactionJournals()
|
||||
->expanded()
|
||||
->before($end)
|
||||
->sortCorrectly()
|
||||
->after($start)
|
||||
->leftJoin('transactions as related', 'related.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('budget_transaction', 'budget_transaction.transaction_id', '=', 'related.id')
|
||||
->leftJoin(
|
||||
'transactions as source',
|
||||
function (JoinClause $join) {
|
||||
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', '0');
|
||||
}
|
||||
)
|
||||
->groupBy(['source.account_id'])
|
||||
->whereIn('budget_transaction.budget_id', $budgets->pluck('id')->toArray());
|
||||
|
||||
if (count($accountIds) > 0) {
|
||||
$transactionQuery->whereIn('source.account_id', $accountIds);
|
||||
}
|
||||
|
||||
$transactions = $transactionQuery->get($fields);
|
||||
|
||||
// return complete set:
|
||||
$return = $return->merge($transactions);
|
||||
$return = $return->merge($journals);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriodWithoutBudget(Collection $accounts, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
$accountIds = [];
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
}
|
||||
|
||||
/** @var Collection $set */
|
||||
$query = $this->user
|
||||
->transactionJournals()
|
||||
->expanded()
|
||||
->sortCorrectly()
|
||||
->transactionTypes([TransactionType::WITHDRAWAL])
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('budget_transaction_journal.id')
|
||||
->leftJoin(
|
||||
'transactions as source',
|
||||
function (JoinClause $join) {
|
||||
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', '0');
|
||||
}
|
||||
)
|
||||
->before($end)
|
||||
->after($start)->with(
|
||||
[
|
||||
'transactions' => function (HasMany $query) {
|
||||
$query->where('transactions.amount', '<', 0);
|
||||
},
|
||||
'transactions.budgets',
|
||||
]
|
||||
);
|
||||
|
||||
// add account id's, if relevant:
|
||||
if (count($accountIds) > 0) {
|
||||
$query->whereIn('source.account_id', $accountIds);
|
||||
}
|
||||
|
||||
$set = $query->get(TransactionJournal::queryFields());
|
||||
$set = $set->filter(
|
||||
function (TransactionJournal $journal) {
|
||||
foreach ($journal->transactions as $t) {
|
||||
if ($t->budgets->count() === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $accounts
|
||||
@ -350,8 +220,8 @@ class BudgetRepository implements BudgetRepositoryInterface
|
||||
public function spentInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end) : string
|
||||
{
|
||||
// collect amount of transaction journals, which is easy:
|
||||
$budgetIds = $budgets->pluck('id')->toArray();
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$budgetIds = $budgets->pluck('id')->toArray();
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
|
||||
Log::debug('spentInPeriod: Now in spentInPeriod for these budgets: ', $budgetIds);
|
||||
Log::debug('spentInPeriod: and these accounts: ', $accountIds);
|
||||
|
@ -89,25 +89,6 @@ interface BudgetRepositoryInterface
|
||||
*/
|
||||
public function getInactiveBudgets(): Collection;
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): Collection;
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriodWithoutBudget(Collection $accounts, Carbon $start, Carbon $end): Collection;
|
||||
|
||||
/**
|
||||
* @param Collection $budgets
|
||||
* @param Collection $accounts
|
||||
|
@ -20,7 +20,6 @@ use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@ -174,176 +173,6 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param int $page
|
||||
* @param int $pageSize
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public function getJournals(Category $category, int $page, int $pageSize): LengthAwarePaginator
|
||||
{
|
||||
$complete = new Collection;
|
||||
// first collect actual transaction journals (fairly easy)
|
||||
$query = $this->user->transactionJournals()->expanded()->sortCorrectly();
|
||||
$query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
$query->where('category_transaction_journal.category_id', $category->id);
|
||||
$first = $query->get(TransactionJournal::queryFields());
|
||||
|
||||
// then collection transactions (harder)
|
||||
$query = $this->user->transactionJournals()->distinct()
|
||||
->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id')
|
||||
->where('category_transaction.category_id', $category->id);
|
||||
$second = $query->get(['transaction_journals.*']);
|
||||
|
||||
$complete = $complete->merge($first);
|
||||
$complete = $complete->merge($second);
|
||||
|
||||
// sort:
|
||||
/** @var Collection $complete */
|
||||
$complete = $complete->sortByDesc(
|
||||
function ($model) {
|
||||
$date = new Carbon($model->date);
|
||||
|
||||
return intval($date->format('U'));
|
||||
}
|
||||
);
|
||||
// create paginator
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$subSet = $complete->slice($offset, $pageSize)->all();
|
||||
$paginator = new LengthAwarePaginator($subSet, $complete->count(), $pageSize, $page);
|
||||
|
||||
return $paginator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all transactions in a category in a range.
|
||||
*
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriod(Collection $categories, Collection $accounts, array $types, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
$complete = new Collection;
|
||||
// first collect actual transaction journals (fairly easy)
|
||||
$query = $this->user->transactionJournals()->expanded()->sortCorrectly();
|
||||
|
||||
if ($end >= $start) {
|
||||
$query->before($end)->after($start);
|
||||
}
|
||||
|
||||
if (count($types) > 0) {
|
||||
$query->transactionTypes($types);
|
||||
}
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$query->leftJoin('transactions as t', 't.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
$query->whereIn('t.account_id', $accountIds);
|
||||
}
|
||||
if ($categories->count() > 0) {
|
||||
$categoryIds = $categories->pluck('id')->toArray();
|
||||
$query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
$query->whereIn('category_transaction_journal.category_id', $categoryIds);
|
||||
}
|
||||
|
||||
// that should do it:
|
||||
$first = $query->get(TransactionJournal::queryFields());
|
||||
|
||||
|
||||
// then collection transactions (harder)
|
||||
$query = $this->user->transactionJournals()->distinct()
|
||||
->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||
if (count($types) > 0) {
|
||||
$query->whereIn('transaction_types.type', $types);
|
||||
}
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$query->whereIn('transactions.account_id', $accountIds);
|
||||
}
|
||||
if ($categories->count() > 0) {
|
||||
$categoryIds = $categories->pluck('id')->toArray();
|
||||
$query->whereIn('category_transaction.category_id', $categoryIds);
|
||||
}
|
||||
|
||||
|
||||
$second = $query->get(['transaction_journals.*', 'transaction_types.type as transaction_type_type']);
|
||||
|
||||
$complete = $complete->merge($first);
|
||||
$complete = $complete->merge($second);
|
||||
|
||||
return $complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriodWithoutCategory(Collection $accounts, array $types, Carbon $start, Carbon $end) : Collection
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$query = $this->user
|
||||
->transactionJournals();
|
||||
if (count($types) > 0) {
|
||||
$query->transactionTypes($types);
|
||||
}
|
||||
|
||||
$query->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('category_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start);
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$query->leftJoin('transactions as t', 't.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
$query->whereIn('t.account_id', $accountIds);
|
||||
}
|
||||
|
||||
$set = $query->get(['transaction_journals.*']);
|
||||
|
||||
if ($set->count() == 0) {
|
||||
return new Collection;
|
||||
}
|
||||
|
||||
// grab all the transactions from this set.
|
||||
// take only the journals with transactions that all have no category.
|
||||
// select transactions left join journals where id in this set
|
||||
// and left join transaction-category where null category
|
||||
$journalIds = $set->pluck('id')->toArray();
|
||||
$secondQuery = $this->user->transactions()
|
||||
->leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id')
|
||||
->whereNull('category_transaction.id')
|
||||
->whereIn('transaction_journals.id', $journalIds);
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$secondQuery->whereIn('transactions.account_id', $accountIds);
|
||||
}
|
||||
|
||||
// this second set REALLY doesn't have any categories.
|
||||
$secondSet = $secondQuery->get(['transactions.transaction_journal_id']);
|
||||
$allIds = $secondSet->pluck('transaction_journal_id')->toArray();
|
||||
$return = $this->user->transactionJournals()->sortCorrectly()->expanded()->whereIn('transaction_journals.id', $allIds)->get(
|
||||
TransactionJournal::queryFields()
|
||||
);
|
||||
|
||||
return $return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
|
@ -15,7 +15,6 @@ namespace FireflyIII\Repositories\Category;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Category;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@ -84,36 +83,6 @@ interface CategoryRepositoryInterface
|
||||
*/
|
||||
public function getCategories(): Collection;
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param int $page
|
||||
* @param int $pageSize
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public function getJournals(Category $category, int $page, int $pageSize): LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* @param Collection $categories
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriod(Collection $categories, Collection $accounts, array $types, Carbon $start, Carbon $end): Collection;
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriodWithoutCategory(Collection $accounts, array $types, Carbon $start, Carbon $end) : Collection;
|
||||
|
||||
/**
|
||||
* Return most recent transaction(journal) date.
|
||||
*
|
||||
|
@ -458,7 +458,7 @@ class JournalRepository implements JournalRepositoryInterface
|
||||
*/
|
||||
private function storeBudgetWithJournal(TransactionJournal $journal, int $budgetId)
|
||||
{
|
||||
if (intval($budgetId) > 0 && $journal->transactionType->type !== TransactionType::TRANSFER) {
|
||||
if (intval($budgetId) > 0 && $journal->transactionType->type === TransactionType::WITHDRAWAL) {
|
||||
/** @var \FireflyIII\Models\Budget $budget */
|
||||
$budget = Budget::find($budgetId);
|
||||
$journal->budgets()->save($budget);
|
||||
|
@ -26,6 +26,16 @@ use Illuminate\Support\MessageBag;
|
||||
interface JournalRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param TransactionType $type
|
||||
* @param Account $source
|
||||
* @param Account $destination
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag;
|
||||
|
||||
/**
|
||||
* Deletes a journal.
|
||||
*
|
||||
@ -35,15 +45,6 @@ interface JournalRepositoryInterface
|
||||
*/
|
||||
public function delete(TransactionJournal $journal): bool;
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param TransactionType $type
|
||||
* @param array $data
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag;
|
||||
|
||||
/**
|
||||
* Find a specific journal
|
||||
*
|
||||
|
@ -46,73 +46,6 @@ class JournalTasker implements JournalTaskerInterface
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a page of a specific type(s) of journal.
|
||||
*
|
||||
* @param array $types
|
||||
* @param int $page
|
||||
* @param int $pageSize
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public function getJournals(array $types, int $page, int $pageSize = 50): LengthAwarePaginator
|
||||
{
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$query = $this->user->transactionJournals()->expanded()->sortCorrectly();
|
||||
$query->where('transaction_journals.completed', 1);
|
||||
if (count($types) > 0) {
|
||||
$query->transactionTypes($types);
|
||||
}
|
||||
$count = $this->user->transactionJournals()->transactionTypes($types)->count();
|
||||
$set = $query->take($pageSize)->offset($offset)->get(TransactionJournal::queryFields());
|
||||
$journals = new LengthAwarePaginator($set, $count, $pageSize, $page);
|
||||
|
||||
return $journals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of ALL journals, given a specific account and a date range.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournalsInRange(Collection $accounts, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
$query = $this->user->transactionJournals()->expanded()->sortCorrectly();
|
||||
$query->where('transaction_journals.completed', 1);
|
||||
$query->before($end);
|
||||
$query->after($start);
|
||||
|
||||
if ($accounts->count() > 0) {
|
||||
$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(
|
||||
function (Builder $q) use ($ids) {
|
||||
$q->whereIn('destination.account_id', $ids);
|
||||
$q->orWhereIn('source.account_id', $ids);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$set = $query->get(TransactionJournal::queryFields());
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
|
@ -26,27 +26,6 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
interface JournalTaskerInterface
|
||||
{
|
||||
/**
|
||||
* Returns a page of a specific type(s) of journal.
|
||||
*
|
||||
* @param array $types
|
||||
* @param int $page
|
||||
* @param int $pageSize
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
public function getJournals(array $types, int $page, int $pageSize = 50): LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Returns a collection of ALL journals, given a specific account and a date range.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournalsInRange(Collection $accounts, Carbon $start, Carbon $end): Collection;
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
|
@ -133,24 +133,6 @@ class TagRepository implements TagRepositoryInterface
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Tag $tag
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournals(Tag $tag) : Collection
|
||||
{
|
||||
/** @var Collection $journals */
|
||||
$journals = $tag
|
||||
->transactionJournals()
|
||||
->sortCorrectly()
|
||||
->expanded()
|
||||
->groupBy(['tag_transaction_journal.tag_id', 'tag_transaction_journal.transaction_journal_id'])
|
||||
->get(TransactionJournal::queryFields());
|
||||
|
||||
return $journals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
|
@ -65,13 +65,6 @@ interface TagRepositoryInterface
|
||||
*/
|
||||
public function get(): Collection;
|
||||
|
||||
/**
|
||||
* @param Tag $tag
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getJournals(Tag $tag) : Collection;
|
||||
|
||||
/**
|
||||
* This method stores a tag.
|
||||
*
|
||||
|
@ -16,6 +16,7 @@ namespace FireflyIII\Rules\Actions;
|
||||
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class ClearCategory
|
||||
|
@ -16,6 +16,7 @@ namespace FireflyIII\Rules;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleAction;
|
||||
use FireflyIII\Models\RuleTrigger;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Rules\Actions\ActionInterface;
|
||||
use FireflyIII\Rules\Factory\ActionFactory;
|
||||
@ -144,6 +145,36 @@ final class Processor
|
||||
return $this->rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will scan the given transaction journal and check if it matches the triggers found in the Processor
|
||||
* If so, it will also attempt to run the given actions on the journal. It returns a bool indicating if the transaction journal
|
||||
* matches all of the triggers (regardless of whether the Processor could act on it).
|
||||
*
|
||||
* @param Transaction $transaction
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handleTransaction(Transaction $transaction): bool
|
||||
{
|
||||
Log::debug(sprintf('handleTransactionJournal for journal #%d (transaction #%d)', $transaction->transaction_journal_id, $transaction->id));
|
||||
|
||||
// grab the actual journal.
|
||||
$journal = $transaction->transactionJournal()->first();
|
||||
$this->journal = $journal;
|
||||
// get all triggers:
|
||||
$triggered = $this->triggered();
|
||||
if ($triggered) {
|
||||
if ($this->actions->count() > 0) {
|
||||
$this->actions();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will scan the given transaction journal and check if it matches the triggers found in the Processor
|
||||
* If so, it will also attempt to run the given actions on the journal. It returns a bool indicating if the transaction journal
|
||||
|
@ -13,7 +13,8 @@ declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Rules;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Journal\JournalTaskerInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
@ -62,7 +63,7 @@ class TransactionMatcher
|
||||
if (count($this->triggers) === 0) {
|
||||
return new Collection;
|
||||
}
|
||||
$pagesize = min($this->range / 2, $this->limit * 2);
|
||||
$pageSize = min($this->range / 2, $this->limit * 2);
|
||||
|
||||
// Variables used within the loop
|
||||
$processed = 0;
|
||||
@ -76,31 +77,42 @@ class TransactionMatcher
|
||||
// - the maximum number of transactions to search in have been searched
|
||||
do {
|
||||
// Fetch a batch of transactions from the database
|
||||
$paginator = $this->tasker->getJournals($this->transactionTypes, $page, $pagesize);
|
||||
$set = $paginator->getCollection();
|
||||
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAllAssetAccounts()->setLimit($pageSize)->setPage($page)->setTypes($this->transactionTypes);
|
||||
$set = $collector->getPaginatedJournals();
|
||||
Log::debug(sprintf('Found %d journals to check. ', $set->count()));
|
||||
|
||||
// Filter transactions that match the given triggers.
|
||||
$filtered = $set->filter(
|
||||
function (TransactionJournal $journal) use ($processor) {
|
||||
Log::debug(sprintf('Test these triggers on #%d', $journal->id));
|
||||
function (Transaction $transaction) use ($processor) {
|
||||
Log::debug(sprintf('Test these triggers on journal #%d (transaction #%d)', $transaction->transaction_journal_id, $transaction->id));
|
||||
|
||||
return $processor->handleTransactionJournal($journal);
|
||||
return $processor->handleTransaction($transaction);
|
||||
}
|
||||
);
|
||||
|
||||
Log::debug(sprintf('Found %d journals that match.', $filtered->count()));
|
||||
|
||||
// merge:
|
||||
/** @var Collection $result */
|
||||
$result = $result->merge($filtered);
|
||||
Log::debug(sprintf('Total count is now %d', $result->count()));
|
||||
|
||||
// Update counters
|
||||
$page++;
|
||||
$processed += count($set);
|
||||
|
||||
Log::debug(sprintf('Page is now %d, processed is %d', $page, $processed));
|
||||
|
||||
// Check for conditions to finish the loop
|
||||
$reachedEndOfList = $set->count() < $pagesize;
|
||||
$reachedEndOfList = $set->count() < 1;
|
||||
$foundEnough = $result->count() >= $this->limit;
|
||||
$searchedEnough = ($processed >= $this->range);
|
||||
|
||||
Log::debug(sprintf('reachedEndOfList: %s', var_export($reachedEndOfList, true)));
|
||||
Log::debug(sprintf('foundEnough: %s', var_export($foundEnough, true)));
|
||||
Log::debug(sprintf('searchedEnough: %s', var_export($searchedEnough, true)));
|
||||
|
||||
} while (!$reachedEndOfList && !$foundEnough && !$searchedEnough);
|
||||
|
||||
// If the list of matchingTransactions is larger than the maximum number of results
|
||||
|
@ -59,14 +59,14 @@ class Amount
|
||||
if ($coloured === true) {
|
||||
|
||||
if ($amount > 0) {
|
||||
return '<span class="text-success" title="' . e($float) . '">' . $result . '</span>';
|
||||
return sprintf('<span class="text-success">%s</span>', $result);
|
||||
} else {
|
||||
if ($amount < 0) {
|
||||
return '<span class="text-danger" title="' . e($float) . '">' . $result . '</span>';
|
||||
return sprintf('<span class="text-danger">%s</span>', $result);
|
||||
}
|
||||
}
|
||||
|
||||
return '<span style="color:#999" title="' . e($float) . '">' . $result . '</span>';
|
||||
return sprintf('<span style="color:#999">%s</span>', $result);
|
||||
|
||||
|
||||
}
|
||||
@ -139,14 +139,14 @@ class Amount
|
||||
if ($coloured === true) {
|
||||
|
||||
if ($amount > 0) {
|
||||
return '<span class="text-success" title="' . e($float) . '">' . $result . '</span>';
|
||||
return sprintf('<span class="text-success">%s</span>', $result);
|
||||
} else {
|
||||
if ($amount < 0) {
|
||||
return '<span class="text-danger" title="' . e($float) . '">' . $result . '</span>';
|
||||
return sprintf('<span class="text-danger">%s</span>', $result);
|
||||
}
|
||||
}
|
||||
|
||||
return '<span style="color:#999" title="' . e($float) . '">' . $result . '</span>';
|
||||
return sprintf('<span style="color:#999">%s</span>', $result);
|
||||
|
||||
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class Navigation
|
||||
];
|
||||
|
||||
if (!isset($functionMap[$repeatFreq])) {
|
||||
throw new FireflyException('Cannot do addPeriod for $repeat_freq "' . $repeatFreq . '"');
|
||||
throw new FireflyException(sprintf('Cannot do addPeriod for $repeat_freq "%s"', $repeatFreq));
|
||||
}
|
||||
if (isset($modifierMap[$repeatFreq])) {
|
||||
$add = $add * $modifierMap[$repeatFreq];
|
||||
@ -108,7 +108,7 @@ class Navigation
|
||||
}
|
||||
|
||||
if (!isset($functionMap[$repeatFreq])) {
|
||||
throw new FireflyException('Cannot do endOfPeriod for $repeat_freq "' . $repeatFreq . '"');
|
||||
throw new FireflyException(sprintf('Cannot do endOfPeriod for $repeat_freq "%s"', $repeatFreq));
|
||||
}
|
||||
$function = $functionMap[$repeatFreq];
|
||||
if (isset($modifierMap[$repeatFreq])) {
|
||||
@ -202,7 +202,7 @@ class Navigation
|
||||
if (isset($formatMap[$repeatFrequency])) {
|
||||
return $date->formatLocalized(strval($formatMap[$repeatFrequency]));
|
||||
}
|
||||
throw new FireflyException('No date formats for frequency "' . $repeatFrequency . '"!');
|
||||
throw new FireflyException(sprintf('No date formats for frequency "%s"!', $repeatFrequency));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -252,7 +252,7 @@ class Navigation
|
||||
}
|
||||
|
||||
|
||||
throw new FireflyException('Cannot do startOfPeriod for $repeat_freq "' . $repeatFreq . '"');
|
||||
throw new FireflyException(sprintf('Cannot do startOfPeriod for $repeat_freq "%s"', $repeatFreq));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -313,7 +313,7 @@ class Navigation
|
||||
return $date;
|
||||
}
|
||||
|
||||
throw new FireflyException('Cannot do subtractPeriod for $repeat_freq "' . $repeatFreq . '"');
|
||||
throw new FireflyException(sprintf('Cannot do subtractPeriod for $repeat_freq "%s"', $repeatFreq));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -350,7 +350,7 @@ class Navigation
|
||||
|
||||
return $end;
|
||||
}
|
||||
throw new FireflyException('updateEndDate cannot handle $range "' . $range . '"');
|
||||
throw new FireflyException(sprintf('updateEndDate cannot handle range "%s"', $range));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -387,7 +387,7 @@ class Navigation
|
||||
|
||||
|
||||
}
|
||||
throw new FireflyException('updateStartDate cannot handle $range "' . $range . '"');
|
||||
throw new FireflyException(sprintf('updateStartDate cannot handle range "%s"', $range));
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ class Preferences
|
||||
*/
|
||||
public function delete($name): bool
|
||||
{
|
||||
$fullName = 'preference' . auth()->user()->id . $name;
|
||||
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
|
||||
if (Cache::has($fullName)) {
|
||||
Cache::forget($fullName);
|
||||
}
|
||||
@ -66,7 +66,7 @@ class Preferences
|
||||
*/
|
||||
public function getForUser(User $user, $name, $default = null)
|
||||
{
|
||||
$fullName = 'preference' . $user->id . $name;
|
||||
$fullName = sprintf('preference%s%s', $user->id, $name);
|
||||
if (Cache::has($fullName)) {
|
||||
return Cache::get($fullName);
|
||||
}
|
||||
@ -138,7 +138,7 @@ class Preferences
|
||||
*/
|
||||
public function setForUser(User $user, $name, $value): Preference
|
||||
{
|
||||
$fullName = 'preference' . $user->id . $name;
|
||||
$fullName = sprintf('preference%s%s', $user->id, $name);
|
||||
Cache::forget($fullName);
|
||||
$pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data']);
|
||||
|
||||
|
@ -14,11 +14,15 @@ declare(strict_types = 1);
|
||||
namespace FireflyIII\Support\Search;
|
||||
|
||||
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class Search
|
||||
@ -27,20 +31,46 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class Search implements SearchInterface
|
||||
{
|
||||
/** @var int */
|
||||
private $limit = 100;
|
||||
/** @var User */
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* AttachmentRepository constructor.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* The search will assume that the user does not have so many accounts
|
||||
* that this search should be paginated.
|
||||
*
|
||||
* @param array $words
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchAccounts(array $words): Collection
|
||||
{
|
||||
return auth()->user()->accounts()->with('accounttype')->where(
|
||||
function (EloquentBuilder $q) use ($words) {
|
||||
foreach ($words as $word) {
|
||||
$q->orWhere('name', 'LIKE', '%' . e($word) . '%');
|
||||
$accounts = $this->user->accounts()->get();
|
||||
/** @var Collection $result */
|
||||
$result = $accounts->filter(
|
||||
function (Account $account) use ($words) {
|
||||
if ($this->strpos_arr(strtolower($account->name), $words)) {
|
||||
return $account;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
)->get();
|
||||
);
|
||||
|
||||
$result = $result->slice(0, $this->limit);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,46 +81,46 @@ class Search implements SearchInterface
|
||||
public function searchBudgets(array $words): Collection
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$set = auth()->user()->budgets()->get();
|
||||
$newSet = $set->filter(
|
||||
function (Budget $b) use ($words) {
|
||||
$found = 0;
|
||||
foreach ($words as $word) {
|
||||
if (!(strpos(strtolower($b->name), strtolower($word)) === false)) {
|
||||
$found++;
|
||||
}
|
||||
$set = auth()->user()->budgets()->get();
|
||||
/** @var Collection $result */
|
||||
$result = $set->filter(
|
||||
function (Budget $budget) use ($words) {
|
||||
if ($this->strpos_arr(strtolower($budget->name), $words)) {
|
||||
return $budget;
|
||||
}
|
||||
|
||||
return $found > 0;
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
return $newSet;
|
||||
$result = $result->slice(0, $this->limit);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search assumes the user does not have that many categories. So no paginated search.
|
||||
*
|
||||
* @param array $words
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchCategories(array $words): Collection
|
||||
{
|
||||
/** @var Collection $set */
|
||||
$set = auth()->user()->categories()->get();
|
||||
$newSet = $set->filter(
|
||||
function (Category $c) use ($words) {
|
||||
$found = 0;
|
||||
foreach ($words as $word) {
|
||||
if (!(strpos(strtolower($c->name), strtolower($word)) === false)) {
|
||||
$found++;
|
||||
}
|
||||
$categories = $this->user->categories()->get();
|
||||
/** @var Collection $result */
|
||||
$result = $categories->filter(
|
||||
function (Category $category) use ($words) {
|
||||
if ($this->strpos_arr(strtolower($category->name), $words)) {
|
||||
return $category;
|
||||
}
|
||||
|
||||
return $found > 0;
|
||||
return false;
|
||||
}
|
||||
);
|
||||
$result = $result->slice(0, $this->limit);
|
||||
|
||||
return $newSet;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,7 +131,21 @@ class Search implements SearchInterface
|
||||
*/
|
||||
public function searchTags(array $words): Collection
|
||||
{
|
||||
return new Collection;
|
||||
$tags = $this->user->tags()->get();
|
||||
|
||||
/** @var Collection $result */
|
||||
$result = $tags->filter(
|
||||
function (Tag $tag) use ($words) {
|
||||
if ($this->strpos_arr(strtolower($tag->tag), $words)) {
|
||||
return $tag;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
$result = $result->slice(0, $this->limit);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,40 +155,86 @@ class Search implements SearchInterface
|
||||
*/
|
||||
public function searchTransactions(array $words): Collection
|
||||
{
|
||||
// decrypted transaction journals:
|
||||
$decrypted = auth()->user()->transactionJournals()->expanded()->where('transaction_journals.encrypted', 0)->where(
|
||||
function (EloquentBuilder $q) use ($words) {
|
||||
foreach ($words as $word) {
|
||||
$q->orWhere('transaction_journals.description', 'LIKE', '%' . e($word) . '%');
|
||||
}
|
||||
}
|
||||
)->get(TransactionJournal::queryFields());
|
||||
$pageSize = 100;
|
||||
$processed = 0;
|
||||
$page = 1;
|
||||
$result = new Collection();
|
||||
do {
|
||||
$collector = new JournalCollector($this->user);
|
||||
$collector->setAllAssetAccounts()->setLimit($pageSize)->setPage($page);
|
||||
$set = $collector->getPaginatedJournals();
|
||||
Log::debug(sprintf('Found %d journals to check. ', $set->count()));
|
||||
|
||||
// encrypted
|
||||
$all = auth()->user()->transactionJournals()->expanded()->where('transaction_journals.encrypted', 1)->get(TransactionJournal::queryFields());
|
||||
$set = $all->filter(
|
||||
function (TransactionJournal $journal) use ($words) {
|
||||
foreach ($words as $word) {
|
||||
$haystack = strtolower($journal->description);
|
||||
$word = strtolower($word);
|
||||
if (!(strpos($haystack, $word) === false)) {
|
||||
return $journal;
|
||||
// Filter transactions that match the given triggers.
|
||||
$filtered = $set->filter(
|
||||
function (Transaction $transaction) use ($words) {
|
||||
// check descr of journal:
|
||||
if ($this->strpos_arr(strtolower(strval($transaction->description)), $words)) {
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
// check descr of transaction
|
||||
if ($this->strpos_arr(strtolower(strval($transaction->transaction_description)), $words)) {
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
// return false:
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
return null;
|
||||
Log::debug(sprintf('Found %d journals that match.', $filtered->count()));
|
||||
|
||||
// merge:
|
||||
/** @var Collection $result */
|
||||
$result = $result->merge($filtered);
|
||||
Log::debug(sprintf('Total count is now %d', $result->count()));
|
||||
|
||||
// Update counters
|
||||
$page++;
|
||||
$processed += count($set);
|
||||
|
||||
Log::debug(sprintf('Page is now %d, processed is %d', $page, $processed));
|
||||
|
||||
// Check for conditions to finish the loop
|
||||
$reachedEndOfList = $set->count() < 1;
|
||||
$foundEnough = $result->count() >= $this->limit;
|
||||
|
||||
Log::debug(sprintf('reachedEndOfList: %s', var_export($reachedEndOfList, true)));
|
||||
Log::debug(sprintf('foundEnough: %s', var_export($foundEnough, true)));
|
||||
|
||||
} while (!$reachedEndOfList && !$foundEnough);
|
||||
|
||||
$result = $result->slice(0, $this->limit);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
*/
|
||||
public function setLimit(int $limit)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $haystack
|
||||
* @param array $needle
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function strpos_arr(string $haystack, array $needle)
|
||||
{
|
||||
if (strlen($haystack) === 0) {
|
||||
return false;
|
||||
}
|
||||
foreach ($needle as $what) {
|
||||
if (($pos = strpos($haystack, $what)) !== false) {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
$filtered = $set->merge($decrypted);
|
||||
$filtered = $filtered->sortBy(
|
||||
function (TransactionJournal $journal) {
|
||||
return intval($journal->date->format('U'));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$filtered = $filtered->reverse();
|
||||
|
||||
return $filtered;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ class Journal extends Twig_Extension
|
||||
$array[] = '<span class="text-success">(cash)</span>';
|
||||
continue;
|
||||
}
|
||||
$array[] = '<a title="' . e($entry->name) . '" href="' . route('accounts.show', $entry->id) . '">' . e($entry->name) . '</a>';
|
||||
$array[] = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($entry->name), route('accounts.show', $entry->id));
|
||||
}
|
||||
$array = array_unique($array);
|
||||
$result = join(', ', $array);
|
||||
@ -221,7 +221,7 @@ class Journal extends Twig_Extension
|
||||
$array[] = '<span class="text-success">(cash)</span>';
|
||||
continue;
|
||||
}
|
||||
$array[] = '<a title="' . e($entry->name) . '" href="' . route('accounts.show', $entry->id) . '">' . e($entry->name) . '</a>';
|
||||
$array[] = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($entry->name), route('accounts.show', $entry->id));
|
||||
}
|
||||
$array = array_unique($array);
|
||||
$result = join(', ', $array);
|
||||
@ -253,12 +253,12 @@ class Journal extends Twig_Extension
|
||||
$budgets = [];
|
||||
// get all budgets:
|
||||
foreach ($journal->budgets as $budget) {
|
||||
$budgets[] = '<a href="' . route('budgets.show', [$budget->id]) . '" title="' . e($budget->name) . '">' . e($budget->name) . '</a>';
|
||||
$budgets[] = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($budget->name), route('accounts.show', $budget->id));
|
||||
}
|
||||
// and more!
|
||||
foreach ($journal->transactions as $transaction) {
|
||||
foreach ($transaction->budgets as $budget) {
|
||||
$budgets[] = '<a href="' . route('budgets.show', [$budget->id]) . '" title="' . e($budget->name) . '">' . e($budget->name) . '</a>';
|
||||
$budgets[] = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($budget->name), route('accounts.show', $budget->id));
|
||||
}
|
||||
}
|
||||
$string = join(', ', array_unique($budgets));
|
||||
@ -288,7 +288,7 @@ class Journal extends Twig_Extension
|
||||
$categories = [];
|
||||
// get all categories for the journal itself (easy):
|
||||
foreach ($journal->categories as $category) {
|
||||
$categories[] = '<a href="' . route('categories.show', [$category->id]) . '" title="' . e($category->name) . '">' . e($category->name) . '</a>';
|
||||
$categories[] = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($category->name), route('accounts.show', $category->id));
|
||||
}
|
||||
if (count($categories) === 0) {
|
||||
$set = Category::distinct()->leftJoin('category_transaction', 'categories.id', '=', 'category_transaction.category_id')
|
||||
@ -299,8 +299,7 @@ class Journal extends Twig_Extension
|
||||
->get(['categories.*']);
|
||||
/** @var Category $category */
|
||||
foreach ($set as $category) {
|
||||
$categories[] = '<a href="' . route('categories.show', [$category->id]) . '" title="' . e($category->name) . '">' . e($category->name)
|
||||
. '</a>';
|
||||
$categories[] = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($category->name), route('accounts.show', $category->id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,16 +323,16 @@ class Journal extends Twig_Extension
|
||||
|
||||
switch (true) {
|
||||
case $journal->isWithdrawal():
|
||||
$txt = '<i class="fa fa-long-arrow-left fa-fw" title="' . trans('firefly.withdrawal') . '"></i>';
|
||||
$txt = sprintf('<i class="fa fa-long-arrow-left fa-fw" title="%s"></i>', trans('firefly.withdrawal'));
|
||||
break;
|
||||
case $journal->isDeposit():
|
||||
$txt = '<i class="fa fa-long-arrow-right fa-fw" title="' . trans('firefly.deposit') . '"></i>';
|
||||
$txt = sprintf('<i class="fa fa-long-arrow-right fa-fw" title="%s"></i>', trans('firefly.deposit'));
|
||||
break;
|
||||
case $journal->isTransfer():
|
||||
$txt = '<i class="fa fa-fw fa-exchange" title="' . trans('firefly.transfer') . '"></i>';
|
||||
$txt = sprintf('<i class="fa fa-fw fa-exchange" title="%s"></i>', trans('firefly.transfer'));
|
||||
break;
|
||||
case $journal->isOpeningBalance():
|
||||
$txt = '<i class="fa-fw fa fa-ban" title="' . trans('firefly.openingBalance') . '"></i>';
|
||||
$txt = sprintf('<i class="fa-fw fa fa-ban" title="%s"></i>', trans('firefly.openingBalance'));
|
||||
break;
|
||||
default:
|
||||
$txt = '';
|
||||
|
@ -125,7 +125,7 @@ class Transaction extends Twig_Extension
|
||||
&& bccomp($amount, bcmul($transactionAmount, '-1')) !== 0
|
||||
) {
|
||||
// not equal?
|
||||
return ' (' . Amount::formatWithCode($code, $amount, true) . ')';
|
||||
return sprintf(' (%s)', Amount::formatWithCode($code, $amount, true));
|
||||
}
|
||||
|
||||
return '';
|
||||
@ -144,7 +144,7 @@ class Transaction extends Twig_Extension
|
||||
'splitJournalIndicator', function (int $journalId) {
|
||||
$count = TransactionModel::where('transaction_journal_id', $journalId)->whereNull('deleted_at')->count();
|
||||
if ($count > 2) {
|
||||
return '<i class="fa fa-fw fa-share-alt-square" aria-hidden="true"></i>';
|
||||
return '<i class="fa fa-fw fa-share-alt" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
return '';
|
||||
@ -210,7 +210,7 @@ class Transaction extends Twig_Extension
|
||||
return '<span class="text-success">(cash)</span>';
|
||||
}
|
||||
|
||||
return '<a title="' . e($name) . '" href="' . route('accounts.show', [$id]) . '">' . e($name) . '</a>';
|
||||
return sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($name), route('accounts.show', [$id]));
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
@ -276,7 +276,7 @@ class Transaction extends Twig_Extension
|
||||
return '<span class="text-success">(cash)</span>';
|
||||
}
|
||||
|
||||
return '<a title="' . e($name) . '" href="' . route('accounts.show', [$id]) . '">' . e($name) . '</a>';
|
||||
return sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($name), route('accounts.show', [$id]));
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
@ -294,16 +294,16 @@ class Transaction extends Twig_Extension
|
||||
|
||||
switch ($transaction->transaction_type_type) {
|
||||
case TransactionType::WITHDRAWAL:
|
||||
$txt = '<i class="fa fa-long-arrow-left fa-fw" title="' . trans('firefly.withdrawal') . '"></i>';
|
||||
$txt = sprintf('<i class="fa fa-long-arrow-left fa-fw" title="%s"></i>', trans('firefly.withdrawal'));
|
||||
break;
|
||||
case TransactionType::DEPOSIT:
|
||||
$txt = '<i class="fa fa-long-arrow-right fa-fw" title="' . trans('firefly.deposit') . '"></i>';
|
||||
$txt = sprintf('<i class="fa fa-long-arrow-right fa-fw" title="%s"></i>', trans('firefly.deposit'));
|
||||
break;
|
||||
case TransactionType::TRANSFER:
|
||||
$txt = '<i class="fa fa-fw fa-exchange" title="' . trans('firefly.transfer') . '"></i>';
|
||||
$txt = sprintf('<i class="fa fa-fw fa-exchange" title="%s"></i>', trans('firefly.transfer'));
|
||||
break;
|
||||
case TransactionType::OPENING_BALANCE:
|
||||
$txt = '<i class="fa-fw fa fa-ban" title="' . trans('firefly.openingBalance') . '"></i>';
|
||||
$txt = sprintf('<i class="fa-fw fa fa-ban" title="%s"></i>', trans('firefly.openingBalance'));
|
||||
break;
|
||||
default:
|
||||
$txt = '';
|
||||
|
@ -35,7 +35,7 @@ class Translation extends Twig_Extension
|
||||
$filters[] = new Twig_SimpleFilter(
|
||||
'_', function ($name) {
|
||||
|
||||
return trans('firefly.' . $name);
|
||||
return strval(trans(sprintf('firefly.%s', $name)));
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
|
@ -71,6 +71,7 @@
|
||||
],
|
||||
"post-install-cmd": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postInstall",
|
||||
"php artisan firefly:github-move",
|
||||
"php artisan optimize"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
@ -78,6 +79,7 @@
|
||||
"php artisan firefly:upgrade-instructions",
|
||||
"php artisan firefly:upgrade-database",
|
||||
"php artisan firefly:verify",
|
||||
"php artisan firefly:github-move",
|
||||
"php artisan optimize"
|
||||
]
|
||||
},
|
||||
|
2
composer.lock
generated
2
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "cc3d23620e727ee1f4741b2e83f8685f",
|
||||
"hash": "12c9e9450c824d192b8c049989188b8e",
|
||||
"content-hash": "473d3c681e5c41989e9dced651a939df",
|
||||
"packages": [
|
||||
{
|
||||
|
@ -208,6 +208,7 @@ return [
|
||||
FireflyIII\Providers\PiggyBankServiceProvider::class,
|
||||
FireflyIII\Providers\RuleServiceProvider::class,
|
||||
FireflyIII\Providers\RuleGroupServiceProvider::class,
|
||||
FireflyIII\Providers\SearchServiceProvider::class,
|
||||
FireflyIII\Providers\TagServiceProvider::class,
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ return [
|
||||
'single_user_mode' => true,
|
||||
],
|
||||
'chart' => 'chartjs',
|
||||
'version' => '4.1.5',
|
||||
'version' => '4.1.6',
|
||||
'csv_import_enabled' => true,
|
||||
'maxUploadSize' => 5242880,
|
||||
'allowedMimes' => ['image/png', 'image/jpeg', 'application/pdf'],
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* globals startDate, showOnlyTop, showFullList, endDate, reportType, accountIds, inOutReportUrl, accountReportUrl */
|
||||
/* globals startDate, showOnlyTop, showFullList, endDate, reportType, expenseReportUri, accountIds, incExpReportUri,accountReportUri, incomeReportUri */
|
||||
/*
|
||||
* all.js
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
@ -11,25 +11,20 @@ $(function () {
|
||||
"use strict";
|
||||
|
||||
|
||||
|
||||
// load the account report, which this report shows:
|
||||
loadAccountReport();
|
||||
loadAjaxPartial('accountReport', accountReportUri);
|
||||
|
||||
// load income / expense / difference:
|
||||
loadInOutReport();
|
||||
|
||||
// trigger info click
|
||||
triggerInfoClick();
|
||||
|
||||
// trigger list length things:
|
||||
listLengthInitial();
|
||||
// load income and expense reports:
|
||||
loadAjaxPartial('incomeReport', incomeReportUri);
|
||||
loadAjaxPartial('expenseReport', expenseReportUri);
|
||||
loadAjaxPartial('incomeVsExpenseReport', incExpReportUri);
|
||||
|
||||
});
|
||||
|
||||
function triggerInfoClick() {
|
||||
"use strict";
|
||||
// find the little info buttons and respond to them.
|
||||
$('.firefly-info-button').unbind('clicl').click(clickInfoButton);
|
||||
$('.firefly-info-button').unbind('click').click(clickInfoButton);
|
||||
}
|
||||
|
||||
function listLengthInitial() {
|
||||
@ -58,44 +53,6 @@ function triggerList(e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function loadInOutReport() {
|
||||
"use strict";
|
||||
console.log('Going to grab ' + inOutReportUrl);
|
||||
$.get(inOutReportUrl).done(placeInOutReport).fail(failInOutReport);
|
||||
}
|
||||
|
||||
function placeInOutReport(data) {
|
||||
"use strict";
|
||||
$('#incomeReport').removeClass('loading').html(data.income);
|
||||
$('#expenseReport').removeClass('loading').html(data.expenses);
|
||||
$('#incomeVsExpenseReport').removeClass('loading').html(data.incomes_expenses);
|
||||
listLengthInitial();
|
||||
triggerInfoClick();
|
||||
}
|
||||
|
||||
function failInOutReport() {
|
||||
"use strict";
|
||||
console.log('Fail in/out report data!');
|
||||
$('#incomeReport').removeClass('loading').addClass('general-chart-error');
|
||||
$('#expenseReport').removeClass('loading').addClass('general-chart-error');
|
||||
$('#incomeVsExpenseReport').removeClass('loading').addClass('general-chart-error');
|
||||
}
|
||||
|
||||
function loadAccountReport() {
|
||||
"use strict";
|
||||
$.get(accountReportUrl).done(placeAccountReport).fail(failAccountReport);
|
||||
}
|
||||
|
||||
function placeAccountReport(data) {
|
||||
"use strict";
|
||||
$('#accountReport').removeClass('loading').html(data);
|
||||
}
|
||||
|
||||
function failAccountReport(data) {
|
||||
"use strict";
|
||||
$('#accountReport').removeClass('loading').addClass('general-chart-error');
|
||||
}
|
||||
|
||||
function clickInfoButton(e) {
|
||||
"use strict";
|
||||
// find all data tags, regardless of what they are:
|
||||
@ -125,7 +82,111 @@ function respondInfoButton(data) {
|
||||
"use strict";
|
||||
// remove wait cursor
|
||||
$('body').removeClass('waiting');
|
||||
$('#defaultModal').empty().html(data.html);
|
||||
$('#defaultModal').modal('show');
|
||||
$('#defaultModal').empty().html(data.html).modal('show');
|
||||
|
||||
}
|
||||
|
||||
function loadAjaxPartial(holder, uri) {
|
||||
"use strict";
|
||||
console.log('Going to grab URI ' + uri);
|
||||
$.get(uri).done(function (data) {
|
||||
displayAjaxPartial(data, holder);
|
||||
}).fail(function () {
|
||||
failAjaxPartial(uri, holder);
|
||||
});
|
||||
}
|
||||
|
||||
function displayAjaxPartial(data, holder) {
|
||||
"use strict";
|
||||
console.log('Display stuff in ' + holder);
|
||||
var obj = $('#' + holder);
|
||||
obj.removeClass('loading').html(data);
|
||||
|
||||
// call some often needed recalculations and what-not:
|
||||
|
||||
// find a sortable table and make it sortable:
|
||||
if (typeof $.bootstrapSortable === "function") {
|
||||
$.bootstrapSortable(true);
|
||||
}
|
||||
|
||||
// find the info click things and respond to them:
|
||||
triggerInfoClick();
|
||||
|
||||
// trigger list thing
|
||||
listLengthInitial();
|
||||
|
||||
// budget thing
|
||||
$('.budget-chart-activate').unbind('click').on('click', clickBudgetChart);
|
||||
}
|
||||
|
||||
function failAjaxPartial(uri, holder) {
|
||||
"use strict";
|
||||
console.log('Failed to load' + uri);
|
||||
$('#' + holder).removeClass('loading').addClass('general-chart-error');
|
||||
|
||||
}
|
||||
|
||||
function clickBudgetChart(e) {
|
||||
"use strict";
|
||||
var link = $(e.target);
|
||||
var budgetId = link.data('budget');
|
||||
var URL = 'chart/budget/period/' + budgetId + '/' + reportType + '/' + startDate + '/' + endDate + '/' + accountIds;
|
||||
var container = 'budget_chart';
|
||||
// if chart drawn is false, draw the first one, then
|
||||
// set to true
|
||||
if (chartDrawn == false) {
|
||||
// do new chart:
|
||||
|
||||
|
||||
$.getJSON(URL).done(function (data) {
|
||||
console.log('Will draw new columnChart(' + URL + ')');
|
||||
|
||||
var ctx = document.getElementById(container).getContext("2d");
|
||||
var newData = {};
|
||||
newData.datasets = [];
|
||||
|
||||
for (var i = 0; i < data.count; i++) {
|
||||
newData.labels = data.labels;
|
||||
var dataset = data.datasets[i];
|
||||
dataset.backgroundColor = fillColors[i];
|
||||
newData.datasets.push(dataset);
|
||||
}
|
||||
// completely new chart.
|
||||
budgetChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: data,
|
||||
options: defaultColumnOptions
|
||||
});
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
console.log('URL for column chart : ' + URL);
|
||||
chartDrawn = true;
|
||||
} else {
|
||||
console.log('Will now handle remove data and add new!');
|
||||
$.getJSON(URL).done(function (data) {
|
||||
console.log('Will draw updated columnChart(' + URL + ')');
|
||||
var newData = {};
|
||||
newData.datasets = [];
|
||||
|
||||
for (var i = 0; i < data.count; i++) {
|
||||
newData.labels = data.labels;
|
||||
var dataset = data.datasets[i];
|
||||
dataset.backgroundColor = fillColors[i];
|
||||
newData.datasets.push(dataset);
|
||||
}
|
||||
// update the chart
|
||||
console.log('Now update chart thing.');
|
||||
budgetChart.data.datasets = newData.datasets;
|
||||
budgetChart.update();
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,74 +1,15 @@
|
||||
/* globals google, budgetReportUrl, startDate ,reportURL, endDate , reportType ,accountIds, lineChart, categoryReportUrl, balanceReportUrl */
|
||||
/* globals google, categoryReportUri, budgetReportUri, balanceReportUri */
|
||||
|
||||
|
||||
$(function () {
|
||||
"use strict";
|
||||
drawChart();
|
||||
|
||||
loadCategoryReport();
|
||||
loadBalanceReport();
|
||||
loadBudgetReport();
|
||||
loadAjaxPartial('categoryReport', categoryReportUri);
|
||||
loadAjaxPartial('budgetReport', budgetReportUri);
|
||||
loadAjaxPartial('balanceReport',balanceReportUri);
|
||||
});
|
||||
|
||||
function loadCategoryReport() {
|
||||
"use strict";
|
||||
console.log('Going to grab ' + categoryReportUrl);
|
||||
$.get(categoryReportUrl).done(placeCategoryReport).fail(failCategoryReport);
|
||||
}
|
||||
|
||||
function loadBudgetReport() {
|
||||
"use strict";
|
||||
console.log('Going to grab ' + budgetReportUrl);
|
||||
$.get(budgetReportUrl).done(placeBudgetReport).fail(failBudgetReport);
|
||||
}
|
||||
|
||||
|
||||
function loadBalanceReport() {
|
||||
"use strict";
|
||||
console.log('Going to grab ' + categoryReportUrl);
|
||||
$.get(balanceReportUrl).done(placeBalanceReport).fail(failBalanceReport);
|
||||
}
|
||||
|
||||
function placeBudgetReport(data) {
|
||||
"use strict";
|
||||
$('#budgetReport').removeClass('loading').html(data);
|
||||
listLengthInitial();
|
||||
triggerInfoClick();
|
||||
}
|
||||
|
||||
function placeBalanceReport(data) {
|
||||
"use strict";
|
||||
$('#balanceReport').removeClass('loading').html(data);
|
||||
listLengthInitial();
|
||||
triggerInfoClick();
|
||||
}
|
||||
|
||||
function placeCategoryReport(data) {
|
||||
"use strict";
|
||||
$('#categoryReport').removeClass('loading').html(data);
|
||||
listLengthInitial();
|
||||
triggerInfoClick();
|
||||
}
|
||||
|
||||
function failBudgetReport() {
|
||||
"use strict";
|
||||
console.log('Fail budget report data!');
|
||||
$('#budgetReport').removeClass('loading').addClass('general-chart-error');
|
||||
}
|
||||
|
||||
function failBalanceReport() {
|
||||
"use strict";
|
||||
console.log('Fail balance report data!');
|
||||
$('#balanceReport').removeClass('loading').addClass('general-chart-error');
|
||||
}
|
||||
|
||||
function failCategoryReport() {
|
||||
"use strict";
|
||||
console.log('Fail category report data!');
|
||||
$('#categoryReport').removeClass('loading').addClass('general-chart-error');
|
||||
}
|
||||
|
||||
|
||||
function drawChart() {
|
||||
"use strict";
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
/* globals google, startDate ,reportURL, endDate , reportType ,accountIds , picker:true, minDate, year, month, columnChart, lineChart, stackedColumnChart */
|
||||
/* globals budgetMultiUri, accountIds */
|
||||
|
||||
|
||||
$(function () {
|
||||
"use strict";
|
||||
drawChart();
|
||||
|
||||
loadAjaxPartial('budgetMultiYear', budgetMultiUri);
|
||||
});
|
||||
|
||||
|
||||
function drawChart() {
|
||||
"use strict";
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* globals google, accountIds, budgetYearOverviewUrl */
|
||||
/* globals google, accountIds, budgetYearOverviewUri */
|
||||
|
||||
var chartDrawn;
|
||||
var budgetChart;
|
||||
@ -7,30 +7,9 @@ $(function () {
|
||||
chartDrawn = false;
|
||||
drawChart();
|
||||
|
||||
//
|
||||
loadBudgetOverview();
|
||||
loadAjaxPartial('budgetOverview',budgetYearOverviewUri);
|
||||
});
|
||||
|
||||
function loadBudgetOverview() {
|
||||
"use strict";
|
||||
console.log('Going to grab ' + budgetYearOverviewUrl);
|
||||
$.get(budgetYearOverviewUrl).done(placeBudgetOverview).fail(failBudgetOverview);
|
||||
}
|
||||
|
||||
function placeBudgetOverview(data) {
|
||||
"use strict";
|
||||
$('#budgetOverview').removeClass('loading').html(data);
|
||||
$('.budget-chart-activate').on('click', clickBudgetChart);
|
||||
}
|
||||
|
||||
function failBudgetOverview() {
|
||||
"use strict";
|
||||
console.log('Fail budget overview data!');
|
||||
$('#budgetOverview').removeClass('loading').addClass('general-chart-error');
|
||||
}
|
||||
|
||||
|
||||
|
||||
function drawChart() {
|
||||
"use strict";
|
||||
|
||||
@ -40,68 +19,3 @@ function drawChart() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
function clickBudgetChart(e) {
|
||||
"use strict";
|
||||
var link = $(e.target);
|
||||
var budgetId = link.data('budget');
|
||||
var URL = 'chart/budget/period/' + budgetId + '/' + reportType + '/' + startDate + '/' + endDate + '/' + accountIds;
|
||||
var container = 'budget_chart';
|
||||
// if chart drawn is false, draw the first one, then
|
||||
// set to true
|
||||
if (chartDrawn == false) {
|
||||
// do new chart:
|
||||
|
||||
|
||||
$.getJSON(URL).done(function (data) {
|
||||
console.log('Will draw new columnChart(' + URL + ')');
|
||||
|
||||
var ctx = document.getElementById(container).getContext("2d");
|
||||
var newData = {};
|
||||
newData.datasets = [];
|
||||
|
||||
for (var i = 0; i < data.count; i++) {
|
||||
newData.labels = data.labels;
|
||||
var dataset = data.datasets[i];
|
||||
dataset.backgroundColor = fillColors[i];
|
||||
newData.datasets.push(dataset);
|
||||
}
|
||||
// completely new chart.
|
||||
budgetChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: data,
|
||||
options: defaultColumnOptions
|
||||
});
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
console.log('URL for column chart : ' + URL);
|
||||
chartDrawn = true;
|
||||
} else {
|
||||
console.log('Will now handle remove data and add new!');
|
||||
$.getJSON(URL).done(function (data) {
|
||||
console.log('Will draw updated columnChart(' + URL + ')');
|
||||
var newData = {};
|
||||
newData.datasets = [];
|
||||
|
||||
for (var i = 0; i < data.count; i++) {
|
||||
newData.labels = data.labels;
|
||||
var dataset = data.datasets[i];
|
||||
dataset.backgroundColor = fillColors[i];
|
||||
newData.datasets.push(dataset);
|
||||
}
|
||||
// update the chart
|
||||
console.log('Now update chart thing.');
|
||||
budgetChart.data.datasets = newData.datasets;
|
||||
budgetChart.update();
|
||||
|
||||
}).fail(function () {
|
||||
$('#' + container).addClass('general-chart-error');
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'import_configure_title' => 'Konfigurieren Sie Ihren Import',
|
||||
'import_configure_intro' => 'Es gibt einige Optionen für Ihren CSV-Import. Bitte geben Sie an, ob Ihre CSV-Datei Überschriften in der ersten Spalte enthält und was das Datumsformat in Ihrem Datumsfeld ist. Dieses kann einige Experimente erfordern. Das Trennzeichen ist in der Regel ein ",", könnte aber auch ein "." sein. Bitte überprüfen Sie dieses sorgfältig.',
|
||||
'import_configure_form' => 'Formular',
|
||||
'import_configure_form' => 'Basic CSV import options',
|
||||
'header_help' => 'Hier auswählen, wenn die ersten Zeilen der CSV-Datei die Spaltenüberschriften sind',
|
||||
'date_help' => 'Datumsformat in ihrer CSV-Datei. Geben Sie das Format so an, wie es <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">diese Seite</a> zeigt. Die Standardeinstellung ergibt Daten die so aussehen: :dateExample.',
|
||||
'delimiter_help' => 'Wählen Sie das Trennzeichen, welches in ihrer Datei genutzt wird. Wenn Sie nicht sicher sind ist Komma die sicherste Option.',
|
||||
@ -24,7 +24,6 @@ return [
|
||||
|
||||
// roles
|
||||
'column_roles_title' => 'Define column roles',
|
||||
'column_roles_text' => '<p>Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know <a href="https://github.com/JC5/firefly-iii/issues/new">by creating an issue</a>.</p><p>Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.</p>',
|
||||
'column_roles_table' => 'Tabelle',
|
||||
'column_name' => 'Name der Spalte',
|
||||
'column_example' => 'Column example data',
|
||||
|
@ -67,11 +67,25 @@ return [
|
||||
'warning_much_data' => ':days Tage an Daten können eine Weile dauern zu laden.',
|
||||
'registered' => 'Sie haben sich erfolgreich registriert!',
|
||||
'search' => 'Suche',
|
||||
'search_found_accounts' => 'Found :count account(s) for your query.',
|
||||
'search_found_categories' => 'Found :count category(ies) for your query.',
|
||||
'search_found_budgets' => 'Found :count budget(s) for your query.',
|
||||
'search_found_tags' => 'Found :count tag(s) for your query.',
|
||||
'search_found_transactions' => 'Found :count transaction(s) for your query.',
|
||||
'results_limited' => 'The results are limited to :count entries.',
|
||||
'tagbalancingAct' => 'Balancing act',
|
||||
'tagadvancePayment' => 'Advance payment',
|
||||
'tagnothing' => '',
|
||||
'Default asset account' => 'Default asset account',
|
||||
'no_budget_pointer' => 'Sie scheinen keine Budgets festgelegt zu haben. Sie sollten welche auf der <a href="/budgets">Budget</a>-Seite erstellen. Budgets können Ihnen helfen ihre Ausgaben zu verfolgen.',
|
||||
'Savings account' => 'Savings account',
|
||||
'Credit card' => 'Credit card',
|
||||
'source_accounts' => 'Herkunftskonto',
|
||||
'destination_accounts' => 'Zielkonto',
|
||||
'user_id_is' => 'Your user id is <strong>:user</strong>',
|
||||
'field_supports_markdown' => 'This field supports <a href="https://en.support.wordpress.com/markdown-quick-reference/">Markdown</a>.',
|
||||
'need_more_help' => 'If you need more help using Firefly III, please <a href="https://github.com/JC5/firefly-iii/issues">open a ticker on Github</a>.',
|
||||
'nothing_to_display' => 'There are no transactions to show you',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'yearly',
|
||||
@ -842,14 +856,9 @@ return [
|
||||
'import_complete_text' => 'Der Import ist bereit zu starten. Alle Einstellungen wurden von Ihnen erledigt. Bitte laden Sie die Konfigurationsdatei herunter. Diese wird Ihnen beim Import helfen, sollte dieser nicht wie gewünscht verlaufen. Um den Import tatsächlich zu starten führen Sie den folgenden Befehl in der Konsole aus oder nutzen Sie den Web-basierten Import. Abhängig von ihrer Konfiguration wird Ihnen der Konsolenimport mehr Rückmeldungen geben.',
|
||||
'import_download_config' => 'Download configuration',
|
||||
'import_start_import' => 'Start import',
|
||||
'import_intro_beta' => 'Die Importfunktion von Firefly III ist im Beta-Stadium. Viele unterschiedliche Nutzer von Firefly III haben viele verschiedene Datei getestet. Auch wenn die einzelnen Komponenten des Imports funktionieren (wirklich), können Fehler auftreten. Wenn ihre Datei nicht in Firefly importiert werden kann lesen Sie bitte <a href="https://github.com/JC5/firefly-iii/wiki/Submit-issues-with-sensitive-data-in-them">diese Wiki-Seite</a>, damit ich den aufgetretenen Fehler beheben kann.',
|
||||
'import_data' => 'Daten importieren',
|
||||
'import_data_full' => 'Importieren Sie Daten in Firefly III',
|
||||
'import' => 'Import',
|
||||
'import_intro_what_it_does' => 'Diese Seite erlaubt Ihnen das Importieren von Daten in Firefly III. Exportieren Sie dazu Daten von ihrer Bank oder anderen Finanzverwaltungen. Laden Sie die Dateien anschließend hier hoch. Firefly III wird die Daten daraufhin konvertieren. Sie müssen dafür einige Informationen angeben. Bitte wählen Sie nun eine Datei aus folgen Sie den Anweisungen.',
|
||||
'import_intro_import_conf_title' => 'Importkonfiguration',
|
||||
'import_intro_beta_warning' => 'Achtung',
|
||||
'import_intro_import_conf_text' => 'Wie Sie auf den nächsten Seite feststellen werden, hat die Importfunktion viele Einstellungen. Diese Einstellungen sind vor allem von ihrer Bank (oder Finanzverwaltungssoftware), von der ihre Daten stammen, abhängig. Es ist sehr wahrscheinlich, dass bereits eine andere Person solch eine Datei importiert hat und die jeweile <em>Konfigurationsdatei</em> bereitstellt. Bitte schauen Sie daher in der <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">Übersicht der Import-Einstellungen</a></strong> nach, ob bereits eine Konfiguratiosdatei für ihre Bank vorhanden ist. Wenn eine Datei existiert sollten Sie diese herunterladen und hier hochladen. Es wird Ihnen eine Menge Zeit sparen!',
|
||||
'import_file_help' => 'Select your file',
|
||||
'import_status_settings_complete' => 'The import is ready to start.',
|
||||
'import_status_import_complete' => 'The import has completed.',
|
||||
@ -865,11 +874,9 @@ return [
|
||||
'import_double' => 'Row #:row: This row has been imported before, and is stored in <a href=":link">:description</a>.',
|
||||
'import_finished_all' => 'The import has finished. Please check out the results below.',
|
||||
'import_with_key' => 'Import with key \':key\'',
|
||||
|
||||
'import_share_configuration' => 'Bitte denken Sie darüber nach ihre Konfiguration herunterzuladen und in der <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">Übersicht der Import-Einstellungen</a></strong> zu teilen. Dieses erlaubt es anderen Nutzern von Firefly III ihre Daten unkomplizierter zu importieren.',
|
||||
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
|
||||
|
||||
'import_share_configuration' => 'Bitte denken Sie darüber nach ihre Konfiguration herunterzuladen und in der <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">Übersicht der Import-Einstellungen</a></strong> zu teilen. Dieses erlaubt es anderen Nutzern von Firefly III ihre Daten unkomplizierter zu importieren.',
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
'need_at_least_one_account' => 'You need at least one asset account to be able to create piggy banks',
|
||||
'see_help_top_right' => 'For more information, please check out the help pages using the icon in the top right corner of the page.',
|
||||
];
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'import_configure_title' => 'Configure your import',
|
||||
'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.',
|
||||
'import_configure_form' => 'Form',
|
||||
'import_configure_form' => 'Basic CSV import options',
|
||||
'header_help' => 'Check this if the first row of your CSV file are the column titles',
|
||||
'date_help' => 'Date time format in your CSV. Follow the format like <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">this page</a> indicates. The default value will parse dates that look like this: :dateExample.',
|
||||
'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
|
||||
@ -24,7 +24,6 @@ return [
|
||||
|
||||
// roles
|
||||
'column_roles_title' => 'Define column roles',
|
||||
'column_roles_text' => '<p>Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know <a href="https://github.com/JC5/firefly-iii/issues/new">by creating an issue</a>.</p><p>Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.</p>',
|
||||
'column_roles_table' => 'Table',
|
||||
'column_name' => 'Name of column',
|
||||
'column_example' => 'Column example data',
|
||||
|
@ -67,11 +67,25 @@ return [
|
||||
'warning_much_data' => ':days days of data may take a while to load.',
|
||||
'registered' => 'You have registered successfully!',
|
||||
'search' => 'Search',
|
||||
'search_found_accounts' => 'Found :count account(s) for your query.',
|
||||
'search_found_categories' => 'Found :count category(ies) for your query.',
|
||||
'search_found_budgets' => 'Found :count budget(s) for your query.',
|
||||
'search_found_tags' => 'Found :count tag(s) for your query.',
|
||||
'search_found_transactions' => 'Found :count transaction(s) for your query.',
|
||||
'results_limited' => 'The results are limited to :count entries.',
|
||||
'tagbalancingAct' => 'Balancing act',
|
||||
'tagadvancePayment' => 'Advance payment',
|
||||
'tagnothing' => '',
|
||||
'Default asset account' => 'Default asset account',
|
||||
'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the <a href="/budgets">budgets</a>-page. Budgets can help you keep track of expenses.',
|
||||
'Savings account' => 'Savings account',
|
||||
'Credit card' => 'Credit card',
|
||||
'source_accounts' => 'Source account(s)',
|
||||
'destination_accounts' => 'Destination account(s)',
|
||||
'user_id_is' => 'Your user id is <strong>:user</strong>',
|
||||
'field_supports_markdown' => 'This field supports <a href="https://en.support.wordpress.com/markdown-quick-reference/">Markdown</a>.',
|
||||
'need_more_help' => 'If you need more help using Firefly III, please <a href="https://github.com/JC5/firefly-iii/issues">open a ticker on Github</a>.',
|
||||
'nothing_to_display' => 'There are no transactions to show you',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'yearly',
|
||||
@ -842,14 +856,9 @@ return [
|
||||
'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you can either execute the following command in your console, or run the web-based import. Depending on your configuration, the console import will give you more feedback.',
|
||||
'import_download_config' => 'Download configuration',
|
||||
'import_start_import' => 'Start import',
|
||||
'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read <a href="https://github.com/JC5/firefly-iii/wiki/Submit-issues-with-sensitive-data-in-them">this wiki page</a> so I can fix the problem you have run into.',
|
||||
'import_data' => 'Import data',
|
||||
'import_data_full' => 'Import data into Firefly III',
|
||||
'import' => 'Import',
|
||||
'import_intro_what_it_does' => 'This page allows you to import data into Firefly III. To do so, export data from your bank, or from another financial management system. Upload that file here. Firefly III will convert the data. You need to give it some directions. Please select a file and follow the instructions.',
|
||||
'import_intro_import_conf_title' => 'Import "configuration"',
|
||||
'import_intro_beta_warning' => 'Warning',
|
||||
'import_intro_import_conf_text' => 'As you will discover over the next few pages, this import routine has a lot of settings. These settings are mainly dependent on the bank (or financial management software) your file comes from. There is a good chance somebody else already imported such a file and has shared their <em>configuration file</em>. Please visit the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong> to see if there already is a configuration available for your bank or system. If there is, you should download this configuration file and upload it here as well. It will save you a lot of time!',
|
||||
'import_file_help' => 'Select your file',
|
||||
'import_status_settings_complete' => 'The import is ready to start.',
|
||||
'import_status_import_complete' => 'The import has completed.',
|
||||
@ -865,11 +874,9 @@ return [
|
||||
'import_double' => 'Row #:row: This row has been imported before, and is stored in <a href=":link">:description</a>.',
|
||||
'import_finished_all' => 'The import has finished. Please check out the results below.',
|
||||
'import_with_key' => 'Import with key \':key\'',
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
'need_at_least_one_account' => 'You need at least one asset account to be able to create piggy banks',
|
||||
'see_help_top_right' => 'For more information, please check out the help pages using the icon in the top right corner of the page.',
|
||||
];
|
||||
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'import_configure_title' => 'Configurer l\'import',
|
||||
'import_configure_intro' => 'Il y a des options pour l\'import CSV. Veuillez indiquer si votre fichier CSV contient les en-têtes dans la première colonne, et quel est le format de la date de votre champs date. Cela peut nécessiter quelques essais. Le délimiteur de champ est généralement un «, », mais pourrait également être un « ; ». Cochez cette case avec soin.',
|
||||
'import_configure_form' => 'Formulaire',
|
||||
'import_configure_form' => 'Basic CSV import options',
|
||||
'header_help' => 'Cochez cette case si la première ligne de votre fichier CSV contient les entêtes des colonnes',
|
||||
'date_help' => 'Le format de la date et de l’heure dans votre fichier CSV. Utiliser les formats comme indiqué sur <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters"> cette page</a>. La valeur par défaut va extraire les dates qui ressemblent à ceci: :dateExample.',
|
||||
'delimiter_help' => 'Choisissez le délimiteur de champ qui est utilisé dans votre fichier d’entrée. Si vous n’êtes pas certain, la virgule est l’option la plus sûre.',
|
||||
@ -24,7 +24,6 @@ return [
|
||||
|
||||
// roles
|
||||
'column_roles_title' => 'Définir le rôle des colonnes',
|
||||
'column_roles_text' => '<p>Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know <a href="https://github.com/JC5/firefly-iii/issues/new">by creating an issue</a>.</p><p>Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.</p>',
|
||||
'column_roles_table' => 'Tableau',
|
||||
'column_name' => 'Nom de colonne',
|
||||
'column_example' => 'Exemple',
|
||||
|
@ -67,11 +67,25 @@ return [
|
||||
'warning_much_data' => ':days de données peuvent prendre un certain temps à charger.',
|
||||
'registered' => 'Vous avez été enregistré avec succès !',
|
||||
'search' => 'Rechercher',
|
||||
'search_found_accounts' => 'Found :count account(s) for your query.',
|
||||
'search_found_categories' => 'Found :count category(ies) for your query.',
|
||||
'search_found_budgets' => 'Found :count budget(s) for your query.',
|
||||
'search_found_tags' => 'Found :count tag(s) for your query.',
|
||||
'search_found_transactions' => 'Found :count transaction(s) for your query.',
|
||||
'results_limited' => 'The results are limited to :count entries.',
|
||||
'tagbalancingAct' => 'Balancing act',
|
||||
'tagadvancePayment' => 'Advance payment',
|
||||
'tagnothing' => '',
|
||||
'Default asset account' => 'Default asset account',
|
||||
'no_budget_pointer' => 'Vous semblez n’avoir encore aucun budget. Vous devez en créer sur la page des <a href="/budgets"> budgets</a>. Les budgets peuvent vous aider à garder une trace des dépenses.',
|
||||
'Savings account' => 'Savings account',
|
||||
'Credit card' => 'Credit card',
|
||||
'source_accounts' => 'Compte(s) source',
|
||||
'destination_accounts' => 'Compte(s) de destination',
|
||||
'user_id_is' => 'Your user id is <strong>:user</strong>',
|
||||
'field_supports_markdown' => 'This field supports <a href="https://en.support.wordpress.com/markdown-quick-reference/">Markdown</a>.',
|
||||
'need_more_help' => 'If you need more help using Firefly III, please <a href="https://github.com/JC5/firefly-iii/issues">open a ticker on Github</a>.',
|
||||
'nothing_to_display' => 'There are no transactions to show you',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'yearly',
|
||||
@ -842,14 +856,9 @@ return [
|
||||
'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you can either execute the following command in your console, or run the web-based import. Depending on your configuration, the console import will give you more feedback.',
|
||||
'import_download_config' => 'Download configuration',
|
||||
'import_start_import' => 'Start import',
|
||||
'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read <a href="https://github.com/JC5/firefly-iii/wiki/Submit-issues-with-sensitive-data-in-them">this wiki page</a> so I can fix the problem you have run into.',
|
||||
'import_data' => 'Import data',
|
||||
'import_data_full' => 'Import data into Firefly III',
|
||||
'import' => 'Import',
|
||||
'import_intro_what_it_does' => 'This page allows you to import data into Firefly III. To do so, export data from your bank, or from another financial management system. Upload that file here. Firefly III will convert the data. You need to give it some directions. Please select a file and follow the instructions.',
|
||||
'import_intro_import_conf_title' => 'Import "configuration"',
|
||||
'import_intro_beta_warning' => 'Warning',
|
||||
'import_intro_import_conf_text' => 'As you will discover over the next few pages, this import routine has a lot of settings. These settings are mainly dependent on the bank (or financial management software) your file comes from. There is a good chance somebody else already imported such a file and has shared their <em>configuration file</em>. Please visit the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong> to see if there already is a configuration available for your bank or system. If there is, you should download this configuration file and upload it here as well. It will save you a lot of time!',
|
||||
'import_file_help' => 'Select your file',
|
||||
'import_status_settings_complete' => 'The import is ready to start.',
|
||||
'import_status_import_complete' => 'The import has completed.',
|
||||
@ -865,11 +874,9 @@ return [
|
||||
'import_double' => 'Row #:row: This row has been imported before, and is stored in <a href=":link">:description</a>.',
|
||||
'import_finished_all' => 'The import has finished. Please check out the results below.',
|
||||
'import_with_key' => 'Import with key \':key\'',
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
'need_at_least_one_account' => 'You need at least one asset account to be able to create piggy banks',
|
||||
'see_help_top_right' => 'For more information, please check out the help pages using the icon in the top right corner of the page.',
|
||||
];
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'import_configure_title' => 'Configure your import',
|
||||
'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.',
|
||||
'import_configure_form' => 'Form',
|
||||
'import_configure_form' => 'Basic CSV import options',
|
||||
'header_help' => 'Check this if the first row of your CSV file are the column titles',
|
||||
'date_help' => 'Date time format in your CSV. Follow the format like <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">this page</a> indicates. The default value will parse dates that look like this: :dateExample.',
|
||||
'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
|
||||
@ -24,7 +24,6 @@ return [
|
||||
|
||||
// roles
|
||||
'column_roles_title' => 'Define column roles',
|
||||
'column_roles_text' => '<p>Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know <a href="https://github.com/JC5/firefly-iii/issues/new">by creating an issue</a>.</p><p>Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.</p>',
|
||||
'column_roles_table' => 'Table',
|
||||
'column_name' => 'Name of column',
|
||||
'column_example' => 'Column example data',
|
||||
|
@ -67,11 +67,25 @@ return [
|
||||
'warning_much_data' => ':days days of data may take a while to load.',
|
||||
'registered' => 'You have registered successfully!',
|
||||
'search' => 'Search',
|
||||
'search_found_accounts' => 'Found :count account(s) for your query.',
|
||||
'search_found_categories' => 'Found :count category(ies) for your query.',
|
||||
'search_found_budgets' => 'Found :count budget(s) for your query.',
|
||||
'search_found_tags' => 'Found :count tag(s) for your query.',
|
||||
'search_found_transactions' => 'Found :count transaction(s) for your query.',
|
||||
'results_limited' => 'The results are limited to :count entries.',
|
||||
'tagbalancingAct' => 'Balancing act',
|
||||
'tagadvancePayment' => 'Advance payment',
|
||||
'tagnothing' => '',
|
||||
'Default asset account' => 'Default asset account',
|
||||
'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the <a href="/budgets">budgets</a>-page. Budgets can help you keep track of expenses.',
|
||||
'Savings account' => 'Savings account',
|
||||
'Credit card' => 'Credit card',
|
||||
'source_accounts' => 'Source account(s)',
|
||||
'destination_accounts' => 'Destination account(s)',
|
||||
'user_id_is' => 'Your user id is <strong>:user</strong>',
|
||||
'field_supports_markdown' => 'This field supports <a href="https://en.support.wordpress.com/markdown-quick-reference/">Markdown</a>.',
|
||||
'need_more_help' => 'If you need more help using Firefly III, please <a href="https://github.com/JC5/firefly-iii/issues">open a ticker on Github</a>.',
|
||||
'nothing_to_display' => 'There are no transactions to show you',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'yearly',
|
||||
@ -842,14 +856,9 @@ return [
|
||||
'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you can either execute the following command in your console, or run the web-based import. Depending on your configuration, the console import will give you more feedback.',
|
||||
'import_download_config' => 'Download configuration',
|
||||
'import_start_import' => 'Start import',
|
||||
'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read <a href="https://github.com/JC5/firefly-iii/wiki/Submit-issues-with-sensitive-data-in-them">this wiki page</a> so I can fix the problem you have run into.',
|
||||
'import_data' => 'Import data',
|
||||
'import_data_full' => 'Import data into Firefly III',
|
||||
'import' => 'Import',
|
||||
'import_intro_what_it_does' => 'This page allows you to import data into Firefly III. To do so, export data from your bank, or from another financial management system. Upload that file here. Firefly III will convert the data. You need to give it some directions. Please select a file and follow the instructions.',
|
||||
'import_intro_import_conf_title' => 'Import "configuration"',
|
||||
'import_intro_beta_warning' => 'Warning',
|
||||
'import_intro_import_conf_text' => 'As you will discover over the next few pages, this import routine has a lot of settings. These settings are mainly dependent on the bank (or financial management software) your file comes from. There is a good chance somebody else already imported such a file and has shared their <em>configuration file</em>. Please visit the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong> to see if there already is a configuration available for your bank or system. If there is, you should download this configuration file and upload it here as well. It will save you a lot of time!',
|
||||
'import_file_help' => 'Select your file',
|
||||
'import_status_settings_complete' => 'The import is ready to start.',
|
||||
'import_status_import_complete' => 'The import has completed.',
|
||||
@ -865,11 +874,9 @@ return [
|
||||
'import_double' => 'Row #:row: This row has been imported before, and is stored in <a href=":link">:description</a>.',
|
||||
'import_finished_all' => 'The import has finished. Please check out the results below.',
|
||||
'import_with_key' => 'Import with key \':key\'',
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
'need_at_least_one_account' => 'You need at least one asset account to be able to create piggy banks',
|
||||
'see_help_top_right' => 'For more information, please check out the help pages using the icon in the top right corner of the page.',
|
||||
];
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'import_configure_title' => 'Import configureren',
|
||||
'import_configure_intro' => 'Hier zie je enkele opties voor jouw CSV bestand. Geef aan of je CSV bestand kolomtitels bevat, en hoe het datumveld is opgebouwd. Hier moet je wellicht wat experimenteren. Het scheidingsteken is meestal een ",", maar dat kan ook een ";" zijn. Controleer dit zorgvuldig.',
|
||||
'import_configure_form' => 'Formulier',
|
||||
'import_configure_form' => 'Standaard CSV import opties',
|
||||
'header_help' => 'Vink hier als de eerste rij kolomtitels bevat',
|
||||
'date_help' => 'Datum/tijd formaat in jouw CSV bestand. Volg het formaat zoals ze het <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">op deze pagina</a> uitleggen. Het standaardformaat ziet er zo uit: :dateExample.',
|
||||
'delimiter_help' => 'Kies het veldscheidingsteken dat in jouw bestand wordt gebruikt. Als je het niet zeker weet, is de komma de beste optie.',
|
||||
@ -24,7 +24,6 @@ return [
|
||||
|
||||
// roles
|
||||
'column_roles_title' => 'Bepaal de inhoud van elke kolom',
|
||||
'column_roles_text' => '<p>Firefly III kan niet raden welke soort gegevens er in elke kolom staan. Dat moet je er bij vertellen. Gebruik de voorbeeldgegevens en kies het juiste type uit de dropdown. Staat jouw type er niet bij? <a href="https://github.com/JC5/firefly-iii/issues/new">Open dan een ticket</a>.</p><p>Sommige waarden, zoals rekeningnummers en namen staan wellicht al in jouw Firefly III database. Als je dan het vinkje vinkt, kan je zelf de link leggen tussen wat er in het CSV bestand staat en wat er in de database staat. Hiermee kan je de import sturen.</p>',
|
||||
'column_roles_table' => 'Tabel',
|
||||
'column_name' => 'Kolomnaam',
|
||||
'column_example' => 'Voorbeeldgegevens',
|
||||
|
@ -67,11 +67,25 @@ return [
|
||||
'warning_much_data' => 'Het kan even duren voor :days dagen aan gegevens geladen zijn.',
|
||||
'registered' => 'Je bent geregistreerd!',
|
||||
'search' => 'Zoeken',
|
||||
'search_found_accounts' => ':count rekening(en) gevonden bij je zoekopdracht.',
|
||||
'search_found_categories' => ':count categorie(en) gevonden bij je zoekopdracht.',
|
||||
'search_found_budgets' => ':count budget(ten) gevonden bij je zoekopdracht.',
|
||||
'search_found_tags' => ':count tag(s) gevonden bij je zoekopdracht.',
|
||||
'search_found_transactions' => ':count transactie(s) gevonden bij je zoekopdracht.',
|
||||
'results_limited' => 'Er worden maximaal :count resultaten getoond.',
|
||||
'tagbalancingAct' => 'Balancerende tag',
|
||||
'tagadvancePayment' => 'Vooruitbetaalde tag',
|
||||
'tagnothing' => '',
|
||||
'Default asset account' => 'Standaard betaalrekening',
|
||||
'no_budget_pointer' => 'Je hebt nog geen budgetten. Maak er een aantal op de <a href="/budgets">budgetten</a>-pagina. Met budgetten kan je je uitgaven beter bijhouden.',
|
||||
'Savings account' => 'Spaarrekening',
|
||||
'Credit card' => 'Credit card',
|
||||
'source_accounts' => 'Bronrekening(en)',
|
||||
'destination_accounts' => 'Doelrekening(en)',
|
||||
'user_id_is' => 'Je gebruikersnummer is <strong>:user</strong>',
|
||||
'field_supports_markdown' => 'Dit veld ondersteunt <a href="https://en.support.wordpress.com/markdown-quick-reference/">Markdown</a>.',
|
||||
'need_more_help' => 'Als je meer hulp nodig hebt met Firefly III, <a href="https://github.com/JC5/firefly-iii/issues">open dan een ticket op Github</a>.',
|
||||
'nothing_to_display' => 'Er zijn hier geen transacties te zien',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'jaarlijks',
|
||||
@ -842,14 +856,9 @@ return [
|
||||
'import_complete_text' => 'De import kan beginnen. Alle configuratie is opgeslagen. Download dit bestand. Het kan schelen als je de import opnieuw moet doen. Om daadwerkelijk te beginnen, gebruik je of het commando in je console, of de website. Afhankelijk van hoe je Firefly III hebt ingesteld, geeft de console-methode meer feedback.',
|
||||
'import_download_config' => 'Download importconfiguratie',
|
||||
'import_start_import' => 'Import starten',
|
||||
'import_intro_beta' => 'De importfunctie van Firefly III is in bèta. Er zijn al veel bestanden geprobeerd, en elk individueel component zou moeten werken. Gecombineerd echter, kan er wat stuk gaan. Als jouw bestand problemen geeft, lees dan <a href="https://github.com/JC5/firefly-iii/wiki/Submit-issues-with-sensitive-data-in-them">deze wikipagina</a> zodat ik eventuele bugs kan fixen.',
|
||||
'import_data' => 'Importeer data',
|
||||
'import_data_full' => 'Gegevens importeren in Firefly III',
|
||||
'import' => 'Import',
|
||||
'import_intro_what_it_does' => 'Vanaf deze pagina kan je gegevens importeren in Firefly III. Exporteer ze eerst vanuit je internetbankieren of financiële software. Upload dat bestandje hier. Firefly III zal de transacties omzetten. Je zult wel wat hints moeten geven. Selecteer alsjeblieft een bestand en volg de instructies.',
|
||||
'import_intro_import_conf_title' => 'Importconfiguratie',
|
||||
'import_intro_beta_warning' => 'Waarschuwing',
|
||||
'import_intro_import_conf_text' => 'Zoals je wel zult ontdekken heeft de import-routine veel opties. Deze opties verschillen voornamelijk per bank (of softwarepakket). Grote kans dat iemand anders je al voor was en zijn of haar <em>configuratiebestand</em> heeft gedeeld. Kijk vlug op de <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">configuratiebestand-wiki</a></strong> of er al een bestand is voor jouw bank (of softwarepakket). Als die er is, download dit bestand dan en selecteer deze. Het kan veel tijd schelen!',
|
||||
'import_file_help' => 'Selecteer je bestand',
|
||||
'import_status_settings_complete' => 'De import is klaar om te beginnen.',
|
||||
'import_status_import_complete' => 'Het importeren is voltooid.',
|
||||
@ -865,11 +874,9 @@ return [
|
||||
'import_double' => 'Rij: #:row: Deze rij is al geimporteerd en is opgeslagen als <a href=":link">:description</a>.',
|
||||
'import_finished_all' => 'Het importeren is voltooid. Hieronder zie je de resultaten.',
|
||||
'import_with_key' => 'Import met code \':key\'',
|
||||
|
||||
'import_share_configuration' => 'Overweeg om je configuratiebestand te downloaden en te delen op de <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">configuratiebestand-wiki</a></strong>. Hiermee kan je het andere Firefly III gebruikers weer makkelijker maken.',
|
||||
|
||||
'import_finished_report' => 'Het importeren is voltooid. Kijk naar eventuele fouten in het blok hierboven. Alle geimporteerde transacties hebben een tag, en die kan je hieronder bekijken. ',
|
||||
'import_finished_link' => 'De geimporteerde transacties kan je vinden onder tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
|
||||
|
||||
'import_share_configuration' => 'Overweeg om je configuratiebestand te downloaden en te delen op de <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">configuratiebestand-wiki</a></strong>. Hiermee kan je het andere Firefly III gebruikers weer makkelijker maken.',
|
||||
'import_finished_report' => 'Het importeren is voltooid. Kijk naar eventuele fouten in het blok hierboven. Alle geimporteerde transacties hebben een tag, en die kan je hieronder bekijken. ',
|
||||
'import_finished_link' => 'De geimporteerde transacties kan je vinden onder tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
'need_at_least_one_account' => 'Je moet minstens één betaalrekening hebben voor je spaarpotjes kan maken',
|
||||
'see_help_top_right' => 'Meer informatie vind je in de help pagina\'s. Gebruik daarvoor het icoontje rechtsboven in de hoek.',
|
||||
];
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'import_configure_title' => 'Configure sua importação',
|
||||
'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.',
|
||||
'import_configure_form' => 'Formulário',
|
||||
'import_configure_form' => 'Basic CSV import options',
|
||||
'header_help' => 'Verifique se a primeira linha do seu arquivo CSV está com os títulos de coluna',
|
||||
'date_help' => 'Date time format in your CSV. Follow the format like <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">this page</a> indicates. The default value will parse dates that look like this: :dateExample.',
|
||||
'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
|
||||
@ -24,7 +24,6 @@ return [
|
||||
|
||||
// roles
|
||||
'column_roles_title' => 'Definir papeis da coluna',
|
||||
'column_roles_text' => '<p>Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know <a href="https://github.com/JC5/firefly-iii/issues/new">by creating an issue</a>.</p><p>Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.</p>',
|
||||
'column_roles_table' => 'Tabela',
|
||||
'column_name' => 'Nome da coluna',
|
||||
'column_example' => 'Dados de exemplo da coluna',
|
||||
|
@ -67,11 +67,25 @@ return [
|
||||
'warning_much_data' => ':days dias de dados podem demorar um pouco para carregar.',
|
||||
'registered' => 'Você se registrou com sucesso!',
|
||||
'search' => 'Pesquisa',
|
||||
'search_found_accounts' => 'Found :count account(s) for your query.',
|
||||
'search_found_categories' => 'Found :count category(ies) for your query.',
|
||||
'search_found_budgets' => 'Found :count budget(s) for your query.',
|
||||
'search_found_tags' => 'Found :count tag(s) for your query.',
|
||||
'search_found_transactions' => 'Found :count transaction(s) for your query.',
|
||||
'results_limited' => 'The results are limited to :count entries.',
|
||||
'tagbalancingAct' => 'Balancing act',
|
||||
'tagadvancePayment' => 'Advance payment',
|
||||
'tagnothing' => '',
|
||||
'Default asset account' => 'Default asset account',
|
||||
'no_budget_pointer' => 'Parece que não há orçamentos ainda. Você deve criar alguns na página <a href="/budgets">orçamentos</a>. Orçamentos podem ajudá-lo a manter o controle de despesas.',
|
||||
'Savings account' => 'Savings account',
|
||||
'Credit card' => 'Credit card',
|
||||
'source_accounts' => 'Conta(s) de origem',
|
||||
'destination_accounts' => 'Conta(s) de destino',
|
||||
'user_id_is' => 'Your user id is <strong>:user</strong>',
|
||||
'field_supports_markdown' => 'This field supports <a href="https://en.support.wordpress.com/markdown-quick-reference/">Markdown</a>.',
|
||||
'need_more_help' => 'If you need more help using Firefly III, please <a href="https://github.com/JC5/firefly-iii/issues">open a ticker on Github</a>.',
|
||||
'nothing_to_display' => 'There are no transactions to show you',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'yearly',
|
||||
@ -842,14 +856,9 @@ return [
|
||||
'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you can either execute the following command in your console, or run the web-based import. Depending on your configuration, the console import will give you more feedback.',
|
||||
'import_download_config' => 'Download da configuração',
|
||||
'import_start_import' => 'Iniciar importação',
|
||||
'import_intro_beta' => 'A função de importação do Firefly III está em beta. Muitos usuários do Firefly III têm tentado diferentes arquivos. Embora cada componente individual desta rotina de importação funcione (realmente), a combinação pode quebrar. Se seu arquivo não puder ser importado pelo Firefly, por favor leia <a href="https://github.com/JC5/firefly-iii/wiki/Submit-issues-with-sensitive-data-in-them">esta página da wiki</a> para resolver o problema que temos para executar.',
|
||||
'import_data' => 'Importar dados',
|
||||
'import_data_full' => 'Importar dados para o Firefly III',
|
||||
'import' => 'Importar',
|
||||
'import_intro_what_it_does' => 'This page allows you to import data into Firefly III. To do so, export data from your bank, or from another financial management system. Upload that file here. Firefly III will convert the data. You need to give it some directions. Please select a file and follow the instructions.',
|
||||
'import_intro_import_conf_title' => 'Import "configuration"',
|
||||
'import_intro_beta_warning' => 'Warning',
|
||||
'import_intro_import_conf_text' => 'As you will discover over the next few pages, this import routine has a lot of settings. These settings are mainly dependent on the bank (or financial management software) your file comes from. There is a good chance somebody else already imported such a file and has shared their <em>configuration file</em>. Please visit the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong> to see if there already is a configuration available for your bank or system. If there is, you should download this configuration file and upload it here as well. It will save you a lot of time!',
|
||||
'import_file_help' => 'Selecione seu arquivo',
|
||||
'import_status_settings_complete' => 'The import is ready to start.',
|
||||
'import_status_import_complete' => 'The import has completed.',
|
||||
@ -865,11 +874,9 @@ return [
|
||||
'import_double' => 'Row #:row: This row has been imported before, and is stored in <a href=":link">:description</a>.',
|
||||
'import_finished_all' => 'The import has finished. Please check out the results below.',
|
||||
'import_with_key' => 'Import with key \':key\'',
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
'need_at_least_one_account' => 'You need at least one asset account to be able to create piggy banks',
|
||||
'see_help_top_right' => 'For more information, please check out the help pages using the icon in the top right corner of the page.',
|
||||
];
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'import_configure_title' => 'Configure your import',
|
||||
'import_configure_intro' => 'There are some options for your CSV import. Please indicate if your CSV file contains headers on the first column, and what the date format of your date-fields is. That might require some experimentation. The field delimiter is usually a ",", but could also be a ";". Check this carefully.',
|
||||
'import_configure_form' => 'Form',
|
||||
'import_configure_form' => 'Basic CSV import options',
|
||||
'header_help' => 'Check this if the first row of your CSV file are the column titles',
|
||||
'date_help' => 'Date time format in your CSV. Follow the format like <a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">this page</a> indicates. The default value will parse dates that look like this: :dateExample.',
|
||||
'delimiter_help' => 'Choose the field delimiter that is used in your input file. If not sure, comma is the safest option.',
|
||||
@ -24,7 +24,6 @@ return [
|
||||
|
||||
// roles
|
||||
'column_roles_title' => 'Define column roles',
|
||||
'column_roles_text' => '<p>Firefly III cannot guess what data each column contains. You must tell Firefly which kinds of data to expect. The example data can guide you into picking the correct type from the dropdown. If a column cannot be matched to a useful data type, please let me know <a href="https://github.com/JC5/firefly-iii/issues/new">by creating an issue</a>.</p><p>Some values in your CSV file, such as account names or categories, may already exist in your Firefly III database. If you select "map these values" Firefly will not attempt to search for matching values itself but allow you to match the CSV values against the values in your database. This allows you to fine-tune the import.</p>',
|
||||
'column_roles_table' => 'Table',
|
||||
'column_name' => 'Name of column',
|
||||
'column_example' => 'Column example data',
|
||||
|
@ -67,11 +67,25 @@ return [
|
||||
'warning_much_data' => ':days days of data may take a while to load.',
|
||||
'registered' => 'You have registered successfully!',
|
||||
'search' => 'Search',
|
||||
'search_found_accounts' => 'Found :count account(s) for your query.',
|
||||
'search_found_categories' => 'Found :count category(ies) for your query.',
|
||||
'search_found_budgets' => 'Found :count budget(s) for your query.',
|
||||
'search_found_tags' => 'Found :count tag(s) for your query.',
|
||||
'search_found_transactions' => 'Found :count transaction(s) for your query.',
|
||||
'results_limited' => 'The results are limited to :count entries.',
|
||||
'tagbalancingAct' => 'Balancing act',
|
||||
'tagadvancePayment' => 'Advance payment',
|
||||
'tagnothing' => '',
|
||||
'Default asset account' => 'Default asset account',
|
||||
'no_budget_pointer' => 'You seem to have no budgets yet. You should create some on the <a href="/budgets">budgets</a>-page. Budgets can help you keep track of expenses.',
|
||||
'Savings account' => 'Savings account',
|
||||
'Credit card' => 'Credit card',
|
||||
'source_accounts' => 'Source account(s)',
|
||||
'destination_accounts' => 'Destination account(s)',
|
||||
'user_id_is' => 'Your user id is <strong>:user</strong>',
|
||||
'field_supports_markdown' => 'This field supports <a href="https://en.support.wordpress.com/markdown-quick-reference/">Markdown</a>.',
|
||||
'need_more_help' => 'If you need more help using Firefly III, please <a href="https://github.com/JC5/firefly-iii/issues">open a ticker on Github</a>.',
|
||||
'nothing_to_display' => 'There are no transactions to show you',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'yearly',
|
||||
@ -842,14 +856,9 @@ return [
|
||||
'import_complete_text' => 'The import is ready to start. All the configuration you needed to do has been done. Please download the configuration file. It will help you with the import should it not go as planned. To actually run the import, you can either execute the following command in your console, or run the web-based import. Depending on your configuration, the console import will give you more feedback.',
|
||||
'import_download_config' => 'Download configuration',
|
||||
'import_start_import' => 'Start import',
|
||||
'import_intro_beta' => 'The import function of Firefly III is in beta. Many users of Firefly III have tried many different files. Although each individual compontent of this import routine works (really), the combination might break. If your file cannot be imported by Firefly, please read <a href="https://github.com/JC5/firefly-iii/wiki/Submit-issues-with-sensitive-data-in-them">this wiki page</a> so I can fix the problem you have run into.',
|
||||
'import_data' => 'Import data',
|
||||
'import_data_full' => 'Import data into Firefly III',
|
||||
'import' => 'Import',
|
||||
'import_intro_what_it_does' => 'This page allows you to import data into Firefly III. To do so, export data from your bank, or from another financial management system. Upload that file here. Firefly III will convert the data. You need to give it some directions. Please select a file and follow the instructions.',
|
||||
'import_intro_import_conf_title' => 'Import "configuration"',
|
||||
'import_intro_beta_warning' => 'Warning',
|
||||
'import_intro_import_conf_text' => 'As you will discover over the next few pages, this import routine has a lot of settings. These settings are mainly dependent on the bank (or financial management software) your file comes from. There is a good chance somebody else already imported such a file and has shared their <em>configuration file</em>. Please visit the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong> to see if there already is a configuration available for your bank or system. If there is, you should download this configuration file and upload it here as well. It will save you a lot of time!',
|
||||
'import_file_help' => 'Select your file',
|
||||
'import_status_settings_complete' => 'The import is ready to start.',
|
||||
'import_status_import_complete' => 'The import has completed.',
|
||||
@ -865,11 +874,9 @@ return [
|
||||
'import_double' => 'Row #:row: This row has been imported before, and is stored in <a href=":link">:description</a>.',
|
||||
'import_finished_all' => 'The import has finished. Please check out the results below.',
|
||||
'import_with_key' => 'Import with key \':key\'',
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
'import_finished_report' => 'The import has finished. Please note any errors in the block above this line. All transactions imported during this particular session have been tagged, and you can check them out below. ',
|
||||
'import_finished_link' => 'The transactions imported can be found in tag <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a>.',
|
||||
'need_at_least_one_account' => 'You need at least one asset account to be able to create piggy banks',
|
||||
'see_help_top_right' => 'For more information, please check out the help pages using the icon in the top right corner of the page.',
|
||||
];
|
@ -22,7 +22,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
'failed' => '帳號或密碼錯誤。',
|
||||
'throttle' => '登入失敗次數過多,請等待 :seconds 秒後再試。',
|
||||
|
||||
];
|
@ -15,7 +15,7 @@ return [
|
||||
|
||||
'import_configure_title' => '匯入設定',
|
||||
'import_configure_intro' => '這裡有一些 CSV 匯入選項。請檢查你的 CSV 檔的第一列是否包含欄位名稱,和你的日期格式是什麼。你可能需要嘗試幾次來調整正確。欄位分隔符號是通常 ",",但也可能是";";仔細檢查這一點。',
|
||||
'import_configure_form' => '表單',
|
||||
'import_configure_form' => 'Basic CSV import options',
|
||||
'header_help' => 'CSV 檔的第一行是標題',
|
||||
'date_help' => 'CSV 內的日期格式。請跟從<a href="https://secure.php.net/manual/en/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters">這頁</a>內的格式來填寫。 系統預設能夠解析像這樣的日期: :dateExample 。',
|
||||
'delimiter_help' => '請選擇你的檔案中所使用的欄位分隔符號。如果不肯定的話,逗號是最安全的選項。',
|
||||
@ -24,7 +24,6 @@ return [
|
||||
|
||||
// roles
|
||||
'column_roles_title' => '定義欄的內容',
|
||||
'column_roles_text' => '<p>Firefly III 猜不出每一欄中儲存了什麼資料。你必須告訴 Firefly 每一欄中有什麼資料。 下列的示範資料可以幫助你從列表中選擇正確類型。如果有欄位不能配對到有用的類型,請<a href="https://github.com/JC5/firefly-iii/issues/new">告訴我 (只有英語版本)</a>。</p><p>你的 CSV 檔中某些欄位可能已經存在於 Firefly III 的資料庫內,例如帳號名稱,或類別。如果你選擇「配對這些資料」, Firefly 會請你手動配對 CSV 檔和資料庫內的資料。這容許你微調你的匯入設定。</p>',
|
||||
'column_roles_table' => '表格',
|
||||
'column_name' => '欄位名稱',
|
||||
'column_example' => '欄的示例資料',
|
||||
|
@ -51,8 +51,8 @@ return [
|
||||
'flash_info_multiple' => '有一個訊息|有 :count 個訊息',
|
||||
'flash_error_multiple' => '出現了一個錯誤|出現了 :count 個錯誤',
|
||||
'net_worth' => '淨值',
|
||||
'route_has_no_help' => 'There is no help for this route.',
|
||||
'help_may_not_be_your_language' => 'This help text is in English. It is not yet available in your language',
|
||||
'route_has_no_help' => '目前還沒有說明。',
|
||||
'help_may_not_be_your_language' => '這個說明還沒有中文版本,將會顯示英文版本。',
|
||||
'two_factor_welcome' => '哈囉, :user !',
|
||||
'two_factor_enter_code' => '若要繼續,請輸入你的雙重身份驗證 (2FA) 應用程序內顯示的驗證代碼。',
|
||||
'two_factor_code_here' => '在此輸入代碼',
|
||||
@ -67,11 +67,25 @@ return [
|
||||
'warning_much_data' => ':days 天的資料需要一點時間載入。',
|
||||
'registered' => '您已成功註冊 !',
|
||||
'search' => '搜尋',
|
||||
'search_found_accounts' => 'Found :count account(s) for your query.',
|
||||
'search_found_categories' => 'Found :count category(ies) for your query.',
|
||||
'search_found_budgets' => 'Found :count budget(s) for your query.',
|
||||
'search_found_tags' => 'Found :count tag(s) for your query.',
|
||||
'search_found_transactions' => 'Found :count transaction(s) for your query.',
|
||||
'results_limited' => 'The results are limited to :count entries.',
|
||||
'tagbalancingAct' => 'Balancing act',
|
||||
'tagadvancePayment' => 'Advance payment',
|
||||
'tagnothing' => '',
|
||||
'Default asset account' => 'Default asset account',
|
||||
'no_budget_pointer' => '你還沒有預算。你可以在<a href="/budgets">預算</a>頁來建立預算。預算可以幫助你跟蹤支出情況。',
|
||||
'Savings account' => 'Savings account',
|
||||
'Credit card' => 'Credit card',
|
||||
'source_accounts' => '來源帳戶',
|
||||
'destination_accounts' => '目標帳戶',
|
||||
'user_id_is' => 'Your user id is <strong>:user</strong>',
|
||||
'field_supports_markdown' => 'This field supports <a href="https://en.support.wordpress.com/markdown-quick-reference/">Markdown</a>.',
|
||||
'need_more_help' => 'If you need more help using Firefly III, please <a href="https://github.com/JC5/firefly-iii/issues">open a ticker on Github</a>.',
|
||||
'nothing_to_display' => 'There are no transactions to show you',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'yearly',
|
||||
@ -239,8 +253,8 @@ return [
|
||||
'rule_action_set_description_choice' => '把描述設置為…',
|
||||
'rule_action_append_description_choice' => '描述後加上…',
|
||||
'rule_action_prepend_description_choice' => '描述前加上…',
|
||||
'rule_action_set_source_account_choice' => 'Set source account to...',
|
||||
'rule_action_set_source_account' => 'Set source account to :action_value',
|
||||
'rule_action_set_source_account_choice' => '把來源帳戶設置為...',
|
||||
'rule_action_set_source_account' => '將來源帳戶設置為 :action_value',
|
||||
'rule_action_set_destination_account_choice' => 'Set destination account to...',
|
||||
'rule_action_set_destination_account' => 'Set destination account to :action_value',
|
||||
|
||||
@ -379,7 +393,7 @@ return [
|
||||
'convert_please_set_expense_destination' => 'Please pick the expense account where the money will go to.',
|
||||
'convert_please_set_asset_source' => 'Please pick the asset account where the money will come from.',
|
||||
'convert_explanation_withdrawal_deposit' => 'If you convert this withdrawal into a deposit, :amount will be deposited into <a href=":sourceRoute">:sourceName</a> instead of taken from it.',
|
||||
'convert_explanation_withdrawal_transfer' => 'If you convert this withdrawal into a transfer, :amount will be transferred from <a href=":sourceRoute">:sourceName</a> to a new asset account, instead of being paid to <a href=":destinationRoute">:destinationName</a>.',
|
||||
'convert_explanation_withdrawal_transfer' => '如果你把這個提款(支出)轉換為轉帳, :amount 會從 <a href=":sourceRoute">:sourceName</a> 轉帳到新的資產帳戶,而不會付款到 <a href=":destinationRoute">:destinationName</a> 。',
|
||||
'convert_explanation_deposit_withdrawal' => 'If you convert this deposit into a withdrawal, :amount will be removed from <a href=":destinationRoute">:destinationName</a> instead of added to it.',
|
||||
'convert_explanation_deposit_transfer' => 'If you convert this deposit into a transfer, :amount will be transferred from an asset account of your choice into <a href=":destinationRoute">:destinationName</a>.',
|
||||
'convert_explanation_transfer_withdrawal' => 'If you convert this transfer into a withdrawal, :amount will go from <a href=":sourceRoute">:sourceName</a> to a new destination as an expense, instead of to <a href=":destinationRoute">:destinationName</a> as a transfer.',
|
||||
@ -842,14 +856,9 @@ return [
|
||||
'import_complete_text' => '匯入程序已準備妥當。你已完成所有設定。請下載設定檔,當你的匯入出現問題時它將幫上忙。若要執行匯入程序,你可以在您的伺服器上執行以下命令,或運行網頁導入程序。根據您的配置,在伺服器上執行命令或會給你更多的資訊。',
|
||||
'import_download_config' => 'Download configuration',
|
||||
'import_start_import' => '開始匯入',
|
||||
'import_intro_beta' => 'Firefly III 的匯入功能依然在測試階段。很多 Firefly III 的用戶已經成功使用這個功能匯入不同的檔案。儘管這個匯入功能的每個部分都能夠正常運作(我說真的),但是整個功能或者會有點問題。如果你的檔案不能匯入到 Firefly 內,請閱讀<a href="https://github.com/JC5/firefly-iii/wiki/Submit-issues-with-sensitive-data-in-them">這個維基頁面</a>,以方便我修復你所遇到的問題。',
|
||||
'import_data' => '匯入資料',
|
||||
'import_data_full' => '匯入資料到 Firefly III',
|
||||
'import' => '匯入',
|
||||
'import_intro_what_it_does' => 'This page allows you to import data into Firefly III. To do so, export data from your bank, or from another financial management system. Upload that file here. Firefly III will convert the data. You need to give it some directions. Please select a file and follow the instructions.',
|
||||
'import_intro_import_conf_title' => 'Import "configuration"',
|
||||
'import_intro_beta_warning' => 'Warning',
|
||||
'import_intro_import_conf_text' => 'As you will discover over the next few pages, this import routine has a lot of settings. These settings are mainly dependent on the bank (or financial management software) your file comes from. There is a good chance somebody else already imported such a file and has shared their <em>configuration file</em>. Please visit the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong> to see if there already is a configuration available for your bank or system. If there is, you should download this configuration file and upload it here as well. It will save you a lot of time!',
|
||||
'import_file_help' => 'Select your file',
|
||||
'import_status_settings_complete' => '匯入已準備妥當,可以開始。',
|
||||
'import_status_import_complete' => '匯入已完成。',
|
||||
@ -865,11 +874,9 @@ return [
|
||||
'import_double' => '行 #:row: 這行曾被匯入過,並已儲存在<a href=":link">:description</a>。',
|
||||
'import_finished_all' => '匯入已完成。請檢查下列的結果。',
|
||||
'import_with_key' => '以鍵 \':key\' 作匯入',
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
|
||||
'import_finished_report' => '匯入已完成。請留意在這行上面的錯誤記錄。這次所匯入的所有交易都已經進行標記,你可以在下面查看。 ',
|
||||
'import_finished_link' => '匯入成功的所有交易都可以在標籤 <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a> 內找到。',
|
||||
|
||||
|
||||
'import_share_configuration' => 'Please consider downloading your configuration and sharing it at the <strong><a href="https://github.com/firefly-iii/import-configurations/wiki">import configuration center</a></strong>. This will allow other users of Firefly III to import their files more easily.',
|
||||
'import_finished_report' => '匯入已完成。請留意在這行上面的錯誤記錄。這次所匯入的所有交易都已經進行標記,你可以在下面查看。 ',
|
||||
'import_finished_link' => '匯入成功的所有交易都可以在標籤 <a href=":link" class="label label-success" style="font-size:100%;font-weight:normal;">:tag</a> 內找到。',
|
||||
'need_at_least_one_account' => 'You need at least one asset account to be able to create piggy banks',
|
||||
'see_help_top_right' => 'For more information, please check out the help pages using the icon in the top right corner of the page.',
|
||||
];
|
@ -31,13 +31,13 @@ return [
|
||||
'journal_source_account_id' => '資產帳戶 (源頭)',
|
||||
'account_from_id' => '從帳戶',
|
||||
'account_to_id' => '到帳戶',
|
||||
'source_account' => 'Source account',
|
||||
'destination_account' => 'Destination account',
|
||||
'source_account' => '來源帳戶',
|
||||
'destination_account' => '目標帳戶',
|
||||
'journal_destination_account_id' => '資產帳戶 (目標)',
|
||||
'asset_destination_account' => '資產帳戶 (目標)',
|
||||
'asset_source_account' => '資產帳戶 (來源)',
|
||||
'journal_description' => '描述',
|
||||
'note' => 'Notes',
|
||||
'note' => '備註',
|
||||
'split_journal' => '分割此交易',
|
||||
'split_journal_explanation' => '分割這個交易為幾個部分',
|
||||
'currency' => '貨幣',
|
||||
@ -61,11 +61,11 @@ return [
|
||||
'expense_account' => '支出帳戶',
|
||||
'revenue_account' => '收入帳戶',
|
||||
|
||||
'revenue_account_source' => 'Revenue account (source)',
|
||||
'source_account_asset' => 'Source account (asset account)',
|
||||
'revenue_account_source' => '收入帳戶 (源頭)',
|
||||
'source_account_asset' => '來源帳戶 (資產帳戶)',
|
||||
'destination_account_expense' => 'Destination account (expense account)',
|
||||
'destination_account_asset' => 'Destination account (asset account)',
|
||||
'source_account_revenue' => 'Source account (revenue account)',
|
||||
'source_account_revenue' => '來源帳戶 (收入帳戶)',
|
||||
'type' => 'Type',
|
||||
'convert_Withdrawal' => 'Convert withdrawal',
|
||||
'convert_Deposit' => 'Convert deposit',
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user